Check-in [b5f4f910b7]
Not logged in
Overview

SHA1 Hash:b5f4f910b72477f3a61b1ea0d65e2059b7f76664
Date: 2009-08-29 16:45:30
User: drh
Comment:Add additional hyperlinking of dates and userids. For a "circa" timeline, show the "circa" point in the timeline listing.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/info.c from [781d76a85f] to [3701ba08d0].

@@ -21,11 +21,11 @@
 **
 *******************************************************************************
 **
 ** This file contains code to implement the "info" command.  The
 ** "info" command gives command-line access to information about
-** the current tree, or a particular artifact or baseline.
+** the current tree, or a particular artifact or check-in.
 */
 #include "config.h"
 #include "info.h"
 #include <assert.h>
 
@@ -145,145 +145,10 @@
     show_common_info(rid, "uuid:", 1);
   }
 }
 
 /*
-** Show information about descendants of a baseline.  Do this recursively
-** to a depth of N.  Return true if descendants are shown and false if not.
-*/
-static int showDescendants(int pid, int depth, const char *zTitle){
-  Stmt q;
-  int cnt = 0;
-  db_prepare(&q,
-    "SELECT plink.cid, blob.uuid, datetime(plink.mtime, 'localtime'),"
-    "       coalesce(event.euser,event.user),"
-    "       coalesce(event.ecomment,event.comment)"
-    "  FROM plink, blob, event"
-    " WHERE plink.pid=%d"
-    "   AND blob.rid=plink.cid"
-    "   AND event.objid=plink.cid"
-    " ORDER BY plink.mtime ASC",
-    pid
-  );
-  while( db_step(&q)==SQLITE_ROW ){
-    int n;
-    int cid = db_column_int(&q, 0);
-    const char *zUuid = db_column_text(&q, 1);
-    const char *zDate = db_column_text(&q, 2);
-    const char *zUser = db_column_text(&q, 3);
-    const char *zCom = db_column_text(&q, 4);
-    cnt++;
-    if( cnt==1 ){
-      if( zTitle ){
-        @ <div class="section">%s(zTitle)</div>
-      }
-      @ <ul>
-    }
-    @ <li>
-    hyperlink_to_uuid(zUuid);
-    @ %w(zCom) (by %s(zUser) on %s(zDate))
-    if( depth ){
-      n = showDescendants(cid, depth-1, 0);
-    }else{
-      n = db_int(0, "SELECT 1 FROM plink WHERE pid=%d", cid);
-    }
-    if( n==0 ){
-      db_multi_exec("DELETE FROM leaves WHERE rid=%d", cid);
-      @ <b>leaf</b>
-    }
-  }
-  db_finalize(&q);
-  if( cnt ){
-    @ </ul>
-  }
-  return cnt;
-}
-
-/*
-** Show information about ancestors of a baseline.  Do this recursively
-** to a depth of N.  Return true if ancestors are shown and false if not.
-*/
-static void showAncestors(int pid, int depth, const char *zTitle){
-  Stmt q;
-  int cnt = 0;
-  db_prepare(&q,
-    "SELECT plink.pid, blob.uuid, datetime(event.mtime, 'localtime'),"
-    "       coalesce(event.euser,event.user),"
-    "       coalesce(event.ecomment,event.comment)"
-    "  FROM plink, blob, event"
-    " WHERE plink.cid=%d"
-    "   AND blob.rid=plink.pid"
-    "   AND event.objid=plink.pid"
-    " ORDER BY event.mtime DESC",
-    pid
-  );
-  while( db_step(&q)==SQLITE_ROW ){
-    int cid = db_column_int(&q, 0);
-    const char *zUuid = db_column_text(&q, 1);
-    const char *zDate = db_column_text(&q, 2);
-    const char *zUser = db_column_text(&q, 3);
-    const char *zCom = db_column_text(&q, 4);
-    cnt++;
-    if( cnt==1 ){
-      if( zTitle ){
-        @ <div class="section">%s(zTitle)</div>
-      }
-      @ <ul>
-    }
-    @ <li>
-    hyperlink_to_uuid(zUuid);
-    @ %w(zCom) (by %s(zUser) on %s(zDate))
-    if( depth ){
-      showAncestors(cid, depth-1, 0);
-    }
-  }
-  db_finalize(&q);
-  if( cnt ){
-    @ </ul>
-  }
-}
-
-
-#if 0 /* NOT USED */
-/*
-** Show information about baselines mentioned in the "leaves" table.
-*/
-static void showLeaves(int rid){
-  Stmt q;
-  int cnt = 0;
-  db_prepare(&q,
-    "SELECT blob.uuid, datetime(event.mtime, 'localtime'),"
-    "       coalesce(event.euser, event.user),"
-    "       coalesce(event.ecomment,event.comment)"
-    "  FROM leaves, blob, event"
-    " WHERE blob.rid=leaves.rid AND blob.rid!=%d"
-    "   AND event.objid=leaves.rid"
-    " ORDER BY event.mtime DESC",
-    rid
-  );
-  while( db_step(&q)==SQLITE_ROW ){
-    const char *zUuid = db_column_text(&q, 0);
-    const char *zDate = db_column_text(&q, 1);
-    const char *zUser = db_column_text(&q, 2);
-    const char *zCom = db_column_text(&q, 3);
-    cnt++;
-    if( cnt==1 ){
-      @ <div class="section">Leaves</div>
-      @ <ul>
-    }
-    @ <li>
-    hyperlink_to_uuid(zUuid);
-    @ %w(zCom) (by %s(zUser) on %s(zDate))
-  }
-  db_finalize(&q);
-  if( cnt ){
-    @ </ul>
-  }
-}
-#endif
-
-/*
 ** Show information about all tags on a given node.
 */
 static void showTags(int rid, const char *zNotGlob){
   Stmt q;
   int cnt = 0;
@@ -329,11 +194,12 @@
         @ by
       }else{
         @ added by
       }
       hyperlink_to_uuid(zSrcUuid);
-      @ on %s(zDate)
+      @ on
+      hyperlink_to_date(zDate,0);
     }
   }
   db_finalize(&q);
   if( cnt ){
     @ </ul>
@@ -390,10 +256,11 @@
     const char *zUuid = db_column_text(&q, 0);
     char *zTitle = mprintf("Check-in [%.10s]", zUuid);
     char *zEUser, *zEComment;
     const char *zUser;
     const char *zComment;
+    const char *zDate;
     style_header(zTitle);
     login_anonymous_available();
     free(zTitle);
     zEUser = db_text(0,
                    "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
@@ -401,23 +268,28 @@
     zEComment = db_text(0,
                    "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                    TAG_COMMENT, rid);
     zUser = db_column_text(&q, 2);
     zComment = db_column_text(&q, 3);
+    zDate = db_column_text(&q,1);
     @ <div class="section">Overview</div>
     @ <p><table class="label-value">
     @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
     if( g.okSetup ){
       @ (Record ID: %d(rid))
     }
     @ </td></tr>
-    @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr>
+    @ <tr><th>Date:</th><td>
+    hyperlink_to_date(zDate, "</td></tr>");
     if( zEUser ){
-      @ <tr><th>Edited&nbsp;User:</td><td>%h(zEUser)</td></tr>
-      @ <tr><th>Original&nbsp;User:</th><td>%h(zUser)</td></tr>
-    }else{
-      @ <tr><th>User:</td><td>%h(zUser)</td></tr>
+      @ <tr><th>Edited&nbsp;User:</td><td>
+      hyperlink_to_user(zEUser,zDate,"</td></tr>");
+      @ <tr><th>Original&nbsp;User:</th><td>
+      hyperlink_to_user(zUser,zDate,"</td></tr>");
+    }else{
+      @ <tr><th>User:</td><td>
+      hyperlink_to_user(zUser,zDate,"</td></tr>");
     }
     if( zEComment ){
       @ <tr><th>Edited&nbsp;Comment:</th><td>%w(zEComment)</td></tr>
       @ <tr><th>Original&nbsp;Comment:</th><td>%w(zComment)</td></tr>
     }else{
@@ -509,65 +381,10 @@
     @ <blockquote><pre>
     append_diff(pid, fid);
     @ </pre></blockquote>
   }
   db_finalize(&q);
-
-#if 0
-  @ <ul>
-  db_prepare(&q,
-     "SELECT a.name, b.name"
-     "  FROM mlink, filename AS a, filename AS b"
-     " WHERE mid=%d"
-     "   AND a.fnid=mlink.fnid"
-     "   AND b.fnid=mlink.pfnid",
-     rid
-  );
-  while( db_step(&q)==SQLITE_ROW ){
-    const char *zName = db_column_text(&q, 0);
-    const char *zPrior = db_column_text(&q, 1);
-    @ <li><b>Renamed:</b>
-    if( g.okHistory ){
-      @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zPrior)</a> to
-      @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li>
-    }else{
-      @ %h(zPrior) to %h(zName)</li>
-    }
-  }
-  db_finalize(&q);
-  db_prepare(&q,
-     "SELECT name, pid, fid "
-     "  FROM mlink, filename"
-     " WHERE mid=%d"
-     "   AND fid!=pid"
-     "   AND filename.fnid=mlink.fnid",
-     rid
-  );
-  while( db_step(&q)==SQLITE_ROW ){
-    const char *zName = db_column_text(&q, 0);
-    int pid = db_column_int(&q, 1);
-    int fid = db_column_int(&q, 2);
-    if( pid && fid ){
-      @ <li><b>Modified:</b>
-    }else if( fid ){
-      @ <li><b>Added:</b>
-    }else if( pid ){
-      @ <li><b>Deleted:</b>
-    }
-    if( g.okHistory ){
-      @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li>
-    }else{
-      @ %h(zName)</li>
-    }
-  }
-  @ </ul>
-  compute_leaves(rid, 0);
-  showDescendants(rid, 2, "Descendants");
-  showLeaves(rid);
-  showAncestors(rid, 2, "Ancestors");
-#endif
-
   style_footer();
 }
 
 /*
 ** WEBPAGE: winfo
@@ -758,12 +575,13 @@
   while( db_step(&q)==SQLITE_ROW ){
     const char *zDate = db_column_text(&q, 0);
     const char *zUser = db_column_text(&q, 2);
     const char *zComment = db_column_text(&q, 1);
     @ <h2>Check-in %s(zUuid)</h2>
-    @ <p>Made by %h(zUser) on
-    link_to_date(zDate, ":");
+    @ <p>Made by
+    hyperlink_to_user(zUser,zDate," on");
+    hyperlink_to_date(zDate, ":");
     @ %w(zComment). <a href="%s(g.zBaseURL)/ci/%s(zUuid)">[details]</a></p>
     @ <hr>
   }
   db_finalize(&q);
   db_prepare(&q,
@@ -792,11 +610,11 @@
 **
 ** If the object is a file then mention:
 **
 **     * It's artifact ID
 **     * All its filenames
-**     * The baselines it was checked-in on, with times and users
+**     * The check-in it was part of, with times and users
 **
 ** If the object is a manifest, then mention:
 **
 **     * It's artifact ID
 **     * date of check-in
@@ -836,11 +654,13 @@
       @ File
     }
     @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a>
     @ artifact %s(zFuuid) part of check-in
     hyperlink_to_uuid(zVers);
-    @ - %w(zCom) by %h(zUser) on %s(zDate).
+    @ - %w(zCom) by
+    hyperlink_to_user(zUser,zDate," on");
+    hyperlink_to_date(zDate,".");
     cnt++;
     if( pDownloadName && blob_size(pDownloadName)==0 ){
       blob_append(pDownloadName, zName, -1);
     }
   }
@@ -865,11 +685,13 @@
       @ Also wiki page
     }else{
       @ Wiki page
     }
     @ [<a href="%s(g.zBaseURL)/wiki?name=%t(zPagename)">%h(zPagename)</a>]
-    @ artifact %s(zUuid) by %h(zUser) on %s(zDate).
+    @ artifact %s(zUuid) by
+    hyperlink_to_user(zUser,zDate," on");
+    hyperlink_to_date(zDate,".");
     nWiki++;
     cnt++;
     if( pDownloadName && blob_size(pDownloadName)==0 ){
       blob_append(pDownloadName, zPagename, -1);
     }
@@ -895,16 +717,18 @@
       if( zType[0]=='w' ){
         @ Wiki edit
       }else if( zType[0]=='t' ){
         @ Ticket change
       }else if( zType[0]=='c' ){
-        @ Manifest of baseline
+        @ Manifest of check-in
       }else{
         @ Control file referencing
       }
       hyperlink_to_uuid(zUuid);
-      @ - %w(zCom) by %h(zUser) on %s(zDate).
+      @ - %w(zCom) by
+      hyperlink_to_user(zUser,zDate," on");
+      hyperlink_to_date(zDate, ".");
       if( pDownloadName && blob_size(pDownloadName)==0 ){
         blob_append(pDownloadName, zUuid, -1);
       }
       cnt++;
     }

Modified src/timeline.c from [c172ebcb91] to [03b554d5e6].

@@ -75,10 +75,40 @@
     }
   }
 }
 
 /*
+** Generate a hyperlink to a date & time.
+*/
+void hyperlink_to_date(const char *zDate, const char *zSuffix){
+  if( zSuffix==0 ) zSuffix = "";
+  if( g.okHistory ){
+    @ <a href="%s(g.zTop)/timeline?c=%T(zDate)">%s(zDate)</a>%s(zSuffix)
+  }else{
+    @ %s(zDate)%s(zSuffix)
+  }
+}
+
+/*
+** Generate a hyperlink to a user.  This will link to a timeline showing
+** events by that user.  If the date+time is specified, then the timeline
+** is centered on that date+time.
+*/
+void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
+  if( zSuf==0 ) zSuf = "";
+  if( g.okHistory ){
+    if( zD && zD[0] ){
+      @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf)
+    }else{
+      @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf)
+    }
+  }else{
+    @ %s(zU)
+  }
+}
+
+/*
 ** Count the number of primary non-branch children for the given check-in.
 **
 ** A primary child is one where the parent is the primary parent, not
 ** a merge parent.
 **
@@ -155,10 +185,14 @@
     const char *zBgClr = db_column_text(pQuery, 8);
     const char *zDate = db_column_text(pQuery, 2);
     const char *zType = db_column_text(pQuery, 9);
     const char *zUser = db_column_text(pQuery, 4);
     const char *zTagList = db_column_text(pQuery, 10);
+    if( strcmp(zType,"div")==0 ){
+      @ <tr><td colspan=3><hr></td></tr>
+      continue;
+    }
     db_multi_exec("INSERT OR IGNORE INTO seen VALUES(%d)", rid);
     if( memcmp(zDate, zPrevDate, 10) ){
       sprintf(zPrevDate, "%.10s", zDate);
       @ <tr><td colspan=3>
       @   <div class="divider">%s(zPrevDate)</div>
@@ -461,10 +495,15 @@
         blob_appendf(&sql,
             " AND event.mtime>=%f ORDER BY event.mtime ASC",
             rCirca
         );
         nEntry -= (nEntry+1)/2;
+        db_multi_exec(
+          "INSERT OR IGNORE INTO timeline(timestamp,etype)"
+          "VALUES(datetime(%f,'localtime'),'div')",
+          rCirca
+        );
         url_add_parameter(&url, "c", zCirca);
       }else{
         zCirca = 0;
       }
     }else{
@@ -625,17 +664,10 @@
   @     }
   @   }
   @ }
   @ </script>
   style_footer();
-}
-
-/*
-** Render the date string given as a hyperlink to a "circa" timeline.
-*/
-void link_to_date(const char *zDate, const char *zSuffix){
-  @ <a href="%s(g.zBaseURL)/timeline?c=%t(zDate)">%h(zDate)</a>%s(zSuffix)
 }
 
 /*
 ** The input query q selects various records.  Print a human-readable
 ** summary of those records.