Check-in [3984b1b2c1]
Not logged in
Overview

SHA1 Hash:3984b1b2c117b7b3ea4ab2b844e1b607d03dbf8a
Date: 2008-08-04 20:46:52
User: eric
Comment:Make the info web page handle symbolic tags as well as UUIDs. Start trying to make the currently-disabled tagview page more useful.
Timelines: ancestors | descendants | both | eric-tagview-rework | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/info.c from [1b352f5977] to [3ed7c9edba].

@@ -911,17 +911,34 @@
 **
 ** Figure out what the UUID is and jump to it.
 */
 void info_page(void){
   const char *zName;
+  Blob uuid;
   int rid, nName;
 
   zName = P("name");
   if( zName==0 ) fossil_redirect_home();
   nName = strlen(zName);
   if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
-    fossil_redirect_home();
+    switch( sym_tag_to_uuid(zName, &uuid) ){
+      case 1: {
+        /* got one UUID, use it */
+        zName = blob_str(&uuid);
+        break;
+      }
+      case 2: {
+        /* go somewhere to show the multiple UUIDs */
+        tagview_page();
+        return;
+        break;
+      }
+      default: {
+        fossil_redirect_home();
+        break;
+      }
+    }
   }
   if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%s*'", zName) ){
     tktview_page();
     return;
   }

Modified src/login.c from [c686a3eaf4] to [86fb4c3fd8].

@@ -299,11 +299,11 @@
   }
   g.userUid = uid;
   if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
     g.zLogin = 0;
   }
-  if( uid>0 ){
+  if( uid && g.zLogin ){
     zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'");
     login_set_capabilities(zNcap);
     if( db_get_int("inherit-anon",0) ){
       zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
       login_set_capabilities(zAcap);

Modified src/name.c from [825efda6ea] to [cf54ee1717].

@@ -44,34 +44,20 @@
 int name_to_uuid(Blob *pName, int iErrPriority){
   int rc;
   int sz;
   sz = blob_size(pName);
   if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){
-    Stmt q;
     Blob uuid;
     static const char prefix[] = "tag:";
     static const int preflen = sizeof(prefix)-1;
     const char *zName = blob_str(pName);
 
     if( strncmp(zName, prefix, preflen)==0 ){
       zName += preflen;
     }
 
-    db_prepare(&q,
-      "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
-      "  FROM tagxref JOIN event ON rid=objid"
-      " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='sym-'||%Q)"
-      "   AND tagtype>0"
-      "   AND value IS NULL"
-      " ORDER BY event.mtime DESC",
-      zName
-    );
-    blob_zero(&uuid);
-    if( db_step(&q)==SQLITE_ROW ){
-      db_column_blob(&q, 0, &uuid);
-    }
-    db_finalize(&q);
+    sym_tag_to_uuid(zName, &uuid);
     if( blob_size(&uuid)==0 ){
       fossil_error(iErrPriority, "not a valid object name: %s", zName);
       blob_reset(&uuid);
       return 1;
     }else{
@@ -110,10 +96,46 @@
     }
   }else{
     rc = 0;
   }
   return rc;
+}
+
+/*
+** This routine takes a name which might be a symbolic tag and
+** attempts to produce a UUID. The UUID (if any) is returned in the
+** blob pointed to by the second argument.
+**
+** Return as follows:
+**      0   Name is not a tag
+**      1   A single UUID was found
+**      2   More than one UUID was found, so this is presumably a
+**          propagating tag. The return UUID is the most recent,
+**          which is most likely to be the one wanted.
+*/
+int sym_tag_to_uuid(const char *pName, Blob *pUuid){
+  Stmt q;
+  int count = 0;
+  db_prepare(&q,
+    "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
+    "  FROM tagxref JOIN event ON rid=objid"
+    " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='sym-'||%Q)"
+    "   AND tagtype>0"
+    "   AND value IS NULL"
+    " ORDER BY event.mtime DESC",
+    pName
+  );
+  blob_zero(pUuid);
+  while( db_step(&q)==SQLITE_ROW ){
+    count++;
+    if(count>1){
+      break;
+    }
+    db_column_blob(&q, 0, pUuid);
+  }
+  db_finalize(&q);
+  return count;
 }
 
 /*
 ** COMMAND:  test-name-to-uuid
 **

Modified src/tagview.c from [73b17a9efb] to [8e6ed27d79].

@@ -78,11 +78,11 @@
 ** A small search form which forwards to ?like=SEARCH_STRING
 */
 static void tagview_page_search_miniform(void){
   char const * like = P("like");
   @ <div style='font-size:smaller'>
-  @ <form action='/tagview' method='post'>
+  @ <form action='tagview' method='post'>
   @ Search for tags:
   @ <input type='text' name='like' value='%h((like?like:""))' size='10'/>
   @ <input type='submit'/>
   @ </form>
   @ </div>
@@ -134,15 +134,40 @@
     tagname);
   db_generic_query_view(zSql, 1);
   free(zSql);
 }
 
+/*
+** Get the UUIDs for a tag
+*/
+char *tag_query_for_www(const char *pName){
+  static const char zBaseSql[] =
+  @ SELECT
+  @   blob.rid,
+  @   uuid,
+  @   datetime(event.mtime,'localtime') AS timestamp,
+  @   coalesce(ecomment, comment),
+  @   coalesce(euser, 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),
+  @   coalesce(bgcolor, brbgcolor),
+  @   event.type
+  @  FROM event JOIN blob JOIN tagxref
+  @ WHERE blob.rid=event.objid
+  @ AND tagxref.rid = event.objid
+  @ AND tagxref.tagid = (SELECT tagid FROM tag
+  @       WHERE tagname = 'sym-'||%Q)
+  @ ORDER BY 3 desc
+  ;
+  return mprintf(zBaseSql,pName);
+}
 
 /*
-** WEBPAGE: /tagview
+** WEBP AGE: /tagview
 */
-void tagview_page(void){
+void old_tagview_page(void){
   char const * check = 0;
   login_check_credentials();
   if( !g.okRdWiki ){
     login_needed();
   }
@@ -156,10 +181,64 @@
     tagview_page_list_tags( check );
   }else if( 0 != (check = P("name")) ){
     tagview_page_tag_by_name( check );
   }else{
     tagview_page_default();
+  }
+  style_footer();
+}
+
+/*
+** WEBPAGE: /tagview
+*/
+void tagview_page(void){
+  char const *zName = 0;
+  login_check_credentials();
+  if( !g.okRead ){
+    login_needed();
+  }
+  login_anonymous_available();
+  if( 0 != (zName = P("name")) ){
+    Blob uuid;
+    char *zSql;
+    Stmt q;
+    if( sym_tag_to_uuid(zName, &uuid) > 0){
+      style_header("Tagged Baselines");
+      @ <h2>%s(zName):</h2>
+      zSql = tag_query_for_www(zName);
+      db_prepare(&q, zSql);
+      free(zSql);
+      www_print_timeline(&q);
+      db_finalize(&q);
+    }else{
+      style_header("TaggedBaselines");
+      @ <h2>%s(zName):</h2>
+      @ There is no artifact with this tag.
+    }
+  }else{
+    Stmt q;
+    const char *prefix = "sym-";
+    int preflen = strlen(prefix);
+    style_header("Tags");
+    db_prepare(&q,
+      "SELECT tagname"
+      "  FROM tag"
+      " WHERE EXISTS(SELECT 1 FROM tagxref"
+      "               WHERE tagid=tag.tagid"
+      "                 AND tagtype>0)"
+      " ORDER BY tagname"
+    );
+    @ <ul>
+    while( db_step(&q)==SQLITE_ROW ){
+      const char *name = db_column_text(&q, 0);
+      if( strncmp(name, prefix, preflen)==0 ){
+        @ <li><a href=%s(g.zBaseURL)/tagview?name=%s(name+preflen)>
+        @ %s(name+preflen)</a></li>
+      }
+    }
+    @ </ul>
+    db_finalize(&q);
   }
   style_footer();
 }
 
 #undef TAGVIEW_DEFAULT_FILTER