Check-in [df3e34c2e8]
Not logged in
Overview

SHA1 Hash:df3e34c2e8b22fab30f92d5c41c692f428353232
Date: 2009-09-14 15:14:32
User: drh
Comment:Changes to the event mechanism to abbreviate a sequence of edits to the same ticket. Updates through this check-in require a "rebuild".
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/manifest.c from [2a86daa023] to [5e32c12dce].

@@ -922,21 +922,24 @@
 ** Make an entry in the event table for a ticket change artifact.
 */
 void manifest_ticket_event(
   int rid,                    /* Artifact ID of the change ticket artifact */
   const Manifest *pManifest,  /* Parsed content of the artifact */
-  int isNew                   /* True if this is the first event */
+  int isNew,                  /* True if this is the first event */
+  int tktTagId                /* Ticket tag ID */
 ){
   int i;
   char *zTitle;
   Blob comment;
+  Blob brief;
   char *zNewStatus = 0;
   static char *zTitleExpr = 0;
   static char *zStatusColumn = 0;
   static int once = 1;
 
   blob_zero(&comment);
+  blob_zero(&brief);
   if( once ){
     once = 0;
     zTitleExpr = db_get("ticket-title-expr", "title");
     zStatusColumn = db_get("ticket-status-column", "status");
   }
@@ -956,10 +959,12 @@
       );
       if( pManifest->nField>1 ){
         blob_appendf(&comment, " plus %d other change%s",
           pManifest->nField-1, pManifest->nField==2 ? "" : "s");
       }
+      blob_appendf(&brief, "%h ticket [%.10s].",
+                   zNewStatus, pManifest->zTicketUuid);
     }else{
       zNewStatus = db_text("unknown",
          "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
          zStatusColumn, pManifest->zTicketUuid
       );
@@ -967,23 +972,30 @@
            "%d other change%s",
            pManifest->zTicketUuid, zTitle, zNewStatus, pManifest->nField,
            pManifest->nField==1 ? "" : "s"
       );
       free(zNewStatus);
+      blob_appendf(&brief, "Ticket [%.10s]: %d change%s",
+           pManifest->zTicketUuid, pManifest->nField,
+           pManifest->nField==1 ? "" : "s"
+      );
     }
   }else{
     blob_appendf(&comment, "New ticket [%.10s] <i>%h</i>.",
       pManifest->zTicketUuid, zTitle
     );
+    blob_appendf(&brief, "New ticket [%.10s].", pManifest->zTicketUuid);
   }
   free(zTitle);
   db_multi_exec(
-    "REPLACE INTO event(type,mtime,objid,user,comment)"
-    "VALUES('t',%.17g,%d,%Q,%Q)",
-    pManifest->rDate, rid, pManifest->zUser, blob_str(&comment)
+    "REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)"
+    "VALUES('t',%d,%.17g,%d,%Q,%Q,%Q)",
+    tktTagId, pManifest->rDate, rid, pManifest->zUser,
+    blob_str(&comment), blob_str(&brief)
   );
   blob_reset(&comment);
+  blob_reset(&brief);
 }
 
 /*
 ** Scan artifact rid/pContent to see if it is a control artifact of
 ** any key:

Modified src/schema.c from [db3fd09f7a] to [6fd1e2b445].

@@ -223,16 +223,18 @@
 @ --
 @ CREATE TABLE event(
 @   type TEXT,                      -- Type of event
 @   mtime DATETIME,                 -- Date and time when the event occurs
 @   objid INTEGER PRIMARY KEY,      -- Associated record ID
+@   tagid INTEGER,                  -- Associated ticket or wiki name tag
 @   uid INTEGER REFERENCES user,    -- User who caused the event
 @   bgcolor TEXT,                   -- Color set by 'bgcolor' property
 @   euser TEXT,                     -- User set by 'user' property
 @   user TEXT,                      -- Name of the user
 @   ecomment TEXT,                  -- Comment set by 'comment' property
-@   comment TEXT                    -- Comment describing the event
+@   comment TEXT,                   -- Comment describing the event
+@   brief TEXT                      -- Short comment when tagid already seen
 @ );
 @ CREATE INDEX event_i1 ON event(mtime);
 @
 @ -- A record of phantoms.  A phantom is a record for which we know the
 @ -- UUID but we do not (yet) know the file content.

Modified src/timeline.c from [846d5cea62] to [cfb7f2bb64].

@@ -132,10 +132,11 @@
 ** Allowed flags for the tmFlags argument to www_print_timeline
 */
 #if INTERFACE
 #define TIMELINE_ARTID    0x0001  /* Show artifact IDs on non-check-in lines */
 #define TIMELINE_LEAFONLY 0x0002  /* Show "Leaf", but not "Merge", "Fork" etc */
+#define TIMELINE_BRIEF    0x0004  /* Combine adjacent elements of same object */
 #endif
 
 /*
 ** Output a timeline in the web format given a query.  The query
 ** should return these columns:
@@ -147,12 +148,14 @@
 **    4.  User
 **    5.  Number of non-merge children
 **    6.  Number of parents
 **    7.  True if is a leaf
 **    8.  background color
-**    9.  type ("ci", "w")
+**    9.  type ("ci", "w", "t")
 **   10.  list of symbolic tags.
+**   11.  tagid for ticket or wiki
+**   12.  Short comment to user for repeated tickets and wiki
 */
 void www_print_timeline(
   Stmt *pQuery,          /* Query to implement the timeline */
   int tmFlags,           /* Flags controlling display behavior */
   void (*xExtra)(int)    /* Routine to call on each line of display */
@@ -160,10 +163,12 @@
   int wikiFlags;
   int mxWikiLen;
   Blob comment;
   char zPrevDate[20];
   zPrevDate[0] = 0;
+  int prevTagid = 0;
+  int suppressCnt = 0;
 
   mxWikiLen = db_get_int("timeline-max-comment", 0);
   if( db_get_boolean("timeline-block-markup", 0) ){
     wikiFlags = WIKI_INLINE;
   }else{
@@ -185,10 +190,29 @@
     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);
+    int tagid = db_column_int(pQuery, 11);
+    int commentColumn = 3;    /* Column containing comment text */
+    if( tagid ){
+      if( tagid==prevTagid ){
+        if( tmFlags & TIMELINE_BRIEF ){
+          suppressCnt++;
+          continue;
+        }else{
+          commentColumn = 12;
+        }
+      }
+    }
+    prevTagid = tagid;
+    if( suppressCnt ){
+      @ <tr><td><td><td>
+      @ ... preceded by %d(suppressCnt) other
+      @ similar event%s(suppressCnt>1?"s":"").</tr>
+      suppressCnt = 0;
+    }
     if( strcmp(zType,"div")==0 ){
       @ <tr><td colspan=3><hr></td></tr>
       continue;
     }
     db_multi_exec("INSERT OR IGNORE INTO seen VALUES(%d)", rid);
@@ -239,11 +263,11 @@
         }
       }
     }else if( (tmFlags & TIMELINE_ARTID)!=0 ){
       hyperlink_to_uuid(zUuid);
     }
-    db_column_blob(pQuery, 3, &comment);
+    db_column_blob(pQuery, commentColumn, &comment);
     if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
       Blob truncated;
       blob_zero(&truncated);
       blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
       blob_append(&truncated, "...", 3);
@@ -280,11 +304,13 @@
     @   nchild INTEGER,
     @   nparent INTEGER,
     @   isleaf BOOLEAN,
     @   bgcolor TEXT,
     @   etype TEXT,
-    @   taglist TEXT
+    @   taglist TEXT,
+    @   tagid INTEGER,
+    @   short TEXT
     @ )
   ;
   db_multi_exec(zSql);
 }
 
@@ -311,11 +337,13 @@
     @                              WHERE tagid=%d AND rid=plink.cid), 'trunk')),
     @   bgcolor,
     @   event.type,
     @   (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref
     @     WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
-    @       AND tagxref.rid=blob.rid AND tagxref.tagtype>0)
+    @       AND tagxref.rid=blob.rid AND tagxref.tagtype>0),
+    @   tagid,
+    @   brief
     @  FROM event JOIN blob
     @ WHERE blob.rid=event.objid
   ;
   if( zBase==0 ){
     zBase = mprintf(zBaseSql, TAG_BRANCH, TAG_BRANCH);
@@ -393,19 +421,25 @@
   const char *zBefore = P("b");      /* Events before this time */
   const char *zCirca = P("c");       /* Events near this time */
   const char *zTagName = P("t");     /* Show events with this tag */
   HQuery url;                        /* URL for various branch links */
   int tagid;                         /* Tag ID */
+  int tmFlags;                       /* Timeline flags */
 
   /* To view the timeline, must have permission to read project data.
   */
   login_check_credentials();
   if( !g.okRead ){ login_needed(); return; }
   if( zTagName ){
     tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
   }else{
     tagid = 0;
+  }
+  if( zType[0]=='a' ){
+    tmFlags = TIMELINE_BRIEF;
+  }else{
+    tmFlags = 0;
   }
 
   style_header("Timeline");
   login_anonymous_available();
   timeline_temp_table();
@@ -597,11 +631,11 @@
   }
   blob_zero(&sql);
   db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC");
   @ <h2>%b(&desc)</h2>
   blob_reset(&desc);
-  www_print_timeline(&q, 0, 0);
+  www_print_timeline(&q, tmFlags, 0);
   db_finalize(&q);
 
   @ <script>
   @ var parentof = new Object();
   @ var childof = new Object();

Modified src/tkt.c from [bc233f791c] to [c30fd6165c].

@@ -264,11 +264,11 @@
   while( db_step(&q)==SQLITE_ROW ){
     int rid = db_column_int(&q, 0);
     content_get(rid, &content);
     manifest_parse(&manifest, &content);
     ticket_insert(&manifest, createFlag, 0);
-    manifest_ticket_event(rid, &manifest, createFlag);
+    manifest_ticket_event(rid, &manifest, createFlag, tagid);
     manifest_clear(&manifest);
     createFlag = 0;
   }
   db_finalize(&q);
 }