Check-in [3945057916]
Not logged in
Overview

SHA1 Hash:394505791628e571d7020d6cdd85235ec847f49d
Date: 2007-08-01 21:03:03
User: drh
Comment:Add primitive start-time and duration controols to the timeline. Additional checksums on check-in and check-out.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/checkin.c from [5e2184d9ad] to [bb35848e0a].

@@ -227,10 +227,11 @@
   char *zUuid, *zDate;
   char *zManifestFile;   /* Name of the manifest file */
   Blob manifest;
   Blob mcksum;           /* Self-checksum on the manifest */
   Blob cksum1, cksum2;   /* Before and after commit checksums */
+  Blob cksum1b;          /* Checksum recorded in the manifest */
 
   db_must_be_within_tree();
   user_select();
   db_begin_transaction();
   rc = unsaved_changes();
@@ -322,17 +323,22 @@
   /* Verify that the tree checksum is unchanged */
   vfile_aggregate_checksum_repository(nvid, &cksum2);
   if( blob_compare(&cksum1, &cksum2) ){
     fossil_panic("tree checksum does not match repository after commit");
   }
-  vfile_aggregate_checksum_manifest(nvid, &cksum2);
+  vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
+  if( blob_compare(&cksum1, &cksum1b) ){
+    fossil_panic("manifest checksum does not agree with manifest: "
+                 "%b versus %b", &cksum1, &cksum1b);
+  }
   if( blob_compare(&cksum1, &cksum2) ){
-    fossil_panic("tree checksum does not match manifest after commit");
+    fossil_panic("tree checksum does not match manifest after commit: "
+                 "%b versus %b", &cksum1, &cksum2);
   }
   vfile_aggregate_checksum_disk(nvid, &cksum2);
   if( blob_compare(&cksum1, &cksum2) ){
     fossil_panic("tree checksums before and after commit do not match");
   }
 
   /* Commit */
   db_end_transaction(0);
 }

Modified src/checkout.c from [6397d9f546] to [6ea05f6640].

@@ -99,10 +99,11 @@
 */
 void checkout_cmd(void){
   int forceFlag;
   int noWrite;
   int vid, prior;
+  Blob cksum1, cksum1b, cksum2;
 
   db_must_be_within_tree();
   db_begin_transaction();
   forceFlag = find_option("force","f",0)!=0;
   noWrite = find_option("dontwrite",0,0)!=0;
@@ -134,7 +135,15 @@
     blob_write_to_file(&manifest, zManFile);
     free(zManFile);
     db_lset_int("checkout", vid);
   }
   db_multi_exec("DELETE FROM vmerge");
+  vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
+  vfile_aggregate_checksum_disk(vid, &cksum2);
+  if( blob_compare(&cksum1, &cksum2) ){
+    printf("WARNING: manifest checksum does not agree with disk\n");
+  }
+  if( blob_compare(&cksum1, &cksum1b) ){
+    printf("WARNING: manifest checksum does not agree with manifest\n");
+  }
   db_end_transaction(0);
 }

Modified src/descendents.c from [ccfb04b45c] to [caa863826b].

@@ -140,9 +140,9 @@
     " WHERE blob.rid IN"
     "       (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
     "   AND event.objid=blob.rid"
     " ORDER BY event.mtime DESC"
   );
-  www_print_timeline(&q);
+  www_print_timeline(&q, 0);
   db_finalize(&q);
   style_footer();
 }

Modified src/timeline.c from [346b9fb48c] to [c9c7c2c04a].

@@ -60,11 +60,11 @@
 **    0.  UUID
 **    1.  Date/Time
 **    2.  Comment string
 **    3.  User
 */
-void www_print_timeline(Stmt *pQuery){
+void www_print_timeline(Stmt *pQuery, char *zLastDate){
   char zPrevDate[20];
   zPrevDate[0] = 0;
   @ <table cellspacing=0 border=0 cellpadding=0>
   while( db_step(pQuery)==SQLITE_ROW ){
     const char *zDate = db_column_text(pQuery, 1);
@@ -82,10 +82,13 @@
     @ <tr><td valign="top">%s(&zDate[11])</td>
     @ <td width="20"></td>
     @ <td valign="top" align="left">
     hyperlink_to_uuid(db_column_text(pQuery,0));
     @ %h(db_column_text(pQuery,2)) (by %h(db_column_text(pQuery,3)))</td>
+    if( zLastDate ){
+      strcpy(zLastDate, zDate);
+    }
   }
   @ </table>
 }
 
 
@@ -93,27 +96,64 @@
 /*
 ** WEBPAGE: timeline
 */
 void page_timeline(void){
   Stmt q;
+  char *zSQL;
+  char zDate[100];
+  const char *zStart = P("d");
+  int nEntry = atoi(PD("n","25"));
 
   /* To view the timeline, must have permission to read project data.
   */
   login_check_credentials();
   if( !g.okRead ){ login_needed(); return; }
 
   style_header("Timeline");
-  db_prepare(&q,
+  if( !g.okHistory &&
+      db_exists("SELECT 1 FROM user"
+                " WHERE login='anonymous'"
+                "   AND cap LIKE '%%h%%'") ){
+    @ <p><b>Note:</b> You will be able to see much more timeline
+    @ information if <a href="%s(g.zBaseURL)/login">login</a>.</p>
+  }
+  zSQL = mprintf(
     "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
     "  FROM event, blob"
     " WHERE event.type='ci' AND blob.rid=event.objid"
-    " ORDER BY event.mtime DESC"
   );
-  www_print_timeline(&q);
+  if( zStart ){
+    while( isspace(zStart[0]) ){ zStart++; }
+    if( zStart[0] ){
+      zSQL = mprintf("%z AND event.mtime<=julianday(%Q, 'localtime')",
+                      zSQL, zStart);
+    }
+  }
+  zSQL = mprintf("%z ORDER BY event.mtime DESC LIMIT %d", zSQL, nEntry);
+  db_prepare(&q, zSQL);
+  free(zSQL);
+  www_print_timeline(&q, zDate);
   db_finalize(&q);
+  if( zStart==0 ){
+    zStart = zDate;
+  }
+  @ <hr>
+  @ <form method="GET" action="%s(g.zBaseURL)/timeline">
+  @ Start Date:
+  @ <input type="text" size="30" value="%h(zStart)" name="d">
+  @ Number Of Entries:
+  @ <input type="text" size="4" value="%d(nEntry)" name="n">
+  @ <br><input type="submit" value="Submit">
+  @ </form>
+  @ <form method="GET" action="%s(g.zBaseURL)/timeline">
+  @ <input type="hidden" value="%h(zDate)" name="d">
+  @ <input type="hidden" value="%d(nEntry)" name="n">
+  @ <input type="submit" value="Next %d(nEntry) Rows">
+  @ </form>
   style_footer();
 }
+
 /*
 ** The input query q selects various records.  Print a human-readable
 ** summary of those records.
 **
 ** Limit the number of entries printed to nLine.

Modified src/vfile.c from [d4b9c4a1e5] to [8f052c3289].

@@ -330,11 +330,11 @@
 ** Compute an aggregate MD5 checksum over the repository image of every
 ** file in manifest vid.  The file names are part of the checksum.
 **
 ** Return the resulting checksum in blob pOut.
 */
-void vfile_aggregate_checksum_manifest(int vid, Blob *pOut){
+void vfile_aggregate_checksum_manifest(int vid, Blob *pOut, Blob *pManOut){
   int i, fid;
   Blob file, mfile;
   Manifest m;
   char zBuf[100];
 
@@ -351,26 +351,31 @@
     sprintf(zBuf, " %d\n", blob_size(&file));
     md5sum_step_text(zBuf, -1);
     md5sum_step_blob(&file);
     blob_reset(&file);
   }
+  if( pManOut ){
+    blob_zero(pManOut);
+    blob_append(pManOut, m.zRepoCksum, -1);
+  }
   manifest_clear(&m);
   md5sum_finish(pOut);
 }
 
 /*
 ** COMMAND: test-agg-cksum
 */
 void test_agg_cksum_cmd(void){
   int vid;
-  Blob hash;
+  Blob hash, hash2;
   db_must_be_within_tree();
   vid = db_lget_int("checkout", 0);
   vfile_aggregate_checksum_disk(vid, &hash);
   printf("disk:     %s\n", blob_str(&hash));
   blob_reset(&hash);
   vfile_aggregate_checksum_repository(vid, &hash);
   printf("archive:  %s\n", blob_str(&hash));
   blob_reset(&hash);
-  vfile_aggregate_checksum_manifest(vid, &hash);
+  vfile_aggregate_checksum_manifest(vid, &hash, &hash2);
   printf("manifest: %s\n", blob_str(&hash));
+  printf("recorded: %s\n", blob_str(&hash2));
 }