Fossil

Check-in [e288af39]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fluff: Renamed state methods use/reading/writing to usedb/use/extend for clarity. Updated all callers. Extended state module with code to dump the SQL statements it receives to a file for analysis. Extended the 'use' declarations of several passes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:e288af39955b2602cd601c2cd928b8e68c7ff8d9
User & Date: aku 2007-12-02 23:47:45
Context
2007-12-04
04:54
Reworked ComputeLimits in the last breaker pass. Moved the heavy computation of the max predecessor / min successor data down to the sql in the changeset class. check-in: 711e0002 user: aku tags: trunk
2007-12-02
23:47
Fluff: Renamed state methods use/reading/writing to usedb/use/extend for clarity. Updated all callers. Extended state module with code to dump the SQL statements it receives to a file for analysis. Extended the 'use' declarations of several passes. check-in: e288af39 user: aku tags: trunk
23:45
Actually put the code for the new pass into the repository. check-in: 060513f2 user: aku tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to tools/cvs2fossil/lib/c2f_option.tcl.

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
...
140
141
142
143
144
145
146


147
148
149
150
151
152
153
		--passes                    { pass select [Value arguments] }
		--ignore-conflicting-attics { collar ignore_conflicting_attics }
		--project                   { repository add [Value arguments] }
		-v                          -
		--verbose                   { log verbose }
		-q                          -
		--quiet                     { log quiet }
		--state                     { state use [Value arguments] }
		--trunk-only                { repository trunkonly! }
		--exclude                   { project::sym exclude     [Value arguments] }
		--force-tag                 { project::sym forcetag    [Value arguments] }
		--force-branch              { project::sym forcebranch [Value arguments] }
		--batch                     { log noprogress }
		--dots                      { cyclebreaker dotsto [Value arguments] }
		--watch                     { cyclebreaker watch  [Value arguments] }

		default {
		    Usage $badoption$option\n$gethelp
		}
	    }
	}

	if {[llength $arguments] > 1} Usage
................................................................................
	trouble info "                               glob patterns."
	trouble info ""
	trouble info "    --force-branch ?PROJECT:?SYMBOL"
	trouble info "                               Force the named symbol from all or just"
	trouble info "                               the specified project to be converted as"
	trouble info "                               branch. Both project and symbol names"
	trouble info "                               are glob patterns."


	trouble info ""
	trouble info "    --dots PATH                Write the changeset graphs before, after,"
	trouble info "                               and during breaking the of cycles to the"
	trouble info "                               direcotry PATH, using GraphViz's dot format"
	trouble info ""

	# --project, --cache







|







>







 







>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
		--passes                    { pass select [Value arguments] }
		--ignore-conflicting-attics { collar ignore_conflicting_attics }
		--project                   { repository add [Value arguments] }
		-v                          -
		--verbose                   { log verbose }
		-q                          -
		--quiet                     { log quiet }
		--state                     { state usedb [Value arguments] }
		--trunk-only                { repository trunkonly! }
		--exclude                   { project::sym exclude     [Value arguments] }
		--force-tag                 { project::sym forcetag    [Value arguments] }
		--force-branch              { project::sym forcebranch [Value arguments] }
		--batch                     { log noprogress }
		--dots                      { cyclebreaker dotsto [Value arguments] }
		--watch                     { cyclebreaker watch  [Value arguments] }
		--statesavequeriesto        { state savequeriesto [Value arguments] }
		default {
		    Usage $badoption$option\n$gethelp
		}
	    }
	}

	if {[llength $arguments] > 1} Usage
................................................................................
	trouble info "                               glob patterns."
	trouble info ""
	trouble info "    --force-branch ?PROJECT:?SYMBOL"
	trouble info "                               Force the named symbol from all or just"
	trouble info "                               the specified project to be converted as"
	trouble info "                               branch. Both project and symbol names"
	trouble info "                               are glob patterns."
	trouble info ""
	trouble info "  Debug options"
	trouble info ""
	trouble info "    --dots PATH                Write the changeset graphs before, after,"
	trouble info "                               and during breaking the of cycles to the"
	trouble info "                               direcotry PATH, using GraphViz's dot format"
	trouble info ""

	# --project, --cache

Changes to tools/cvs2fossil/lib/c2f_pass.tcl.

123
124
125
126
127
128
129





130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147



148
149
150
151
152
153
154
...
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
	    Call $p discard
	}

	state release
	ShowTimes
	return
    }






    proc Time {pass useconds} {
	::variable mytime
	lappend    mytime $pass $useconds

	return
    }

    proc ShowTimes {} {
	::variable mytime
	foreach {pass useconds} $mytime {
	    set sec [format %8.2f [expr {double($useconds)/1e6}]]
	    log write 0 pass "$sec sec/$pass"
	}
	return
    }

    # # ## ### ##### ######## #############
    ## Internal methods




    proc Ok? {code label ov {emptyok 1}} {
	upvar 1 $ov ok
	::variable mydesc
	if {$emptyok && ($code eq "")} return
	if {[info exists mydesc($code)]} return
	if {$label ne ""} {append label " "}
................................................................................
    # # ## ### ##### ######## #############
    ## Internal, state

    typevariable mypasses      {} ; # List of registered passes (codes).
    typevariable mydesc -array {} ; # Pass descriptions (one line).
    typevariable mycmd  -array {} ; # Pass callback command.

    typevariable mystart -1
    typevariable myend   -1
    typevariable mytime  {} ; # Timing data for each executed pass.


    # # ## ### ##### ######## #############
    ## Configuration

    pragma -hasinstances   no ; # singleton
    pragma -hastypeinfo    no ; # no introspection
    pragma -hastypedestroy no ; # immortal







>
>
>
>
>




>






|
<




|
|
>
>
>







 







|
|
|
>







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
	    Call $p discard
	}

	state release
	ShowTimes
	return
    }

    typemethod current {} { return $mycurrentpass }

    # # ## ### ##### ######## #############
    ## Internal methods

    proc Time {pass useconds} {
	::variable mytime
	lappend    mytime $pass $useconds
	ShowTime          $pass $useconds
	return
    }

    proc ShowTimes {} {
	::variable mytime
	foreach {pass useconds} $mytime {
	    ShowTime $pass $useconds

	}
	return
    }

    proc ShowTime {pass useconds} {
	set sec [format %8.2f [expr {double($useconds)/1e6}]]
	log write 0 pass "$sec sec/$pass"
	return
    }

    proc Ok? {code label ov {emptyok 1}} {
	upvar 1 $ov ok
	::variable mydesc
	if {$emptyok && ($code eq "")} return
	if {[info exists mydesc($code)]} return
	if {$label ne ""} {append label " "}
................................................................................
    # # ## ### ##### ######## #############
    ## Internal, state

    typevariable mypasses      {} ; # List of registered passes (codes).
    typevariable mydesc -array {} ; # Pass descriptions (one line).
    typevariable mycmd  -array {} ; # Pass callback command.

    typevariable mystart       -1
    typevariable myend         -1
    typevariable mytime        {} ; # Timing data for each executed pass.
    typevariable mycurrentpass {} ; # Pass currently running.

    # # ## ### ##### ######## #############
    ## Configuration

    pragma -hasinstances   no ; # singleton
    pragma -hastypeinfo    no ; # no introspection
    pragma -hastypedestroy no ; # immortal

Changes to tools/cvs2fossil/lib/c2f_patopsort.tcl.

41
42
43
44
45
46
47
48
49
50





51
52
53
54
55
56
57
58
59
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state reading revision
	state reading changeset
	state reading csorder






	state writing cstimestamp {
	    -- Commit order of all changesets based on their
	    -- dependencies, plus a monotonically increasing
	    -- timestamp.

	    cid  INTEGER  NOT NULL  REFERENCES changeset,
	    pos  INTEGER  NOT NULL,
	    date INTEGER  NOT NULL,







|
|
|
>
>
>
>
>

|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state use revision
	state use tag
	state use branch
	state use symbol
	state use changeset
	state use csitem
	state use cssuccessor
	state use csorder

	state extend cstimestamp {
	    -- Commit order of all changesets based on their
	    -- dependencies, plus a monotonically increasing
	    -- timestamp.

	    cid  INTEGER  NOT NULL  REFERENCES changeset,
	    pos  INTEGER  NOT NULL,
	    date INTEGER  NOT NULL,

Changes to tools/cvs2fossil/lib/c2f_pbreakacycle.tcl.

47
48
49
50
51
52
53
54
55
56




57
58
59
60
61
62
63
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state reading changeset
	state reading csitem
	state reading csorder




	return
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.







|
|
|
>
>
>
>







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state use revision
	state use tag
	state use branch
	state use symbol
	state use changeset
	state use csitem
	state use cssuccessor
	return
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.

Changes to tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl.

43
44
45
46
47
48
49
50
51
52




53
54
55
56
57
58
59
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state reading revision
	state reading changeset
	state reading csitem




	return
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.







|
|
|
>
>
>
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state use revision
	state use symbol
	state use changeset
	state use csitem
	state use cstype
	state use cssuccessor

	return
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.

Changes to tools/cvs2fossil/lib/c2f_pbreakscycle.tcl.

43
44
45
46
47
48
49
50
51
52




53
54
55
56
57
58
59
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state reading revision
	state reading changeset
	state reading csitem




	return
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.







|
|
|
>
>
>
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state use revision
	state use tag
	state use branch
	state use symbol
	state use changeset
	state use csitem
	state use cssuccessor
	return
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.

Changes to tools/cvs2fossil/lib/c2f_pcollar.tcl.

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	# does not hold, a name may occur several times, in different
	# projects. We further store the user visible file name
	# associated with the rcs archive.

	# Both projects and files are identified by globally unique
	# integer ids, automatically assigned by the database.

	state writing project {
	    pid  INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    name TEXT     NOT NULL  UNIQUE
	}
	state writing file {
	    fid     INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    pid     INTEGER  NOT NULL  REFERENCES project,       -- project the file belongs to
	    name    TEXT     NOT NULL,
	    visible TEXT     NOT NULL,
	    exec    INTEGER  NOT NULL, -- boolean, 'file executable'.
	    UNIQUE (pid, name)         -- file names are unique within a project
	}
................................................................................
    }

    typemethod load {} {
	# Pass manager interface. Executed for all passes before the
	# run passes, to load all data of their pass from the state,
	# as if it had been computed by the pass itself.

	state reading project
	state reading file

	repository load
	return
    }

    typemethod run {} {
	# Pass manager interface. Executed to perform the







|



|







 







|
|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	# does not hold, a name may occur several times, in different
	# projects. We further store the user visible file name
	# associated with the rcs archive.

	# Both projects and files are identified by globally unique
	# integer ids, automatically assigned by the database.

	state extend project {
	    pid  INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    name TEXT     NOT NULL  UNIQUE
	}
	state extend file {
	    fid     INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    pid     INTEGER  NOT NULL  REFERENCES project,       -- project the file belongs to
	    name    TEXT     NOT NULL,
	    visible TEXT     NOT NULL,
	    exec    INTEGER  NOT NULL, -- boolean, 'file executable'.
	    UNIQUE (pid, name)         -- file names are unique within a project
	}
................................................................................
    }

    typemethod load {} {
	# Pass manager interface. Executed for all passes before the
	# run passes, to load all data of their pass from the state,
	# as if it had been computed by the pass itself.

	state use project
	state use file

	repository load
	return
    }

    typemethod run {} {
	# Pass manager interface. Executed to perform the

Changes to tools/cvs2fossil/lib/c2f_pcollrev.tcl.

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define names and structure of the persistent state of this
	# pass.

	state reading project
	state reading file

	# We deal with per project and per file data, the first
	# collated from the second.

	# Per file we have general information, ..., and then
	# revisions and symbols. The latter can be further separated
	# into tags and branches. At project level the per-file
................................................................................
	#	Revisions, Branches, Tags
	#
	# Pseudo class hierarchy
	#	Tag      <- Symbol <- Event
	#	Branch   <- Symbol <- Event
	#	Revision           <- Event

	state writing revision {
	    -- Revisions. Identified by a global numeric id each
	    -- belongs to a single file, identified by its id. It
	    -- further has a dotted revision number (DTN).
	    --
	    -- Constraint: The dotted revision number is unique within
            --             the file. See end of definition.

................................................................................
	    mid   INTEGER  NOT NULL  REFERENCES meta,
	    coff  INTEGER  NOT NULL,
	    clen  INTEGER  NOT NULL,

	    UNIQUE (fid, rev) -- The DTN is unique within the revision's file.
	}

	state writing optype {
	    oid   INTEGER  NOT NULL  PRIMARY KEY,
	    name  TEXT     NOT NULL,
	    UNIQUE(name)
	}
	state run {
	    INSERT INTO optype VALUES (-1,'delete');  -- The opcode names are the
	    INSERT INTO optype VALUES ( 0,'nothing'); -- fixed pieces, see myopstate
	    INSERT INTO optype VALUES ( 1,'add');     -- in file::rev. myopcode is
	    INSERT INTO optype VALUES ( 2,'change');  -- loaded from this.
	}

	state writing revisionbranchchildren {
	    -- The non-primary children of a revision, as reachable
	    -- through a branch symbol, are listed here. This is
	    -- needed by pass 5 to break internal dependencies in a
	    -- changeset.

	    rid   INTEGER  NOT NULL  REFERENCES revision,
	    brid  INTEGER  NOT NULL  REFERENCES revision,
	    UNIQUE(rid,brid)
	}

	state writing tag {
	    tid  INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    fid  INTEGER  NOT NULL  REFERENCES file,     -- File the item belongs to
	    lod  INTEGER            REFERENCES symbol,   -- Line of development (NULL => Trunk)
	    sid  INTEGER  NOT NULL  REFERENCES symbol,   -- Symbol capturing the tag

	    rev  INTEGER  NOT NULL  REFERENCES revision  -- The revision being tagged.
	} { rev sid }
	# Indices on: rev (revision successors)
	#             sid (tag predecessors, branch successors/predecessors)

	state writing branch {
	    bid   INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    fid   INTEGER  NOT NULL  REFERENCES file,     -- File the item belongs to
	    lod   INTEGER            REFERENCES symbol,   -- Line of development (NULL => Trunk)
	    sid   INTEGER  NOT NULL  REFERENCES symbol,   -- Symbol capturing the branch

	    root  INTEGER            REFERENCES revision, -- Revision the branch sprouts from
	    first INTEGER            REFERENCES revision, -- First revision committed to the branch
................................................................................
	# Project level ...
	#	pLineOfDevelopment, pSymbol, pBranch, pTag, pTrunk
	#
	#	pTrunk  <- pLineOfDevelopment
	#	pBranch <- pSymbol, pLineOfDevelopment
	#	pTag    <- pSymbol, pLineOfDevelopment

	state writing symbol {
	    sid  INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    pid  INTEGER  NOT NULL  REFERENCES project,  -- Project the symbol belongs to
	    name TEXT     NOT NULL,
	    type INTEGER  NOT NULL  REFERENCES symtype,  -- enum { excluded = 0, tag, branch, undefined }

	    tag_count    INTEGER  NOT NULL, -- How often the symbol is used as tag.
	    branch_count INTEGER  NOT NULL, -- How often the symbol is used as branch
	    commit_count INTEGER  NOT NULL, -- How often a file was committed on the symbol

	    UNIQUE (pid, name) -- Symbols are unique within the project
	}

	state writing blocker {
	    -- For each symbol we save which other symbols are
	    -- blocking its removal (if the user asks for it).

	    sid INTEGER  NOT NULL  REFERENCES symbol, --
	    bid INTEGER  NOT NULL  REFERENCES symbol, -- Sprouted from sid, blocks it.
	    UNIQUE (sid, bid)
	}

	state writing parent {
	    -- For each symbol we save which other symbols can act as
	    -- a possible parent in some file, and how often.

	    sid INTEGER  NOT NULL  REFERENCES symbol, --
	    pid INTEGER  NOT NULL  REFERENCES symbol, -- Possible parent of sid
	    n   INTEGER  NOT NULL,                    -- How often pid can act as parent.
	    UNIQUE (sid, pid)
	}

	state writing symtype {
	    tid    INTEGER  NOT NULL  PRIMARY KEY,
	    name   TEXT     NOT NULL,
	    plural TEXT     NOT NULL,
	    UNIQUE (name)
	    UNIQUE (plural)
	}
	state run {
	    INSERT INTO symtype VALUES (0,'excluded', 'excluded');
	    INSERT INTO symtype VALUES (1,'tag',      'tags');
	    INSERT INTO symtype VALUES (2,'branch',   'branches');
	    INSERT INTO symtype VALUES (3,'undefined','undefined');
	}

	state writing meta {
	    -- Meta data of revisions. See revision.mid for the
	    -- reference. Many revisions can share meta data. This is
	    -- actually one of the criterions used to sort revisions
	    -- into changesets.

	    mid INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,

................................................................................
	    --              X is the same as the line of development
	    --              of X itself.
	}

	# Authors and commit messages are fully global, i.e. per
	# repository.

	state writing author {
	    aid  INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    name TEXT     NOT NULL  UNIQUE
	}

	state writing cmessage {
	    cid  INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    text TEXT     NOT NULL  UNIQUE
	}

	project::sym getsymtypes
	file::rev    getopcodes
	return
    }

    typemethod load {} {
	state reading symbol
	state reading symtype
	state reading optype

	project::sym getsymtypes
	file::rev    getopcodes
	repository   loadsymbols
	return
    }








|
|







 







|







 







|











|










|










|







 







|












|








|









|













|







 







|




|










|
|
|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define names and structure of the persistent state of this
	# pass.

	state use project
	state use file

	# We deal with per project and per file data, the first
	# collated from the second.

	# Per file we have general information, ..., and then
	# revisions and symbols. The latter can be further separated
	# into tags and branches. At project level the per-file
................................................................................
	#	Revisions, Branches, Tags
	#
	# Pseudo class hierarchy
	#	Tag      <- Symbol <- Event
	#	Branch   <- Symbol <- Event
	#	Revision           <- Event

	state extend revision {
	    -- Revisions. Identified by a global numeric id each
	    -- belongs to a single file, identified by its id. It
	    -- further has a dotted revision number (DTN).
	    --
	    -- Constraint: The dotted revision number is unique within
            --             the file. See end of definition.

................................................................................
	    mid   INTEGER  NOT NULL  REFERENCES meta,
	    coff  INTEGER  NOT NULL,
	    clen  INTEGER  NOT NULL,

	    UNIQUE (fid, rev) -- The DTN is unique within the revision's file.
	}

	state extend optype {
	    oid   INTEGER  NOT NULL  PRIMARY KEY,
	    name  TEXT     NOT NULL,
	    UNIQUE(name)
	}
	state run {
	    INSERT INTO optype VALUES (-1,'delete');  -- The opcode names are the
	    INSERT INTO optype VALUES ( 0,'nothing'); -- fixed pieces, see myopstate
	    INSERT INTO optype VALUES ( 1,'add');     -- in file::rev. myopcode is
	    INSERT INTO optype VALUES ( 2,'change');  -- loaded from this.
	}

	state extend revisionbranchchildren {
	    -- The non-primary children of a revision, as reachable
	    -- through a branch symbol, are listed here. This is
	    -- needed by pass 5 to break internal dependencies in a
	    -- changeset.

	    rid   INTEGER  NOT NULL  REFERENCES revision,
	    brid  INTEGER  NOT NULL  REFERENCES revision,
	    UNIQUE(rid,brid)
	}

	state extend tag {
	    tid  INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    fid  INTEGER  NOT NULL  REFERENCES file,     -- File the item belongs to
	    lod  INTEGER            REFERENCES symbol,   -- Line of development (NULL => Trunk)
	    sid  INTEGER  NOT NULL  REFERENCES symbol,   -- Symbol capturing the tag

	    rev  INTEGER  NOT NULL  REFERENCES revision  -- The revision being tagged.
	} { rev sid }
	# Indices on: rev (revision successors)
	#             sid (tag predecessors, branch successors/predecessors)

	state extend branch {
	    bid   INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    fid   INTEGER  NOT NULL  REFERENCES file,     -- File the item belongs to
	    lod   INTEGER            REFERENCES symbol,   -- Line of development (NULL => Trunk)
	    sid   INTEGER  NOT NULL  REFERENCES symbol,   -- Symbol capturing the branch

	    root  INTEGER            REFERENCES revision, -- Revision the branch sprouts from
	    first INTEGER            REFERENCES revision, -- First revision committed to the branch
................................................................................
	# Project level ...
	#	pLineOfDevelopment, pSymbol, pBranch, pTag, pTrunk
	#
	#	pTrunk  <- pLineOfDevelopment
	#	pBranch <- pSymbol, pLineOfDevelopment
	#	pTag    <- pSymbol, pLineOfDevelopment

	state extend symbol {
	    sid  INTEGER  NOT NULL  PRIMARY KEY AUTOINCREMENT,
	    pid  INTEGER  NOT NULL  REFERENCES project,  -- Project the symbol belongs to
	    name TEXT     NOT NULL,
	    type INTEGER  NOT NULL  REFERENCES symtype,  -- enum { excluded = 0, tag, branch, undefined }

	    tag_count    INTEGER  NOT NULL, -- How often the symbol is used as tag.
	    branch_count INTEGER  NOT NULL, -- How often the symbol is used as branch
	    commit_count INTEGER  NOT NULL, -- How often a file was committed on the symbol

	    UNIQUE (pid, name) -- Symbols are unique within the project
	}

	state extend blocker {
	    -- For each symbol we save which other symbols are
	    -- blocking its removal (if the user asks for it).

	    sid INTEGER  NOT NULL  REFERENCES symbol, --
	    bid INTEGER  NOT NULL  REFERENCES symbol, -- Sprouted from sid, blocks it.
	    UNIQUE (sid, bid)
	}

	state extend parent {
	    -- For each symbol we save which other symbols can act as
	    -- a possible parent in some file, and how often.

	    sid INTEGER  NOT NULL  REFERENCES symbol, --
	    pid INTEGER  NOT NULL  REFERENCES symbol, -- Possible parent of sid
	    n   INTEGER  NOT NULL,                    -- How often pid can act as parent.
	    UNIQUE (sid, pid)
	}

	state extend symtype {
	    tid    INTEGER  NOT NULL  PRIMARY KEY,
	    name   TEXT     NOT NULL,
	    plural TEXT     NOT NULL,
	    UNIQUE (name)
	    UNIQUE (plural)
	}
	state run {
	    INSERT INTO symtype VALUES (0,'excluded', 'excluded');
	    INSERT INTO symtype VALUES (1,'tag',      'tags');
	    INSERT INTO symtype VALUES (2,'branch',   'branches');
	    INSERT INTO symtype VALUES (3,'undefined','undefined');
	}

	state extend meta {
	    -- Meta data of revisions. See revision.mid for the
	    -- reference. Many revisions can share meta data. This is
	    -- actually one of the criterions used to sort revisions
	    -- into changesets.

	    mid INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,

................................................................................
	    --              X is the same as the line of development
	    --              of X itself.
	}

	# Authors and commit messages are fully global, i.e. per
	# repository.

	state extend author {
	    aid  INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    name TEXT     NOT NULL  UNIQUE
	}

	state extend cmessage {
	    cid  INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    text TEXT     NOT NULL  UNIQUE
	}

	project::sym getsymtypes
	file::rev    getopcodes
	return
    }

    typemethod load {} {
	state use symbol
	state use symtype
	state use optype

	project::sym getsymtypes
	file::rev    getopcodes
	repository   loadsymbols
	return
    }

Changes to tools/cvs2fossil/lib/c2f_pcollsym.tcl.

41
42
43
44
45
46
47
48
49
50


51
52
53
54
55
56
57
58
59
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define names and structure of the persistent state of this
	# pass.

	state reading symbol
	state reading blocker
	state reading parent



	state writing preferedparent {
	    -- For each symbol the prefered parent. This describes the
	    -- tree of the found lines of development. Actually a
	    -- forest in case of multiple projects, with one tree per
	    -- project.

	    sid INTEGER  NOT NULL  PRIMARY KEY  REFERENCES symbol,
	    pid INTEGER  NOT NULL               REFERENCES symbol







|
|
|
>
>

|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define names and structure of the persistent state of this
	# pass.

	state use project
	state use symbol
	state use symtype
	state use blocker
	state use parent

	state extend preferedparent {
	    -- For each symbol the prefered parent. This describes the
	    -- tree of the found lines of development. Actually a
	    -- forest in case of multiple projects, with one tree per
	    -- project.

	    sid INTEGER  NOT NULL  PRIMARY KEY  REFERENCES symbol,
	    pid INTEGER  NOT NULL               REFERENCES symbol

Changes to tools/cvs2fossil/lib/c2f_pfiltersym.tcl.

41
42
43
44
45
46
47
48
49
50
51
52
53

54
55





56
57


58
59
60
61
62
63
64
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define names and structure of the persistent state of this
	# pass.

	state reading symbol
	state reading blocker
	state reading parent
	state reading preferedparent
	state reading revision
	state reading revisionbranchchildren

	state reading branch
	state reading tag






	state writing noop {


	    id    INTEGER NOT NULL  PRIMARY KEY, -- tag/branch reference
	    noop  INTEGER NOT NULL
	}
	return
    }

    typemethod load {} {







|
|
<
<
|
|
>
|
|
>
>
>
>
>

<
>
>







41
42
43
44
45
46
47
48
49


50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define names and structure of the persistent state of this
	# pass.

	state use project
	state use file


	state use revision
	state use revisionbranchchildren
	state use branch
	state use tag
	state use symbol
	state use blocker
	state use parent
	state use author
	state use cmessage
	state use preferedparent


	# NOTE: So far no pass coming after this makes us of this information.
	state extend noop {
	    id    INTEGER NOT NULL  PRIMARY KEY, -- tag/branch reference
	    noop  INTEGER NOT NULL
	}
	return
    }

    typemethod load {} {

Changes to tools/cvs2fossil/lib/c2f_pinitcsets.tcl.

41
42
43
44
45
46
47

48
49
50

51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
..
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.


	state reading meta
	state reading revision
	state reading revisionbranchchildren

	state reading branch

	state reading tag
	state reading symbol

	# Data per changeset, namely the project it belongs to, how it
	# was induced (revision or symbol), plus reference to the
	# primary entry causing it (meta entry or symbol). An adjunct
	# table translates the type id's into human readable labels.

	state writing changeset {
	    cid   INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    pid   INTEGER  NOT NULL  REFERENCES project,
	    type  INTEGER  NOT NULL  REFERENCES cstype,
	    src   INTEGER  NOT NULL -- REFERENCES meta|symbol (type dependent)
	}
	state writing cstype {
	    tid   INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    name  TEXT     NOT NULL,
	    UNIQUE (name)
	}
	# Note: Keep the labels used here in sync with the names for
	#       singleton helper classes for 'project::rev'. They are
	#       the valid type names for changesets and also hardwired
................................................................................
	# changeset.  The items are in principle unique, if we were
	# looking only at relevant changesets. However as they come
	# from disparate sources the same id may have different
	# meaning, be in different changesets and so is formally not
	# unique. So we can only say that it is unique within the
	# changeset. The integrity module has stronger checks.

	state writing csitem {
	    cid  INTEGER  NOT NULL  REFERENCES changeset,
	    pos  INTEGER  NOT NULL,
	    iid  INTEGER  NOT NULL, -- REFERENCES revision|tag|branch
	    UNIQUE (cid, pos),
	    UNIQUE (cid, iid)
	} { iid }
	# Index on: iid (successor/predecessor retrieval)
................................................................................
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.

	state reading changeset
	state reading csitem
	state reading cstype

	# Need the types first, the constructor in the loop below uses
	# them to assert the correctness of type names.
	project::rev getcstypes

	# TODO: Move to project::rev
	set n 0







>
|
|
|
>
|
>
|
<






|





|







 







|







 







|
|
|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
..
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state use project
	state use file
	state use revision
	state use revisionbranchchildren
	state use branch
	state use tag
	state use symbol
	state use meta


	# Data per changeset, namely the project it belongs to, how it
	# was induced (revision or symbol), plus reference to the
	# primary entry causing it (meta entry or symbol). An adjunct
	# table translates the type id's into human readable labels.

	state extend changeset {
	    cid   INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    pid   INTEGER  NOT NULL  REFERENCES project,
	    type  INTEGER  NOT NULL  REFERENCES cstype,
	    src   INTEGER  NOT NULL -- REFERENCES meta|symbol (type dependent)
	}
	state extend cstype {
	    tid   INTEGER  NOT NULL  PRIMARY KEY  AUTOINCREMENT,
	    name  TEXT     NOT NULL,
	    UNIQUE (name)
	}
	# Note: Keep the labels used here in sync with the names for
	#       singleton helper classes for 'project::rev'. They are
	#       the valid type names for changesets and also hardwired
................................................................................
	# changeset.  The items are in principle unique, if we were
	# looking only at relevant changesets. However as they come
	# from disparate sources the same id may have different
	# meaning, be in different changesets and so is formally not
	# unique. So we can only say that it is unique within the
	# changeset. The integrity module has stronger checks.

	state extend csitem {
	    cid  INTEGER  NOT NULL  REFERENCES changeset,
	    pos  INTEGER  NOT NULL,
	    iid  INTEGER  NOT NULL, -- REFERENCES revision|tag|branch
	    UNIQUE (cid, pos),
	    UNIQUE (cid, iid)
	} { iid }
	# Index on: iid (successor/predecessor retrieval)
................................................................................
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.

	state use changeset
	state use csitem
	state use cstype

	# Need the types first, the constructor in the loop below uses
	# them to assert the correctness of type names.
	project::rev getcstypes

	# TODO: Move to project::rev
	set n 0

Changes to tools/cvs2fossil/lib/c2f_prtopsort.tcl.

41
42
43
44
45
46
47
48
49
50



51
52
53
54
55
56
57
58
59
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state reading revision
	state reading changeset
	state reading csitem




	state writing csorder {
	    -- Commit order of the revision changesets based on their
	    -- dependencies

	    cid INTEGER  NOT NULL  REFERENCES changeset,
	    pos INTEGER  NOT NULL,
	    UNIQUE (cid),
	    UNIQUE (pos)
................................................................................
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.

	state reading changeset
	project::rev loadcounter
	return
    }

    typemethod run {} {
	# Pass manager interface. Executed to perform the
	# functionality of the pass.







|
|
|
>
>
>

|







 







|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    # # ## ### ##### ######## #############
    ## Public API

    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state use revision
	state use symbol
	state use changeset
	state use csitem
	state use cstype
	state use cssuccessor

	state extend csorder {
	    -- Commit order of the revision changesets based on their
	    -- dependencies

	    cid INTEGER  NOT NULL  REFERENCES changeset,
	    pos INTEGER  NOT NULL,
	    UNIQUE (cid),
	    UNIQUE (pos)
................................................................................
    }

    typemethod load {} {
	# Pass manager interface. Executed to load data computed by
	# this pass into memory when this pass is skipped instead of
	# executed.

	state use changeset
	project::rev loadcounter
	return
    }

    typemethod run {} {
	# Pass manager interface. Executed to perform the
	# functionality of the pass.

Changes to tools/cvs2fossil/lib/c2f_state.tcl.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
..
91
92
93
94
95
96
97
98
99
100
101


102
103


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125

126
127
128
129
130
131
132
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158

159
160
161
162
163
164
165
166
167
168














169
170
171
172
173
174

175
176
177
178
179
180
181
# # ## ### ##### ######## ############# #####################
##

snit::type ::vc::fossil::import::cvs::state {
    # # ## ### ##### ######## #############
    ## Public API

    typemethod use {path} {
	# Immediate validation. There are are two possibilities to
	# consider. The path exists or it doesn't.

	# In the first case it has to be a readable and writable file,
	# and it has to be a proper sqlite database. Further checks
	# regarding the required tables will be done later, by the
	# passes, during their setup.
................................................................................
	log write 2 state release
	${type}::STATE close
	if {$mypath eq ""} return
	file delete $mypath
	return
    }

    typemethod writing {name definition {indices {}}} {
	# Method for a user to declare a table its needs for storing
	# persistent state, and the expected structure. A possibly
	# previously existing definition is dropped.



	log write 1 state "writing $name" ; # TODO move to level 5 or so



	$mystate transaction {
	    catch { $mystate eval "DROP TABLE $name" }
	    $mystate eval "CREATE TABLE $name ( $definition )"

	    set id 0
	    foreach columns $indices {
		log write 1 state "index   $name$id" ; # TODO move to level 5 or so

		$mystate eval "CREATE INDEX ${name}$id ON ${name} ( [join $columns ,] )"
		incr id
	    }
	}
	return
    }

    typemethod reading {name} {
	log write 1 state "reading $name" ; # TODO move to level 5 or so


	# Method for a user to declare a table it wishes to read
	# from. A missing table is an internal error causing an
	# immediate exit.


	set found [llength [$mystate eval {
	    SELECT name
	    FROM sqlite_master
	    WHERE type = 'table'
	    AND   name = $name
	    ;
................................................................................
	return
    }

    typemethod discard {name} {
	# Method for a user to remove outdated information from the
	# persistent state, table by table.

	log write 1 state "discard $name" ; # TODO move to level 5 or so

	$mystate transaction {
	    catch { $mystate eval "DROP TABLE $name" }
	}
	return
    }

    typemethod run {args} {

	return [uplevel 1 [linsert $args 0 $mystate eval]]
    }

    typemethod one {args} {

	return [lindex [uplevel 1 [linsert $args 0 $mystate eval]] 0]
    }

    typemethod transaction {script} {
	return [uplevel 1 [list $mystate transaction $script]]
    }

    typemethod id {} {
	return [$mystate last_insert_rowid]
    }















    # # ## ### ##### ######## #############
    ## State

    typevariable mystate {} ; # Sqlite database (command) holding the converter state.
    typevariable mypath  {} ; # Path to the database, for cleanup of a temp database.


    # # ## ### ##### ######## #############
    ## Internal methods


    # # ## ### ##### ######## #############
    ## Configuration







|







 







|
<
<
|
>
>

|
>
>







|








|
|
>

<
|
|
>







 







|








>




>
|









>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
|
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
..
91
92
93
94
95
96
97
98


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# # ## ### ##### ######## ############# #####################
##

snit::type ::vc::fossil::import::cvs::state {
    # # ## ### ##### ######## #############
    ## Public API

    typemethod usedb {path} {
	# Immediate validation. There are are two possibilities to
	# consider. The path exists or it doesn't.

	# In the first case it has to be a readable and writable file,
	# and it has to be a proper sqlite database. Further checks
	# regarding the required tables will be done later, by the
	# passes, during their setup.
................................................................................
	log write 2 state release
	${type}::STATE close
	if {$mypath eq ""} return
	file delete $mypath
	return
    }

    # Declare a table needed for the storing of persistent state, and


    # its structure. A possibly previously existing definition is
    # dropped. To be used when a table is needed and not assumed to
    # exist from previous passes.

    typemethod extend {name definition {indices {}}} {
	log write 5 state "extend $name"
	Save "extend $name ================================"

	$mystate transaction {
	    catch { $mystate eval "DROP TABLE $name" }
	    $mystate eval "CREATE TABLE $name ( $definition )"

	    set id 0
	    foreach columns $indices {
		log write 5 state "index  $name$id"

		$mystate eval "CREATE INDEX ${name}$id ON ${name} ( [join $columns ,] )"
		incr id
	    }
	}
	return
    }

    # Declare that a table is needed for reading from and/or storing
    # to persistent state, and is assumed to already exist. A missing
    # table is an internal error causing an immediate exit.


    typemethod use {name} {
	log write 5 state "use    $name"
	Save "use $name ==================================="

	set found [llength [$mystate eval {
	    SELECT name
	    FROM sqlite_master
	    WHERE type = 'table'
	    AND   name = $name
	    ;
................................................................................
	return
    }

    typemethod discard {name} {
	# Method for a user to remove outdated information from the
	# persistent state, table by table.

	log write 5 state "discard $name"

	$mystate transaction {
	    catch { $mystate eval "DROP TABLE $name" }
	}
	return
    }

    typemethod run {args} {
	Save $args
	return [uplevel 1 [linsert $args 0 $mystate eval]]
    }

    typemethod one {args} {
	Save $args
	return [uplevel 1 [linsert $args 0 $mystate onecolumn]]
    }

    typemethod transaction {script} {
	return [uplevel 1 [list $mystate transaction $script]]
    }

    typemethod id {} {
	return [$mystate last_insert_rowid]
    }

    typemethod savequeriesto {path} {
	set mysavepath $path
	return
    }

    # # ## ### ##### ######## #############

    proc Save {text} {
	::variable mysavepath
	if {$mysavepath eq ""} return
	fileutil::appendToFile $mysavepath $text\n\n
	return
    }

    # # ## ### ##### ######## #############
    ## State

    typevariable mystate    {} ; # Sqlite database (command) holding the converter state.
    typevariable mypath     {} ; # Path to the database, for cleanup of a temp database.
    typevariable mysavepath {} ; # Path where to save queries for introspection.

    # # ## ### ##### ######## #############
    ## Internal methods


    # # ## ### ##### ######## #############
    ## Configuration