Fossil SCM

Add primitive start-time and duration controols to the timeline. Additional checksums on check-in and check-out.

drh 2007-08-01 21:03 trunk
Commit 394505791628e571d7020d6cdd85235ec847f49d
+8 -2
--- src/checkin.c
+++ src/checkin.c
@@ -227,10 +227,11 @@
227227
char *zUuid, *zDate;
228228
char *zManifestFile; /* Name of the manifest file */
229229
Blob manifest;
230230
Blob mcksum; /* Self-checksum on the manifest */
231231
Blob cksum1, cksum2; /* Before and after commit checksums */
232
+ Blob cksum1b; /* Checksum recorded in the manifest */
232233
233234
db_must_be_within_tree();
234235
user_select();
235236
db_begin_transaction();
236237
rc = unsaved_changes();
@@ -322,17 +323,22 @@
322323
/* Verify that the tree checksum is unchanged */
323324
vfile_aggregate_checksum_repository(nvid, &cksum2);
324325
if( blob_compare(&cksum1, &cksum2) ){
325326
fossil_panic("tree checksum does not match repository after commit");
326327
}
327
- vfile_aggregate_checksum_manifest(nvid, &cksum2);
328
+ vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
329
+ if( blob_compare(&cksum1, &cksum1b) ){
330
+ fossil_panic("manifest checksum does not agree with manifest: "
331
+ "%b versus %b", &cksum1, &cksum1b);
332
+ }
328333
if( blob_compare(&cksum1, &cksum2) ){
329
- fossil_panic("tree checksum does not match manifest after commit");
334
+ fossil_panic("tree checksum does not match manifest after commit: "
335
+ "%b versus %b", &cksum1, &cksum2);
330336
}
331337
vfile_aggregate_checksum_disk(nvid, &cksum2);
332338
if( blob_compare(&cksum1, &cksum2) ){
333339
fossil_panic("tree checksums before and after commit do not match");
334340
}
335341
336342
/* Commit */
337343
db_end_transaction(0);
338344
}
339345
--- src/checkin.c
+++ src/checkin.c
@@ -227,10 +227,11 @@
227 char *zUuid, *zDate;
228 char *zManifestFile; /* Name of the manifest file */
229 Blob manifest;
230 Blob mcksum; /* Self-checksum on the manifest */
231 Blob cksum1, cksum2; /* Before and after commit checksums */
 
232
233 db_must_be_within_tree();
234 user_select();
235 db_begin_transaction();
236 rc = unsaved_changes();
@@ -322,17 +323,22 @@
322 /* Verify that the tree checksum is unchanged */
323 vfile_aggregate_checksum_repository(nvid, &cksum2);
324 if( blob_compare(&cksum1, &cksum2) ){
325 fossil_panic("tree checksum does not match repository after commit");
326 }
327 vfile_aggregate_checksum_manifest(nvid, &cksum2);
 
 
 
 
328 if( blob_compare(&cksum1, &cksum2) ){
329 fossil_panic("tree checksum does not match manifest after commit");
 
330 }
331 vfile_aggregate_checksum_disk(nvid, &cksum2);
332 if( blob_compare(&cksum1, &cksum2) ){
333 fossil_panic("tree checksums before and after commit do not match");
334 }
335
336 /* Commit */
337 db_end_transaction(0);
338 }
339
--- src/checkin.c
+++ src/checkin.c
@@ -227,10 +227,11 @@
227 char *zUuid, *zDate;
228 char *zManifestFile; /* Name of the manifest file */
229 Blob manifest;
230 Blob mcksum; /* Self-checksum on the manifest */
231 Blob cksum1, cksum2; /* Before and after commit checksums */
232 Blob cksum1b; /* Checksum recorded in the manifest */
233
234 db_must_be_within_tree();
235 user_select();
236 db_begin_transaction();
237 rc = unsaved_changes();
@@ -322,17 +323,22 @@
323 /* Verify that the tree checksum is unchanged */
324 vfile_aggregate_checksum_repository(nvid, &cksum2);
325 if( blob_compare(&cksum1, &cksum2) ){
326 fossil_panic("tree checksum does not match repository after commit");
327 }
328 vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
329 if( blob_compare(&cksum1, &cksum1b) ){
330 fossil_panic("manifest checksum does not agree with manifest: "
331 "%b versus %b", &cksum1, &cksum1b);
332 }
333 if( blob_compare(&cksum1, &cksum2) ){
334 fossil_panic("tree checksum does not match manifest after commit: "
335 "%b versus %b", &cksum1, &cksum2);
336 }
337 vfile_aggregate_checksum_disk(nvid, &cksum2);
338 if( blob_compare(&cksum1, &cksum2) ){
339 fossil_panic("tree checksums before and after commit do not match");
340 }
341
342 /* Commit */
343 db_end_transaction(0);
344 }
345
--- src/checkout.c
+++ src/checkout.c
@@ -99,10 +99,11 @@
9999
*/
100100
void checkout_cmd(void){
101101
int forceFlag;
102102
int noWrite;
103103
int vid, prior;
104
+ Blob cksum1, cksum1b, cksum2;
104105
105106
db_must_be_within_tree();
106107
db_begin_transaction();
107108
forceFlag = find_option("force","f",0)!=0;
108109
noWrite = find_option("dontwrite",0,0)!=0;
@@ -134,7 +135,15 @@
134135
blob_write_to_file(&manifest, zManFile);
135136
free(zManFile);
136137
db_lset_int("checkout", vid);
137138
}
138139
db_multi_exec("DELETE FROM vmerge");
140
+ vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
141
+ vfile_aggregate_checksum_disk(vid, &cksum2);
142
+ if( blob_compare(&cksum1, &cksum2) ){
143
+ printf("WARNING: manifest checksum does not agree with disk\n");
144
+ }
145
+ if( blob_compare(&cksum1, &cksum1b) ){
146
+ printf("WARNING: manifest checksum does not agree with manifest\n");
147
+ }
139148
db_end_transaction(0);
140149
}
141150
--- src/checkout.c
+++ src/checkout.c
@@ -99,10 +99,11 @@
99 */
100 void checkout_cmd(void){
101 int forceFlag;
102 int noWrite;
103 int vid, prior;
 
104
105 db_must_be_within_tree();
106 db_begin_transaction();
107 forceFlag = find_option("force","f",0)!=0;
108 noWrite = find_option("dontwrite",0,0)!=0;
@@ -134,7 +135,15 @@
134 blob_write_to_file(&manifest, zManFile);
135 free(zManFile);
136 db_lset_int("checkout", vid);
137 }
138 db_multi_exec("DELETE FROM vmerge");
 
 
 
 
 
 
 
 
139 db_end_transaction(0);
140 }
141
--- src/checkout.c
+++ src/checkout.c
@@ -99,10 +99,11 @@
99 */
100 void checkout_cmd(void){
101 int forceFlag;
102 int noWrite;
103 int vid, prior;
104 Blob cksum1, cksum1b, cksum2;
105
106 db_must_be_within_tree();
107 db_begin_transaction();
108 forceFlag = find_option("force","f",0)!=0;
109 noWrite = find_option("dontwrite",0,0)!=0;
@@ -134,7 +135,15 @@
135 blob_write_to_file(&manifest, zManFile);
136 free(zManFile);
137 db_lset_int("checkout", vid);
138 }
139 db_multi_exec("DELETE FROM vmerge");
140 vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
141 vfile_aggregate_checksum_disk(vid, &cksum2);
142 if( blob_compare(&cksum1, &cksum2) ){
143 printf("WARNING: manifest checksum does not agree with disk\n");
144 }
145 if( blob_compare(&cksum1, &cksum1b) ){
146 printf("WARNING: manifest checksum does not agree with manifest\n");
147 }
148 db_end_transaction(0);
149 }
150
--- src/descendents.c
+++ src/descendents.c
@@ -140,9 +140,9 @@
140140
" WHERE blob.rid IN"
141141
" (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
142142
" AND event.objid=blob.rid"
143143
" ORDER BY event.mtime DESC"
144144
);
145
- www_print_timeline(&q);
145
+ www_print_timeline(&q, 0);
146146
db_finalize(&q);
147147
style_footer();
148148
}
149149
--- src/descendents.c
+++ src/descendents.c
@@ -140,9 +140,9 @@
140 " WHERE blob.rid IN"
141 " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
142 " AND event.objid=blob.rid"
143 " ORDER BY event.mtime DESC"
144 );
145 www_print_timeline(&q);
146 db_finalize(&q);
147 style_footer();
148 }
149
--- src/descendents.c
+++ src/descendents.c
@@ -140,9 +140,9 @@
140 " WHERE blob.rid IN"
141 " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
142 " AND event.objid=blob.rid"
143 " ORDER BY event.mtime DESC"
144 );
145 www_print_timeline(&q, 0);
146 db_finalize(&q);
147 style_footer();
148 }
149
+44 -4
--- src/timeline.c
+++ src/timeline.c
@@ -60,11 +60,11 @@
6060
** 0. UUID
6161
** 1. Date/Time
6262
** 2. Comment string
6363
** 3. User
6464
*/
65
-void www_print_timeline(Stmt *pQuery){
65
+void www_print_timeline(Stmt *pQuery, char *zLastDate){
6666
char zPrevDate[20];
6767
zPrevDate[0] = 0;
6868
@ <table cellspacing=0 border=0 cellpadding=0>
6969
while( db_step(pQuery)==SQLITE_ROW ){
7070
const char *zDate = db_column_text(pQuery, 1);
@@ -82,10 +82,13 @@
8282
@ <tr><td valign="top">%s(&zDate[11])</td>
8383
@ <td width="20"></td>
8484
@ <td valign="top" align="left">
8585
hyperlink_to_uuid(db_column_text(pQuery,0));
8686
@ %h(db_column_text(pQuery,2)) (by %h(db_column_text(pQuery,3)))</td>
87
+ if( zLastDate ){
88
+ strcpy(zLastDate, zDate);
89
+ }
8790
}
8891
@ </table>
8992
}
9093
9194
@@ -93,27 +96,64 @@
9396
/*
9497
** WEBPAGE: timeline
9598
*/
9699
void page_timeline(void){
97100
Stmt q;
101
+ char *zSQL;
102
+ char zDate[100];
103
+ const char *zStart = P("d");
104
+ int nEntry = atoi(PD("n","25"));
98105
99106
/* To view the timeline, must have permission to read project data.
100107
*/
101108
login_check_credentials();
102109
if( !g.okRead ){ login_needed(); return; }
103110
104111
style_header("Timeline");
105
- db_prepare(&q,
112
+ if( !g.okHistory &&
113
+ db_exists("SELECT 1 FROM user"
114
+ " WHERE login='anonymous'"
115
+ " AND cap LIKE '%%h%%'") ){
116
+ @ <p><b>Note:</b> You will be able to see much more timeline
117
+ @ information if <a href="%s(g.zBaseURL)/login">login</a>.</p>
118
+ }
119
+ zSQL = mprintf(
106120
"SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
107121
" FROM event, blob"
108122
" WHERE event.type='ci' AND blob.rid=event.objid"
109
- " ORDER BY event.mtime DESC"
110123
);
111
- www_print_timeline(&q);
124
+ if( zStart ){
125
+ while( isspace(zStart[0]) ){ zStart++; }
126
+ if( zStart[0] ){
127
+ zSQL = mprintf("%z AND event.mtime<=julianday(%Q, 'localtime')",
128
+ zSQL, zStart);
129
+ }
130
+ }
131
+ zSQL = mprintf("%z ORDER BY event.mtime DESC LIMIT %d", zSQL, nEntry);
132
+ db_prepare(&q, zSQL);
133
+ free(zSQL);
134
+ www_print_timeline(&q, zDate);
112135
db_finalize(&q);
136
+ if( zStart==0 ){
137
+ zStart = zDate;
138
+ }
139
+ @ <hr>
140
+ @ <form method="GET" action="%s(g.zBaseURL)/timeline">
141
+ @ Start Date:
142
+ @ <input type="text" size="30" value="%h(zStart)" name="d">
143
+ @ Number Of Entries:
144
+ @ <input type="text" size="4" value="%d(nEntry)" name="n">
145
+ @ <br><input type="submit" value="Submit">
146
+ @ </form>
147
+ @ <form method="GET" action="%s(g.zBaseURL)/timeline">
148
+ @ <input type="hidden" value="%h(zDate)" name="d">
149
+ @ <input type="hidden" value="%d(nEntry)" name="n">
150
+ @ <input type="submit" value="Next %d(nEntry) Rows">
151
+ @ </form>
113152
style_footer();
114153
}
154
+
115155
/*
116156
** The input query q selects various records. Print a human-readable
117157
** summary of those records.
118158
**
119159
** Limit the number of entries printed to nLine.
120160
--- src/timeline.c
+++ src/timeline.c
@@ -60,11 +60,11 @@
60 ** 0. UUID
61 ** 1. Date/Time
62 ** 2. Comment string
63 ** 3. User
64 */
65 void www_print_timeline(Stmt *pQuery){
66 char zPrevDate[20];
67 zPrevDate[0] = 0;
68 @ <table cellspacing=0 border=0 cellpadding=0>
69 while( db_step(pQuery)==SQLITE_ROW ){
70 const char *zDate = db_column_text(pQuery, 1);
@@ -82,10 +82,13 @@
82 @ <tr><td valign="top">%s(&zDate[11])</td>
83 @ <td width="20"></td>
84 @ <td valign="top" align="left">
85 hyperlink_to_uuid(db_column_text(pQuery,0));
86 @ %h(db_column_text(pQuery,2)) (by %h(db_column_text(pQuery,3)))</td>
 
 
 
87 }
88 @ </table>
89 }
90
91
@@ -93,27 +96,64 @@
93 /*
94 ** WEBPAGE: timeline
95 */
96 void page_timeline(void){
97 Stmt q;
 
 
 
 
98
99 /* To view the timeline, must have permission to read project data.
100 */
101 login_check_credentials();
102 if( !g.okRead ){ login_needed(); return; }
103
104 style_header("Timeline");
105 db_prepare(&q,
 
 
 
 
 
 
 
106 "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
107 " FROM event, blob"
108 " WHERE event.type='ci' AND blob.rid=event.objid"
109 " ORDER BY event.mtime DESC"
110 );
111 www_print_timeline(&q);
 
 
 
 
 
 
 
 
 
 
112 db_finalize(&q);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113 style_footer();
114 }
 
115 /*
116 ** The input query q selects various records. Print a human-readable
117 ** summary of those records.
118 **
119 ** Limit the number of entries printed to nLine.
120
--- src/timeline.c
+++ src/timeline.c
@@ -60,11 +60,11 @@
60 ** 0. UUID
61 ** 1. Date/Time
62 ** 2. Comment string
63 ** 3. User
64 */
65 void www_print_timeline(Stmt *pQuery, char *zLastDate){
66 char zPrevDate[20];
67 zPrevDate[0] = 0;
68 @ <table cellspacing=0 border=0 cellpadding=0>
69 while( db_step(pQuery)==SQLITE_ROW ){
70 const char *zDate = db_column_text(pQuery, 1);
@@ -82,10 +82,13 @@
82 @ <tr><td valign="top">%s(&zDate[11])</td>
83 @ <td width="20"></td>
84 @ <td valign="top" align="left">
85 hyperlink_to_uuid(db_column_text(pQuery,0));
86 @ %h(db_column_text(pQuery,2)) (by %h(db_column_text(pQuery,3)))</td>
87 if( zLastDate ){
88 strcpy(zLastDate, zDate);
89 }
90 }
91 @ </table>
92 }
93
94
@@ -93,27 +96,64 @@
96 /*
97 ** WEBPAGE: timeline
98 */
99 void page_timeline(void){
100 Stmt q;
101 char *zSQL;
102 char zDate[100];
103 const char *zStart = P("d");
104 int nEntry = atoi(PD("n","25"));
105
106 /* To view the timeline, must have permission to read project data.
107 */
108 login_check_credentials();
109 if( !g.okRead ){ login_needed(); return; }
110
111 style_header("Timeline");
112 if( !g.okHistory &&
113 db_exists("SELECT 1 FROM user"
114 " WHERE login='anonymous'"
115 " AND cap LIKE '%%h%%'") ){
116 @ <p><b>Note:</b> You will be able to see much more timeline
117 @ information if <a href="%s(g.zBaseURL)/login">login</a>.</p>
118 }
119 zSQL = mprintf(
120 "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
121 " FROM event, blob"
122 " WHERE event.type='ci' AND blob.rid=event.objid"
 
123 );
124 if( zStart ){
125 while( isspace(zStart[0]) ){ zStart++; }
126 if( zStart[0] ){
127 zSQL = mprintf("%z AND event.mtime<=julianday(%Q, 'localtime')",
128 zSQL, zStart);
129 }
130 }
131 zSQL = mprintf("%z ORDER BY event.mtime DESC LIMIT %d", zSQL, nEntry);
132 db_prepare(&q, zSQL);
133 free(zSQL);
134 www_print_timeline(&q, zDate);
135 db_finalize(&q);
136 if( zStart==0 ){
137 zStart = zDate;
138 }
139 @ <hr>
140 @ <form method="GET" action="%s(g.zBaseURL)/timeline">
141 @ Start Date:
142 @ <input type="text" size="30" value="%h(zStart)" name="d">
143 @ Number Of Entries:
144 @ <input type="text" size="4" value="%d(nEntry)" name="n">
145 @ <br><input type="submit" value="Submit">
146 @ </form>
147 @ <form method="GET" action="%s(g.zBaseURL)/timeline">
148 @ <input type="hidden" value="%h(zDate)" name="d">
149 @ <input type="hidden" value="%d(nEntry)" name="n">
150 @ <input type="submit" value="Next %d(nEntry) Rows">
151 @ </form>
152 style_footer();
153 }
154
155 /*
156 ** The input query q selects various records. Print a human-readable
157 ** summary of those records.
158 **
159 ** Limit the number of entries printed to nLine.
160
+8 -3
--- src/vfile.c
+++ src/vfile.c
@@ -330,11 +330,11 @@
330330
** Compute an aggregate MD5 checksum over the repository image of every
331331
** file in manifest vid. The file names are part of the checksum.
332332
**
333333
** Return the resulting checksum in blob pOut.
334334
*/
335
-void vfile_aggregate_checksum_manifest(int vid, Blob *pOut){
335
+void vfile_aggregate_checksum_manifest(int vid, Blob *pOut, Blob *pManOut){
336336
int i, fid;
337337
Blob file, mfile;
338338
Manifest m;
339339
char zBuf[100];
340340
@@ -351,26 +351,31 @@
351351
sprintf(zBuf, " %d\n", blob_size(&file));
352352
md5sum_step_text(zBuf, -1);
353353
md5sum_step_blob(&file);
354354
blob_reset(&file);
355355
}
356
+ if( pManOut ){
357
+ blob_zero(pManOut);
358
+ blob_append(pManOut, m.zRepoCksum, -1);
359
+ }
356360
manifest_clear(&m);
357361
md5sum_finish(pOut);
358362
}
359363
360364
/*
361365
** COMMAND: test-agg-cksum
362366
*/
363367
void test_agg_cksum_cmd(void){
364368
int vid;
365
- Blob hash;
369
+ Blob hash, hash2;
366370
db_must_be_within_tree();
367371
vid = db_lget_int("checkout", 0);
368372
vfile_aggregate_checksum_disk(vid, &hash);
369373
printf("disk: %s\n", blob_str(&hash));
370374
blob_reset(&hash);
371375
vfile_aggregate_checksum_repository(vid, &hash);
372376
printf("archive: %s\n", blob_str(&hash));
373377
blob_reset(&hash);
374
- vfile_aggregate_checksum_manifest(vid, &hash);
378
+ vfile_aggregate_checksum_manifest(vid, &hash, &hash2);
375379
printf("manifest: %s\n", blob_str(&hash));
380
+ printf("recorded: %s\n", blob_str(&hash2));
376381
}
377382
--- src/vfile.c
+++ src/vfile.c
@@ -330,11 +330,11 @@
330 ** Compute an aggregate MD5 checksum over the repository image of every
331 ** file in manifest vid. The file names are part of the checksum.
332 **
333 ** Return the resulting checksum in blob pOut.
334 */
335 void vfile_aggregate_checksum_manifest(int vid, Blob *pOut){
336 int i, fid;
337 Blob file, mfile;
338 Manifest m;
339 char zBuf[100];
340
@@ -351,26 +351,31 @@
351 sprintf(zBuf, " %d\n", blob_size(&file));
352 md5sum_step_text(zBuf, -1);
353 md5sum_step_blob(&file);
354 blob_reset(&file);
355 }
 
 
 
 
356 manifest_clear(&m);
357 md5sum_finish(pOut);
358 }
359
360 /*
361 ** COMMAND: test-agg-cksum
362 */
363 void test_agg_cksum_cmd(void){
364 int vid;
365 Blob hash;
366 db_must_be_within_tree();
367 vid = db_lget_int("checkout", 0);
368 vfile_aggregate_checksum_disk(vid, &hash);
369 printf("disk: %s\n", blob_str(&hash));
370 blob_reset(&hash);
371 vfile_aggregate_checksum_repository(vid, &hash);
372 printf("archive: %s\n", blob_str(&hash));
373 blob_reset(&hash);
374 vfile_aggregate_checksum_manifest(vid, &hash);
375 printf("manifest: %s\n", blob_str(&hash));
 
376 }
377
--- src/vfile.c
+++ src/vfile.c
@@ -330,11 +330,11 @@
330 ** Compute an aggregate MD5 checksum over the repository image of every
331 ** file in manifest vid. The file names are part of the checksum.
332 **
333 ** Return the resulting checksum in blob pOut.
334 */
335 void vfile_aggregate_checksum_manifest(int vid, Blob *pOut, Blob *pManOut){
336 int i, fid;
337 Blob file, mfile;
338 Manifest m;
339 char zBuf[100];
340
@@ -351,26 +351,31 @@
351 sprintf(zBuf, " %d\n", blob_size(&file));
352 md5sum_step_text(zBuf, -1);
353 md5sum_step_blob(&file);
354 blob_reset(&file);
355 }
356 if( pManOut ){
357 blob_zero(pManOut);
358 blob_append(pManOut, m.zRepoCksum, -1);
359 }
360 manifest_clear(&m);
361 md5sum_finish(pOut);
362 }
363
364 /*
365 ** COMMAND: test-agg-cksum
366 */
367 void test_agg_cksum_cmd(void){
368 int vid;
369 Blob hash, hash2;
370 db_must_be_within_tree();
371 vid = db_lget_int("checkout", 0);
372 vfile_aggregate_checksum_disk(vid, &hash);
373 printf("disk: %s\n", blob_str(&hash));
374 blob_reset(&hash);
375 vfile_aggregate_checksum_repository(vid, &hash);
376 printf("archive: %s\n", blob_str(&hash));
377 blob_reset(&hash);
378 vfile_aggregate_checksum_manifest(vid, &hash, &hash2);
379 printf("manifest: %s\n", blob_str(&hash));
380 printf("recorded: %s\n", blob_str(&hash2));
381 }
382

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button