Fossil

Check-in [96b7bfb834]
Login

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

Overview
Comment:Added convenience command to the state package when the sql returns a single row. Added more statistics about revisions, tags, branches, symbols, changesets to various passes.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 96b7bfb83401cc7e8ea8ad0eb803e6f50b3b50ff
User & Date: aku 2007-11-16 08:32:40.000
Context
2007-11-17
04:39
Added an option "--batch" with which the user can disable the feedback display standard to interactive use. ... (check-in: 4e7dd05fc6 user: aku tags: trunk)
00:29
Merge aku's CVS import changes into the main line. Fix a small bug in diff.c. ... (check-in: 38b967dcf5 user: drh tags: trunk)
2007-11-16
08:32
Added convenience command to the state package when the sql returns a single row. Added more statistics about revisions, tags, branches, symbols, changesets to various passes. ... (check-in: 96b7bfb834 user: aku tags: trunk)
06:55
Moved out-of-place state declarations to the proper phase (setup, not run). ... (check-in: ce7fb48e8c user: aku tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl.
18
19
20
21
22
23
24

25
26
27
28
29
30
31
# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.4                                   ; # Required runtime.
package require snit                                      ; # OO system.
package require struct::list                              ; # Higher order list operations.
package require vc::tools::log                            ; # User feedback.

package require vc::fossil::import::cvs::cyclebreaker     ; # Breaking dependency cycles.
package require vc::fossil::import::cvs::state            ; # State storage.
package require vc::fossil::import::cvs::project::rev     ; # Project level changesets

# # ## ### ##### ######## ############# #####################
## Register the pass with the management








>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.4                                   ; # Required runtime.
package require snit                                      ; # OO system.
package require struct::list                              ; # Higher order list operations.
package require vc::tools::log                            ; # User feedback.
package require vc::fossil::import::cvs::repository       ; # Repository management.
package require vc::fossil::import::cvs::cyclebreaker     ; # Breaking dependency cycles.
package require vc::fossil::import::cvs::state            ; # State storage.
package require vc::fossil::import::cvs::project::rev     ; # Project level changesets

# # ## ### ##### ######## ############# #####################
## Register the pass with the management

74
75
76
77
78
79
80


81
82
83
84
85
86
87
	# functionality of the pass.

	state transaction {
	    cyclebreaker run [struct::list filter [project::rev all] \
				  [myproc IsByRevision]] \
		[myproc SaveOrder]
	}


	return
    }

    typemethod discard {} {
	# Pass manager interface. Executed for all passes after the
	# run passes, to remove all data of this pass from the state,
	# as being out of date.







>
>







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
	# functionality of the pass.

	state transaction {
	    cyclebreaker run [struct::list filter [project::rev all] \
				  [myproc IsByRevision]] \
		[myproc SaveOrder]
	}

	repository printcsetstatistics
	return
    }

    typemethod discard {} {
	# Pass manager interface. Executed for all passes after the
	# run passes, to remove all data of this pass from the state,
	# as being out of date.
117
118
119
120
121
122
123

124
125
126
127
128
129
130
    # # ## ### ##### ######## #############
}

namespace eval ::vc::fossil::import::cvs::pass {
    namespace export breakrcycle
    namespace eval breakrcycle {
	namespace import ::vc::fossil::import::cvs::cyclebreaker

	namespace import ::vc::fossil::import::cvs::state
	namespace eval project {
	    namespace import ::vc::fossil::import::cvs::project::rev
	}
	namespace import ::vc::tools::log
	log register breakrcycle
    }







>







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    # # ## ### ##### ######## #############
}

namespace eval ::vc::fossil::import::cvs::pass {
    namespace export breakrcycle
    namespace eval breakrcycle {
	namespace import ::vc::fossil::import::cvs::cyclebreaker
	namespace import ::vc::fossil::import::cvs::repository
	namespace import ::vc::fossil::import::cvs::state
	namespace eval project {
	    namespace import ::vc::fossil::import::cvs::project::rev
	}
	namespace import ::vc::tools::log
	log register breakrcycle
    }
Changes to tools/cvs2fossil/lib/c2f_pbreakscycle.tcl.
18
19
20
21
22
23
24

25
26
27
28
29
30
31
# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.4                                   ; # Required runtime.
package require snit                                      ; # OO system.
package require struct::list                              ; # Higher order list operations.
package require vc::fossil::import::cvs::cyclebreaker     ; # Breaking dependency cycles.

package require vc::fossil::import::cvs::state            ; # State storage.
package require vc::fossil::import::cvs::project::rev     ; # Project level changesets

# # ## ### ##### ######## ############# #####################
## Register the pass with the management

vc::fossil::import::cvs::pass define \







>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.4                                   ; # Required runtime.
package require snit                                      ; # OO system.
package require struct::list                              ; # Higher order list operations.
package require vc::fossil::import::cvs::cyclebreaker     ; # Breaking dependency cycles.
package require vc::fossil::import::cvs::repository       ; # Repository management.
package require vc::fossil::import::cvs::state            ; # State storage.
package require vc::fossil::import::cvs::project::rev     ; # Project level changesets

# # ## ### ##### ######## ############# #####################
## Register the pass with the management

vc::fossil::import::cvs::pass define \
61
62
63
64
65
66
67


68
69
70
71
72
73
74
	# Pass manager interface. Executed to perform the
	# functionality of the pass.

	state transaction {
	    cyclebreaker run [struct::list filter [project::rev all] \
				  [myproc IsBySymbol]]
	}


	return
    }

    typemethod discard {} {
	# Pass manager interface. Executed for all passes after the
	# run passes, to remove all data of this pass from the state,
	# as being out of date.







>
>







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
	# Pass manager interface. Executed to perform the
	# functionality of the pass.

	state transaction {
	    cyclebreaker run [struct::list filter [project::rev all] \
				  [myproc IsBySymbol]]
	}

	repository printcsetstatistics
	return
    }

    typemethod discard {} {
	# Pass manager interface. Executed for all passes after the
	# run passes, to remove all data of this pass from the state,
	# as being out of date.
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
    # # ## ### ##### ######## #############
}

namespace eval ::vc::fossil::import::cvs::pass {
    namespace export breakscycle
    namespace eval breakscycle {
	namespace import ::vc::fossil::import::cvs::cyclebreaker

	namespace import ::vc::fossil::import::cvs::state
	namespace eval project {
	    namespace import ::vc::fossil::import::cvs::project::rev
	}
    }
}

# # ## ### ##### ######## ############# #####################
## Ready

package provide vc::fossil::import::cvs::pass::breakscycle 1.0
return







>












93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    # # ## ### ##### ######## #############
}

namespace eval ::vc::fossil::import::cvs::pass {
    namespace export breakscycle
    namespace eval breakscycle {
	namespace import ::vc::fossil::import::cvs::cyclebreaker
	namespace import ::vc::fossil::import::cvs::repository
	namespace import ::vc::fossil::import::cvs::state
	namespace eval project {
	    namespace import ::vc::fossil::import::cvs::project::rev
	}
    }
}

# # ## ### ##### ######## ############# #####################
## Ready

package provide vc::fossil::import::cvs::pass::breakscycle 1.0
return
Changes to tools/cvs2fossil/lib/c2f_pcollrev.tcl.
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

		$file drop
	    }

	    $project purgeghostsymbols
	}

	repository printrevstatistics
	repository persistrev
	integrity  strict

	log write 1 collrev "Scan completed"
	return
    }

    typemethod discard {} {







|
|







337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

		$file drop
	    }

	    $project purgeghostsymbols
	}

	repository persistrev
	repository printrevstatistics
	integrity  strict

	log write 1 collrev "Scan completed"
	return
    }

    typemethod discard {} {
Changes to tools/cvs2fossil/lib/c2f_pfiltersym.tcl.
17
18
19
20
21
22
23

24
25
26
27
28
29
30
# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.4                               ; # Required runtime.
package require snit                                  ; # OO system.
package require vc::tools::misc                       ; # Text formatting.
package require vc::tools::log                        ; # User feedback.

package require vc::fossil::import::cvs::state        ; # State storage.
package require vc::fossil::import::cvs::integrity    ; # State storage integrity checks.
package require vc::fossil::import::cvs::project::sym ; # Project level symbols

# # ## ### ##### ######## ############# #####################
## Register the pass with the management








>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.4                               ; # Required runtime.
package require snit                                  ; # OO system.
package require vc::tools::misc                       ; # Text formatting.
package require vc::tools::log                        ; # User feedback.
package require vc::fossil::import::cvs::repository   ; # Repository management.
package require vc::fossil::import::cvs::state        ; # State storage.
package require vc::fossil::import::cvs::integrity    ; # State storage integrity checks.
package require vc::fossil::import::cvs::project::sym ; # Project level symbols

# # ## ### ##### ######## ############# #####################
## Register the pass with the management

78
79
80
81
82
83
84


85
86
87
88
89
90
91
	# to them is done completely in the database.

	state transaction {
	    FilterExcludedSymbols
	    MutateSymbols
	    AdjustParents
	    RefineSymbols



	    # Strict integrity enforces that all meta entries are in
	    # the same LOD as the revision using them. At this point
	    # this may not be true any longer. If a NTDB was excluded
	    # then all revisions it shared with the trunk were moved
	    # to the trunk LOD, however their meta entries will still
	    # refer to the now gone LOD symbol. This is fine however,







>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
	# to them is done completely in the database.

	state transaction {
	    FilterExcludedSymbols
	    MutateSymbols
	    AdjustParents
	    RefineSymbols

	    repository printrevstatistics

	    # Strict integrity enforces that all meta entries are in
	    # the same LOD as the revision using them. At this point
	    # this may not be true any longer. If a NTDB was excluded
	    # then all revisions it shared with the trunk were moved
	    # to the trunk LOD, however their meta entries will still
	    # refer to the now gone LOD symbol. This is fine however,
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
	return
    }

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

    proc FilterExcludedSymbols {} {
	log write 3 filtersym "Filter out excluded symbols and users"

	# We pull all the excluded symbols together into a table for
	# easy reference by the upcoming DELETE and other statements.
	# ('x IN table' clauses).

	set excl [project::sym excluded]








|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
	return
    }

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

    proc FilterExcludedSymbols {} {
	log write 3 filtersym "Remove the excluded symbols and their users"

	# We pull all the excluded symbols together into a table for
	# easy reference by the upcoming DELETE and other statements.
	# ('x IN table' clauses).

	set excl [project::sym excluded]

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
	    # shared with their respective trunk. We disconnect from
	    # their NTDB children, and make them parents of their
	    # 'dbchild'. The associated 'dbparent' is squashed
	    # instead. All parents of the joints are moved to the
	    # trunk as well.

	    set tjoint $link($joint)
	    set tlod [lindex [state run {
		SELECT lod FROM revision WHERE rid = $tjoint
	    }] 0]

	    # Covnert db/parent/child into regular parent/child links.
	    state run {
		UPDATE revision SET dbparent = NULL, parent = $joint  WHERE rid = $tjoint ;
		UPDATE revision SET dbchild  = NULL, child  = $tjoint WHERE rid = $joint  ;
	    }
	    while {1} {







|

|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
	    # shared with their respective trunk. We disconnect from
	    # their NTDB children, and make them parents of their
	    # 'dbchild'. The associated 'dbparent' is squashed
	    # instead. All parents of the joints are moved to the
	    # trunk as well.

	    set tjoint $link($joint)
	    set tlod [state one {
		SELECT lod FROM revision WHERE rid = $tjoint
	    }]

	    # Covnert db/parent/child into regular parent/child links.
	    state run {
		UPDATE revision SET dbparent = NULL, parent = $joint  WHERE rid = $tjoint ;
		UPDATE revision SET dbchild  = NULL, child  = $tjoint WHERE rid = $joint  ;
	    }
	    while {1} {
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
	    # based finding the branch as possible parent, and done
	    # now instead of as part of the already complex join.
	    #
	    # ... AND P.pid IN (SELECT B.sid
	    #                   FROM branch B
	    #                   WHERE B.root = R.rid)

	    if {![lindex [state run {
		SELECT COUNT(*)
		FROM branch B
		WHERE  B.sid  = $pid
		AND    B.root = $rid
	    }] 0]} {
		incr tmax -1
		set  mxs [format $fmt $tmax]
		continue
	    }

	    #
	    # BOTTLE-NECK ...







|




|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
	    # based finding the branch as possible parent, and done
	    # now instead of as part of the already complex join.
	    #
	    # ... AND P.pid IN (SELECT B.sid
	    #                   FROM branch B
	    #                   WHERE B.root = R.rid)

	    if {![state one {
		SELECT COUNT(*)
		FROM branch B
		WHERE  B.sid  = $pid
		AND    B.root = $rid
	    }]} {
		incr tmax -1
		set  mxs [format $fmt $tmax]
		continue
	    }

	    #
	    # BOTTLE-NECK ...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
	    # join.
	    #
	    # ... AND P.pid IN (SELECT BX.sid
	    #                   FROM branch BX
	    #                   WHERE BX.root = R.rid
	    #                   AND   BX.pos > B.pos)

	    if {![lindex [state run {
		SELECT COUNT(*)
		FROM branch B
		WHERE  B.sid  = $pid
		AND    B.root = $rid
		AND    B.pos  > $pos
	    }] 0]} {
		incr bmax -1
		set  mxs [format $fmt $bmax]
		continue
	    }

	    #
	    # BOTTLE-NECK ...







|





|







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
	    # join.
	    #
	    # ... AND P.pid IN (SELECT BX.sid
	    #                   FROM branch BX
	    #                   WHERE BX.root = R.rid
	    #                   AND   BX.pos > B.pos)

	    if {![state one {
		SELECT COUNT(*)
		FROM branch B
		WHERE  B.sid  = $pid
		AND    B.root = $rid
		AND    B.pos  > $pos
	    }]} {
		incr bmax -1
		set  mxs [format $fmt $bmax]
		continue
	    }

	    #
	    # BOTTLE-NECK ...
496
497
498
499
500
501
502

503
504
505
506
507
508
509

    # # ## ### ##### ######## #############
}

namespace eval ::vc::fossil::import::cvs::pass {
    namespace export filtersym
    namespace eval filtersym {

	namespace import ::vc::fossil::import::cvs::state
	namespace import ::vc::fossil::import::cvs::integrity
	namespace eval project {
	    namespace import ::vc::fossil::import::cvs::project::sym
	}
	namespace import ::vc::tools::misc::nsp
	namespace import ::vc::tools::log







>







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

    # # ## ### ##### ######## #############
}

namespace eval ::vc::fossil::import::cvs::pass {
    namespace export filtersym
    namespace eval filtersym {
	namespace import ::vc::fossil::import::cvs::repository
	namespace import ::vc::fossil::import::cvs::state
	namespace import ::vc::fossil::import::cvs::integrity
	namespace eval project {
	    namespace import ::vc::fossil::import::cvs::project::sym
	}
	namespace import ::vc::tools::misc::nsp
	namespace import ::vc::tools::log
Changes to tools/cvs2fossil/lib/c2f_pinitcsets.tcl.
129
130
131
132
133
134
135


136
137
138
139
140
141
142
	# functionality of the pass.

	state transaction {
	    CreateRevisionChangesets  ; # Group file revisions into csets.
	    BreakInternalDependencies ; # Split the csets based on internal conflicts.
	    CreateSymbolChangesets    ; # Create csets for tags and branches.
	    PersistTheChangesets


	}
	return
    }

    typemethod discard {} {
	# Pass manager interface. Executed for all passes after the
	# run passes, to remove all data of this pass from the state,







>
>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
	# functionality of the pass.

	state transaction {
	    CreateRevisionChangesets  ; # Group file revisions into csets.
	    BreakInternalDependencies ; # Split the csets based on internal conflicts.
	    CreateSymbolChangesets    ; # Create csets for tags and branches.
	    PersistTheChangesets

	    repository printcsetstatistics
	}
	return
    }

    typemethod discard {} {
	# Pass manager interface. Executed for all passes after the
	# run passes, to remove all data of this pass from the state,
Changes to tools/cvs2fossil/lib/c2f_prev.tcl.
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
		# Split the range and schedule the resulting fragments
		# for further inspection. Remember the number of
		# dependencies cut before we remove them from
		# consideration, for documentation later.

		set breaks($best) $cross($best)

		log write 6 csets "Best break @ $best, cuts [nsp $cross($best) dependency dependencies]"

		# Note: The value of best is an abolute location in
		# myrevisions. Use the start of current to make it an
		# index absolute to current.

		set brel [expr {$best - [lindex $current 0]}]
		set bnext $brel ; incr bnext







|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
		# Split the range and schedule the resulting fragments
		# for further inspection. Remember the number of
		# dependencies cut before we remove them from
		# consideration, for documentation later.

		set breaks($best) $cross($best)

		log write 6 csets "Best break @ $best, cutting [nsp $cross($best) dependency dependencies]"

		# Note: The value of best is an abolute location in
		# myrevisions. Use the start of current to make it an
		# index absolute to current.

		set brel [expr {$best - [lindex $current 0]}]
		set bnext $brel ; incr bnext
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
	    SELECT tid, name FROM cstype;
	}] { set mycstype($name) $tid }
	return
    }

    typemethod loadcounter {} {
	# Initialize the counter from the state
	set mycounter [lindex [state run {
	    SELECT MAX(cid) FROM changeset
	}] 0]
	return
    }

    proc PullInternalSuccessorRevisions {dv revisions} {
	upvar 1 $dv dependencies
	set theset ('[join $revisions {','}]')








<
|
<







284
285
286
287
288
289
290

291

292
293
294
295
296
297
298
	    SELECT tid, name FROM cstype;
	}] { set mycstype($name) $tid }
	return
    }

    typemethod loadcounter {} {
	# Initialize the counter from the state

	set mycounter [state one { SELECT MAX(cid) FROM changeset }]

	return
    }

    proc PullInternalSuccessorRevisions {dv revisions} {
	upvar 1 $dv dependencies
	set theset ('[join $revisions {','}]')

Changes to tools/cvs2fossil/lib/c2f_repository.tcl.
87
88
89
90
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
    }

    # pass I results
    typemethod printstatistics {} {
	set prlist [TheProjects]
	set npr [llength $prlist]

	log write 2 repository "Scanned [nsp $npr project]"

	if {$npr > 1} {
	    set  bmax [max [struct::list map $prlist [myproc .BaseLength]]]
	    incr bmax 2
	    set  bfmt %-${bmax}s

	    set  nmax [max [struct::list map $prlist [myproc .NFileLength]]]
	    set  nfmt %${nmax}s
	} else {
	    set bfmt %s
	    set nfmt %s
	}

	set keep {}
	foreach p $prlist {
	    set nfiles [llength [$p filenames]]
	    set line "Project [format $bfmt \"[$p printbase]\"] : [format $nfmt $nfiles] [sp $nfiles file]"
	    if {$nfiles < 1} {
		append line ", dropped"
	    } else {
		lappend keep $p
	    }
	    log write 2 repository $line
	}







|
















|







87
88
89
90
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
    }

    # pass I results
    typemethod printstatistics {} {
	set prlist [TheProjects]
	set npr [llength $prlist]

	log write 2 repository "Statistics: Scanned [nsp $npr project]"

	if {$npr > 1} {
	    set  bmax [max [struct::list map $prlist [myproc .BaseLength]]]
	    incr bmax 2
	    set  bfmt %-${bmax}s

	    set  nmax [max [struct::list map $prlist [myproc .NFileLength]]]
	    set  nfmt %${nmax}s
	} else {
	    set bfmt %s
	    set nfmt %s
	}

	set keep {}
	foreach p $prlist {
	    set nfiles [llength [$p filenames]]
	    set line "Statistics: Project [format $bfmt \"[$p printbase]\"] : [format $nfmt $nfiles] [sp $nfiles file]"
	    if {$nfiles < 1} {
		append line ", dropped"
	    } else {
		lappend keep $p
	    }
	    log write 2 repository $line
	}
162
163
164
165
166
167
168
169
170















































171
172
173
174
175
176
177
	    }
	}
	return
    }

    # pass II results
    typemethod printrevstatistics {} {
	log write 2 repository "Scanned ..."
	# number of revisions, symbols, repository wide, per project ...















































	return
    }

    # pass II persistence
    typemethod persistrev {} {
	state transaction {
	    SaveAuthors







|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
	    }
	}
	return
    }

    # pass II results
    typemethod printrevstatistics {} {
	log write 2 repository "Revision statistics"
	# number of revisions, symbols, repository wide, and per project ...

	set rcount [state one { SELECT COUNT (*) FROM revision }]
	set tcount [state one { SELECT COUNT (*) FROM tag      }]
	set bcount [state one { SELECT COUNT (*) FROM branch   }]
	set scount [state one { SELECT COUNT (*) FROM symbol   }]
	set acount [state one { SELECT COUNT (*) FROM author   }]
	set ccount [state one { SELECT COUNT (*) FROM cmessage }]
	set fmt %[string length [max [list $rcount $tcount $bcount $scount $acount $ccount]]]s

	log write 2 repository "Statistics: [format $fmt $rcount] [sp $rcount revision]"
	log write 2 repository "Statistics: [format $fmt $tcount] [sp $tcount tag]"
	log write 2 repository "Statistics: [format $fmt $bcount] [sp $bcount branch branches]"
	log write 2 repository "Statistics: [format $fmt $scount] [sp $scount symbol]"
	log write 2 repository "Statistics: [format $fmt $acount] [sp $acount author]"
	log write 2 repository "Statistics: [format $fmt $ccount] [sp $ccount {log message}]"

	set prlist [TheProjects]
	set npr [llength $prlist]

	if {$npr > 1} {
	    set  bmax [max [struct::list map $prlist [myproc .BaseLength]]]
	    incr bmax 2
	    set  bfmt %-${bmax}s
	} else {
	    set bfmt %s
	}

	foreach p $prlist {
	    set pid [$p id]
	    set prefix "Statistics: Project [format $bfmt \"[$p printbase]\"]"
	    regsub -all {[^	]} $prefix { } blanks
	    set sep " : "

	    set rcount [state one { SELECT COUNT (*) FROM revision R, file F WHERE R.fid = F.fid AND F.pid = $pid }]
	    set tcount [state one { SELECT COUNT (*) FROM tag T,      file F WHERE T.fid = F.fid AND F.pid = $pid }]
	    set bcount [state one { SELECT COUNT (*) FROM branch B,   file F WHERE B.fid = F.fid AND F.pid = $pid }]
	    set scount [state one { SELECT COUNT (*) FROM symbol             WHERE pid = $pid                     }]
	    set acount [state one { SELECT COUNT (*) FROM author   WHERE aid IN (SELECT DISTINCT aid FROM meta WHERE pid = $pid) }]
	    set ccount [state one { SELECT COUNT (*) FROM cmessage WHERE cid IN (SELECT DISTINCT cid FROM meta WHERE pid = $pid) }]

	    log write 2 repository "$prefix$sep[format $fmt $rcount] [sp $rcount revision]"
	    log write 2 repository "$blanks$sep[format $fmt $tcount] [sp $tcount tag]"
	    log write 2 repository "$blanks$sep[format $fmt $bcount] [sp $bcount branch branches]"
	    log write 2 repository "$blanks$sep[format $fmt $scount] [sp $scount symbol]"
	    log write 2 repository "$blanks$sep[format $fmt $acount] [sp $acount author]"
	    log write 2 repository "$blanks$sep[format $fmt $ccount] [sp $ccount {log message}]"
	}
	return
    }

    # pass II persistence
    typemethod persistrev {} {
	state transaction {
	    SaveAuthors
224
225
226
227
228
229
230











































231
232
233
234
235
236
237
	return
    }

    typemethod projectof {pid} {
	return $myprojmap($pid)
    }












































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

    typevariable mybase           {} ; # Base path to CVS repository.
    typevariable myprojpaths      {} ; # List of paths to all declared
				       # projects, relative to mybase.
    typevariable myprojects       {} ; # List of objects for all







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







271
272
273
274
275
276
277
278
279
280
281
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
315
316
317
318
319
320
321
322
323
324
325
326
327
	return
    }

    typemethod projectof {pid} {
	return $myprojmap($pid)
    }


    # pass IV+ results
    typemethod printcsetstatistics {} {
	log write 2 repository "Changeset statistics"
	# number of revisions, symbols, repository wide, and per project ...

	set ccount [state one { SELECT COUNT (*) FROM changeset                }]
	set rcount [state one { SELECT COUNT (*) FROM changeset WHERE type = 0 }]
	set scount [state one { SELECT COUNT (*) FROM changeset WHERE type = 1 }]
	set fmt %[string length [max [list $ccount $rcount $scount]]]s

	log write 2 repository "Statistics: [format $fmt $ccount] [sp $ccount changeset]"
	log write 2 repository "Statistics: [format $fmt $rcount] [sp $rcount {revision changeset}]"
	log write 2 repository "Statistics: [format $fmt $scount] [sp $scount {symbol changeset}]"

	set prlist [TheProjects]
	set npr [llength $prlist]

	if {$npr > 1} {
	    set  bmax [max [struct::list map $prlist [myproc .BaseLength]]]
	    incr bmax 2
	    set  bfmt %-${bmax}s
	} else {
	    set bfmt %s
	}

	foreach p $prlist {
	    set pid [$p id]
	    set prefix "Statistics: Project [format $bfmt \"[$p printbase]\"]"
	    regsub -all {[^	]} $prefix { } blanks
	    set sep " : "

	    set ccount [state one { SELECT COUNT (*) FROM changeset WHERE pid = $pid              }]
	    set rcount [state one { SELECT COUNT (*) FROM changeset WHERE pid = $pid AND type = 0 }]
	    set scount [state one { SELECT COUNT (*) FROM changeset WHERE pid = $pid AND type = 1 }]

	    log write 2 repository "$prefix$sep[format $fmt $ccount] [sp $ccount changeset]"
	    log write 2 repository "$blanks$sep[format $fmt $rcount] [sp $rcount {revision changeset}]"
	    log write 2 repository "$blanks$sep[format $fmt $scount] [sp $scount {symbol changeset}]"
	}
	return
    }

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

    typevariable mybase           {} ; # Base path to CVS repository.
    typevariable myprojpaths      {} ; # List of paths to all declared
				       # projects, relative to mybase.
    typevariable myprojects       {} ; # List of objects for all
Changes to tools/cvs2fossil/lib/c2f_state.tcl.
142
143
144
145
146
147
148




149
150
151
152
153
154
155
	}
	return
    }

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





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

    typemethod id {} {
	return [$mystate last_insert_rowid]







>
>
>
>







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
	}
	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]