Check-in [08db9e11cb]
Not logged in
Overview

SHA1 Hash:08db9e11cb6f86f943893cc154bc86c6285ec7ab
Date: 2009-01-21 23:40:17
User: drh
Comment:Track the origin of tags and display that origin in the tag and properities information field of the "vinfo" page. Must "fossil rebuild" after this change.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/branch.c from [df727f7105] to [ffbb452f74].

@@ -255,10 +255,44 @@
     "%s AND blob.rid IN (SELECT rid FROM tagxref WHERE tagtype>0 AND tagid=%d)"
     " ORDER BY event.mtime DESC",
     timeline_query_for_www(), TAG_NEWBRANCH
   );
   www_print_timeline(&q, 0, brlist_extra);
+  db_finalize(&q);
+  @ <br clear="both">
+  @ <script>
+  @ function xin(id){
+  @ }
+  @ function xout(id){
+  @ }
+  @ </script>
+  style_footer();
+}
+
+/*
+** WEBPAGE: symtaglist
+**
+** Show a timeline of all check-ins that have a primary symbolic tag.
+*/
+void symtaglist_page(void){
+  Stmt q;
+
+  login_check_credentials();
+  if( !g.okRead ){ login_needed(); return; }
+
+  style_header("Tagged Check-ins");
+  login_anonymous_available();
+  @ <h2>Check-ins that have one or more primary symbolic tags</h2>
+  db_prepare(&q,
+    "%s AND blob.rid IN (SELECT rid FROM tagxref"
+    "                     WHERE tagtype>1 AND srcid>0"
+    "                       AND tagid IN (SELECT tagid FROM tag "
+    "                                      WHERE tagname GLOB 'sym-*'))"
+    " ORDER BY event.mtime DESC",
+    timeline_query_for_www(), TAG_NEWBRANCH
+  );
+  www_print_timeline(&q, 0, 0);
   db_finalize(&q);
   @ <br clear="both">
   @ <script>
   @ function xin(id){
   @ }

Modified src/info.c from [e44bb517cc] to [b49f2b6028].

@@ -269,45 +269,53 @@
 */
 static void showTags(int rid, const char *zNotGlob){
   Stmt q;
   int cnt = 0;
   db_prepare(&q,
-    "SELECT tag.tagid, tagname, srcid, blob.uuid, value,"
-    "       datetime(tagxref.mtime,'localtime'), tagtype"
-    "  FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
-    "       LEFT JOIN blob ON blob.rid=tagxref.srcid"
+    "SELECT tag.tagid, tagname, "
+    "       (SELECT uuid FROM blob WHERE rid=tagxref.srcid AND rid!=%d),"
+    "       value, datetime(tagxref.mtime,'localtime'), tagtype,"
+    "       (SELECT uuid FROM blob WHERE rid=tagxref.origid)"
+    "  FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
     " WHERE tagxref.rid=%d AND tagname NOT GLOB '%s'"
-    " ORDER BY tagname", rid, zNotGlob
+    " ORDER BY tagname", rid, rid, zNotGlob
   );
   while( db_step(&q)==SQLITE_ROW ){
     const char *zTagname = db_column_text(&q, 1);
-    int srcid = db_column_int(&q, 2);
-    const char *zUuid = db_column_text(&q, 3);
-    const char *zValue = db_column_text(&q, 4);
-    const char *zDate = db_column_text(&q, 5);
-    int tagtype = db_column_int(&q, 6);
+    const char *zSrcUuid = db_column_text(&q, 2);
+    const char *zValue = db_column_text(&q, 3);
+    const char *zDate = db_column_text(&q, 4);
+    int tagtype = db_column_int(&q, 5);
+    const char *zOrigUuid = db_column_text(&q, 6);
     cnt++;
     if( cnt==1 ){
       @ <div class="section">Tags And Properties</div>
       @ <ul>
     }
     @ <li>
     @ <b>%h(zTagname)</b>
-    if( zValue ){
+    if( tagtype==0 ){
+      @ <i>cancelled.
+    }else if( zValue ){
       @ = %h(zValue)<i>
-    }else if( tagtype==0 ){
-      @ <i>Cancelled
-    }else{
+    }else {
       @ <i>
     }
-    if( srcid==0 ){
-      @ Inherited
-    }else if( zUuid ){
-      @ From
-      hyperlink_to_uuid(zUuid);
-    }
-    @ on %s(zDate)</i>
+    if( tagtype==2 ){
+      if( zOrigUuid && zOrigUuid[0] ){
+        @ inherited from
+        hyperlink_to_uuid(zOrigUuid);
+      }else{
+        @ propagates to descendants
+      }
+    }
+    if( zSrcUuid && zSrcUuid[0] ){
+      @ added by
+      hyperlink_to_uuid(zSrcUuid);
+      @ on %s(zDate)
+    }
+    @ </i>
   }
   db_finalize(&q);
   if( cnt ){
     @ </ul>
   }

Modified src/manifest.c from [6584f80fc0] to [a82cc38cad].

@@ -501,11 +501,11 @@
           zUuid = 0;
         }else{
           goto manifest_syntax_error;
         }
         defossilize(zName);
-        if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' && zName[0]!='0' ){
+        if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
           goto manifest_syntax_error;
         }
         if( validate16(&zName[1], strlen(&zName[1])) ){
           /* Do not allow tags whose names look like UUIDs */
           goto manifest_syntax_error;
@@ -948,14 +948,13 @@
       }else{
         tid = rid;
       }
       if( tid ){
         switch( m.aTag[i].zName[0] ){
-          case '+':  type = 1;  break;
-          case '*':  type = 2;  break;
-          case '-':  type = 0;  break;
-          case '0':  type = -1; break;
+          case '-':  type = 0;  break;  /* Cancel prior occurances */
+          case '+':  type = 1;  break;  /* Apply to target only */
+          case '*':  type = 2;  break;  /* Propagate to descendants */
           default:
             fossil_fatal("unknown tag type in manifest: %s", m.aTag);
             return 0;
         }
         tag_insert(&m.aTag[i].zName[1], type, m.aTag[i].zValue,

Modified src/schema.c from [aa74a1f6fa] to [2bbbb93440].

@@ -290,14 +290,15 @@
 @ -- keep calling them tags because in many cases the value is ignored.
 @ --
 @ CREATE TABLE tagxref(
 @   tagid INTEGER REFERENCES tag,   -- The tag that added or removed
 @   tagtype INTEGER,                -- 0:cancel  1:single  2:branch
-@   srcid INTEGER REFERENCES blob,  -- Origin of the tag. 0 for propagated tags
+@   srcid INTEGER REFERENCES blob,  -- Artifact of tag. 0 for propagated tags
+@   origid INTEGER REFERENCES blob, -- check-in holding propagated tag
 @   value TEXT,                     -- Value of the tag.  Might be NULL.
 @   mtime TIMESTAMP,                -- Time of addition or removal
-@   rid INTEGER REFERENCE blob,     -- Baseline that tag added/removed from
+@   rid INTEGER REFERENCE blob,     -- Artifact tag is applied to
 @   UNIQUE(rid, tagid)
 @ );
 @ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);
 @
 @ -- Template for the TICKET table

Modified src/tag.c from [2e6da967ad] to [fb6da1128f].

@@ -39,10 +39,11 @@
 */
 void tag_propagate(
   int pid,             /* Propagate the tag to children of this node */
   int tagid,           /* Tag to propagate */
   int tagType,         /* 2 for a propagating tag.  0 for an antitag */
+  int origId,          /* Artifact of tag, when tagType==2 */
   const char *zValue,  /* Value of the tag.  Might be NULL */
   double mtime         /* Timestamp on the tag */
 ){
   PQueue queue;
   Stmt s, ins, eventupdate;
@@ -58,13 +59,13 @@
      tagType!=0, tagid
   );
   db_bind_double(&s, ":mtime", mtime);
   if( tagType==2 ){
     db_prepare(&ins,
-       "REPLACE INTO tagxref(tagid, tagtype, srcid, value, mtime, rid)"
-       "VALUES(%d,2,0,%Q,:mtime,:rid)",
-       tagid, zValue
+       "REPLACE INTO tagxref(tagid, tagtype, srcid, origid, value, mtime, rid)"
+       "VALUES(%d,2,0,%d,%Q,:mtime,:rid)",
+       tagid, origId, zValue
     );
     db_bind_double(&ins, ":mtime", mtime);
   }else{
     zValue = 0;
     db_prepare(&ins,
@@ -108,21 +109,22 @@
 ** Propagate all propagatable tags in pid to its children.
 */
 void tag_propagate_all(int pid){
   Stmt q;
   db_prepare(&q,
-     "SELECT tagid, tagtype, mtime, value FROM tagxref"
+     "SELECT tagid, tagtype, mtime, value, origid FROM tagxref"
      " WHERE rid=%d"
      "   AND (tagtype=0 OR tagtype=2)",
      pid
   );
   while( db_step(&q)==SQLITE_ROW ){
     int tagid = db_column_int(&q, 0);
     int tagtype = db_column_int(&q, 1);
     double mtime = db_column_double(&q, 2);
     const char *zValue = db_column_text(&q, 3);
-    tag_propagate(pid, tagid, tagtype, zValue, mtime);
+    int origid = db_column_int(&q, 4);
+    tag_propagate(pid, tagid, tagtype, origid, zValue, mtime);
   }
   db_finalize(&q);
 }
 
 /*
@@ -142,11 +144,11 @@
 /*
 ** Insert a tag into the database.
 */
 void tag_insert(
   const char *zTag,        /* Name of the tag (w/o the "+" or "-" prefix */
-  int tagtype,             /* 0:cancel  1:singleton  2:propagated -1:erase */
+  int tagtype,             /* 0:cancel  1:singleton  2:propagated */
   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 */
 ){
@@ -169,14 +171,10 @@
   rc = db_step(&s);
   db_finalize(&s);
   if( rc==SQLITE_ROW ){
     /* Another entry that is more recent already exists.  Do nothing */
     return;
-  }
-  if( tagtype<0 ){
-    return;
-    /* TBD: erase tags */
   }
   db_prepare(&s,
     "REPLACE INTO tagxref(tagid,tagtype,srcId,value,mtime,rid)"
     " VALUES(%d,%d,%d,%Q,:mtime,%d)",
     tagid, tagtype, srcId, zValue, rid
@@ -204,11 +202,11 @@
   }
   if( zCol ){
     db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
   }
   if( tagtype==0 || tagtype==2 ){
-    tag_propagate(rid, tagid, tagtype, zValue, mtime);
+    tag_propagate(rid, tagid, tagtype, rid, zValue, mtime);
   }
 }
 
 
 /*