Check-in [9395aba4f4]
Not logged in
Overview

SHA1 Hash:9395aba4f41641191e172b786274f53b2b20a697
Date: 2007-09-22 12:38:05
User: drh
Comment:Timeline now responses to comment and user properties.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/descendents.c from [f44f14d0b6] to [57da1765de].

@@ -147,16 +147,14 @@
     base = name_to_rid(g.argv[2]);
   }
   if( base==0 ) return;
   compute_leaves(base);
   db_prepare(&q,
-    "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'), comment, 0,"
-    "       (SELECT count(*) FROM plink WHERE cid=blob.rid)"
-    "  FROM leaves, blob, event"
-    " WHERE blob.rid=leaves.rid"
-    "   AND event.objid=leaves.rid"
-    " ORDER BY event.mtime DESC"
+    "%s"
+    "   AND event.objid IN (SELECT rid FROM leaves)"
+    " ORDER BY event.mtime DESC",
+    timeline_query_for_tty()
   );
   print_timeline(&q, 20);
   db_finalize(&q);
 }
 
@@ -169,18 +167,15 @@
 void branches_cmd(void){
   Stmt q;
 
   db_must_be_within_tree();
   db_prepare(&q,
-    "SELECT blob.rid, blob.uuid, datetime(event.mtime,'localtime'),"
-    "       event.comment, 0,"
-    "       (SELECT count(*) FROM plink WHERE cid=blob.rid)"
-    "  FROM blob, event"
-    " WHERE blob.rid IN"
+    "%s"
+    "   AND blob.rid IN"
     "       (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
-    "   AND event.objid=blob.rid"
-    " ORDER BY event.mtime DESC"
+    " ORDER BY event.mtime DESC",
+    timeline_query_for_tty()
   );
   print_timeline(&q, 2000);
   db_finalize(&q);
 }
 
@@ -195,17 +190,15 @@
   login_check_credentials();
   if( !g.okRead ){ login_needed(); return; }
 
   style_header("Leaves");
   db_prepare(&q,
-    "SELECT blob.rid, blob.uuid, datetime(event.mtime,'localtime'),"
-    "       event.comment, event.user, 1, 1, 0, NULL"
-    "  FROM blob, event"
-    " WHERE blob.rid IN"
+    "%s"
+    "   AND blob.rid IN"
     "       (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
-    "   AND event.objid=blob.rid"
-    " ORDER BY event.mtime DESC"
+    " ORDER BY event.mtime DESC",
+    timeline_query_for_www()
   );
   www_print_timeline(&q, 0, 0, 0, 0);
   db_finalize(&q);
   @ <script>
   @ function xin(id){

Modified src/tag.c from [2d541bbe04] to [8fad57b8b1].

@@ -120,10 +120,39 @@
     id = db_last_insert_rowid();
   }
   return id;
 }
 
+/*
+** Insert a tag into the database.
+*/
+void tag_insert(
+  const char *zTag,        /* Name of the tag (w/o the "+" or "-" prefix */
+  int addFlag,             /* True to add.  False to remove */
+  const char *zValue,      /* Value if the tag is really a property */
+  int srcId,               /* Artifact that contains this tag */
+  double mtime,            /* Timestamp.  Use default if <=0.0 */
+  int rid                  /* Artifact to which the tag is to attached */
+){
+  Stmt s;
+  int tagid = tag_findid(zTag, 1);
+  if( mtime<=0.0 ){
+    mtime = db_double(0.0, "SELECT julianday('now')");
+  }
+  db_prepare(&s,
+    "REPLACE INTO tagxref(tagid,addFlag,srcId,value,mtime,rid)"
+    " VALUES(%d,%d,%d,%Q,:mtime,%d)",
+    tagid, addFlag, srcId, zValue, rid
+  );
+  db_bind_double(&s, ":mtime", mtime);
+  db_step(&s);
+  db_finalize(&s);
+  if( strncmp(zTag, "br", 2)==0 ){
+    tag_propagate(rid, tagid, 1, zValue, mtime);
+  }
+}
+
 
 /*
 ** COMMAND: test-addtag
 ** %fossil test-addtag TAGNAME UUID ?VALUE?
 **
@@ -133,31 +162,45 @@
 ** use only.
 */
 void addtag_cmd(void){
   const char *zTag;
   const char *zValue;
-  int tagid;
-  int rid;
-  double now;
+  int rid;
   db_must_be_within_tree();
   if( g.argc!=4 && g.argc!=5 ){
     usage("TAGNAME UUID ?VALUE?");
   }
   zTag = g.argv[2];
   rid = name_to_rid(g.argv[3]);
   if( rid==0 ){
     fossil_fatal("no such object: %s", g.argv[3]);
   }
-  db_begin_transaction();
-  tagid = tag_findid(zTag, 1);
   zValue = g.argc==5 ? g.argv[4] : 0;
-  db_multi_exec(
-    "REPLACE INTO tagxref(tagid,addFlag,srcId,value,mtime,rid)"
-    " VALUES(%d,1,-1,%Q,julianday('now'),%d)",
-    tagid, rid, zValue, rid
-  );
-  if( strncmp(zTag, "br", 2)==0 ){
-    now = db_double(0.0, "SELECT julianday('now')");
-    tag_propagate(rid, tagid, 1, zValue, now);
+  db_begin_transaction();
+  tag_insert(zTag, 1, zValue, -1, 0.0, rid);
+  db_end_transaction(0);
+}
+/*
+** COMMAND: test-deltag
+** %fossil test-deltag TAGNAME UUID
+**
+** Cancel a tag to the rebuildable tables of the local repository.
+** No tag artifact is created so the cancellation is undone the next
+** time the repository is rebuilt.  This routine is for testing
+** use only.
+*/
+void deltag_cmd(void){
+  const char *zTag;
+  int rid;
+  db_must_be_within_tree();
+  if( g.argc!=4 ){
+    usage("TAGNAME UUID");
+  }
+  zTag = g.argv[2];
+  rid = name_to_rid(g.argv[3]);
+  if( rid==0 ){
+    fossil_fatal("no such object: %s", g.argv[3]);
   }
+  db_begin_transaction();
+  tag_insert(zTag, 0, 0, -1, 0.0, rid);
   db_end_transaction(0);
 }

Modified src/timeline.c from [aa66611fa0] to [34dd916f04].

@@ -75,11 +75,11 @@
   }
 }
 
 /*
 ** Output a timeline in the web format given a query.  The query
-** should return 4 columns:
+** should return these columns:
 **
 **    0.  rid
 **    1.  UUID
 **    2.  Date/Time
 **    3.  Comment string
@@ -189,10 +189,44 @@
   blob_appendf(pOut, "];\n");
   return 0;
 }
 
 /*
+** Return a pointer to a constant string that forms the basis
+** for a timeline query for the WWW interface.
+*/
+const char *timeline_query_for_www(void){
+  static const char zBaseSql[] =
+    @ SELECT
+    @   blob.rid,
+    @   uuid,
+    @   datetime(event.mtime,'localtime'),
+    @   coalesce((SELECT value FROM tagxref
+    @              WHERE rid=blob.rid
+    @                AND tagid=(SELECT tagid FROM tag WHERE tagname='comment')),
+    @            comment),
+    @   coalesce((SELECT value FROM tagxref
+    @              WHERE rid=blob.rid
+    @                AND tagid=(SELECT tagid FROM tag WHERE tagname='user')),
+    @            user),
+    @   (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),
+    @   (SELECT count(*) FROM plink WHERE cid=blob.rid),
+    @   NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),
+    @   (SELECT value FROM tagxref
+    @     WHERE rid=blob.rid
+    @       AND tagid=(SELECT tagid FROM tag WHERE tagname='bgcolor')
+    @    UNION ALL
+    @    SELECT value FROM tagxref
+    @     WHERE rid=blob.rid
+    @       AND tagid=(SELECT tagid FROM tag WHERE tagname='br-bgcolor'))
+    @  FROM event JOIN blob
+    @ WHERE blob.rid=event.objid
+  ;
+  return zBaseSql;
+}
+
+/*
 ** WEBPAGE: timeline
 **
 ** Query parameters:
 **
 **    d=STARTDATE    date in iso8601 notation.          dflt: newest event
@@ -213,38 +247,25 @@
   int objid = atoi(PD("e","0"));
   int relatedEvents = P("r")!=0;
   int afterFlag = P("a")!=0;
   int firstEvent;
   int lastEvent;
-  int clr1, clr2;     /* Tag IDs for specifying background colors */
 
   /* To view the timeline, must have permission to read project data.
   */
   login_check_credentials();
   if( !g.okRead ){ login_needed(); return; }
 
   style_header("Timeline");
-  clr1 = db_int(0, "SELECT tagid FROM tag WHERE tagname='br-bg-color'");
-  clr2 = db_int(0, "SELECT tagid FROM tag WHERE tagname='bg-color'");
   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 access <u>much</u> more
     @ historical information if <a href="%s(g.zBaseURL)/login">login</a>.</p>
   }
-  zSQL = mprintf(
-    "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'), comment, user,"
-    "       (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),"
-    "       (SELECT count(*) FROM plink WHERE cid=blob.rid),"
-    "       NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),"
-    "       (SELECT value FROM tagxref WHERE rid=blob.rid AND tagid=%d"
-    "        UNION ALL"
-    "        SELECT value FROM tagxref WHERE rid=blob.rid AND tagid=%d)"
-    "  FROM event JOIN blob"
-    " WHERE event.type='ci' AND blob.rid=event.objid", clr2, clr1
-  );
+  zSQL = mprintf("%s", timeline_query_for_www());
   if( zUser ){
     zSQL = mprintf("%z AND event.user=%Q", zSQL, zUser);
   }
   if( objid ){
     char *z = db_text(0, "SELECT datetime(event.mtime) FROM event"
@@ -367,10 +388,19 @@
 /*
 ** The input query q selects various records.  Print a human-readable
 ** summary of those records.
 **
 ** Limit the number of entries printed to nLine.
+**
+** The query should return these columns:
+**
+**    0.  rid
+**    1.  uuid
+**    2.  Date/Time
+**    3.  Comment string and user
+**    4.  Number of non-merge children
+**    5.  Number of parents
 */
 void print_timeline(Stmt *q, int mxLine){
   int nLine = 0;
   char zPrevDate[20];
   zPrevDate[0] = 0;
@@ -408,10 +438,38 @@
       zFree = sqlite3_mprintf("[%.10s] %s", zUuid, zCom);
     }
     nLine += comment_print(zFree, 9, 79);
     sqlite3_free(zFree);
   }
+}
+
+/*
+** Return a pointer to a static string that forms the basis for
+** a timeline query for display on a TTY.
+*/
+const char *timeline_query_for_tty(void){
+  static const char zBaseSql[] =
+    @ SELECT
+    @   blob.rid,
+    @   uuid,
+    @   datetime(event.mtime,'localtime'),
+    @   coalesce((SELECT value FROM tagxref
+    @             WHERE rid=blob.rid
+    @             AND tagid=(SELECT tagid FROM tag WHERE tagname='comment')),
+    @            comment)
+    @     || ' (by ' ||
+    @     coalesce((SELECT value FROM tagxref
+    @               WHERE rid=blob.rid
+    @               AND tagid=(SELECT tagid FROM tag WHERE tagname='user')),
+    @              user)
+    @     || ')',
+    @   (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim),
+    @   (SELECT count(*) FROM plink WHERE cid=blob.rid)
+    @ FROM event, blob
+    @ WHERE blob.rid=event.objid
+  ;
+  return zBaseSql;
 }
 
 
 /*
 ** COMMAND: timeline
@@ -492,19 +550,14 @@
     if( mode==3 || mode==4 ){
       fossil_fatal("cannot compute descendents or ancestors of a date");
     }
     zDate = mprintf("(SELECT julianday(%Q, 'utc'))", zOrigin);
   }
-  zSQL = mprintf(
-    "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'),"
-    "       comment || ' (by ' || user || ')',"
-    "       (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim),"
-    "       (SELECT count(*) FROM plink WHERE cid=blob.rid)"
-    "  FROM event, blob"
-    " WHERE event.type='ci' AND blob.rid=event.objid"
-    "   AND event.mtime %s %s",
-    (mode==1 || mode==4) ? "<=" : ">=", zDate
+  zSQL = mprintf("%s AND event.mtime %s %s",
+     timeline_query_for_tty(),
+     (mode==1 || mode==4) ? "<=" : ">=",
+     zDate
   );
   if( mode==3 || mode==4 ){
     db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
     if( mode==3 ){
       compute_descendents(objid, n);

Modified src/update.c from [6cc6e53fd7] to [07dea7ee93].

@@ -68,16 +68,14 @@
     }
   }else{
     compute_leaves(vid);
     if( db_int(0, "SELECT count(*) FROM leaves")>1 ){
       db_prepare(&q,
-        "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'),"
-        "       comment || ' (by ' || user || ')', 1, 1"
-        "  FROM event, blob"
-        " WHERE event.type='ci' AND blob.rid=event.objid"
+        "%s "
         "   AND event.objid IN leaves"
-        " ORDER BY event.mtime DESC"
+        " ORDER BY event.mtime DESC",
+        timeline_query_for_tty()
       );
       print_timeline(&q, 100);
       db_finalize(&q);
       fossil_fatal("Multiple descendents");
     }