Fossil
Check-in [615a52f0ba]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview

SHA1 Hash:615a52f0ba072ae9a1116b0a8d92e621687d3ce3
Date: 2010-03-16 16:52:37
User: drh
Comment:Change the format of the A-card for attachments again. Add the ATTACHMENT table to the repository. Insert attachment information into the ATTACHMENT table when processing attachment artifacts.

Tags And Properties
Changes
[hide diffs]

Changes to src/manifest.c

@@ -166,39 +166,40 @@
     cPrevType = z[0];
     seenHeader = 1;
     if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error;
     switch( z[0] ){
       /*
-      **     A (+|-)<filename> target source
+      **     A <filename> <target> ?<source>?
       **
       ** Identifies an attachment to either a wiki page or a ticket.
-      ** <uuid> is the artifact that is the attachment.
+      ** <source> is the artifact that is the attachment.  <source>
+      ** is omitted to delete an attachment.  <target> is the name of
+      ** a wiki page or ticket to which that attachment is connected.
       */
       case 'A': {
         char *zName, *zTarget, *zSrc;
         md5sum_step_text(blob_buffer(&line), blob_size(&line));
         if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
         if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
-        if( blob_token(&line, &a3)==0 ) goto manifest_syntax_error;
         if( p->zAttachName!=0 ) goto manifest_syntax_error;
         zName = blob_terminate(&a1);
         zTarget = blob_terminate(&a2);
+        blob_token(&line, &a3);
         zSrc = blob_terminate(&a3);
         defossilize(zName);
-        if( zName[0]!='+' && zName[0]!='-' ){
-          goto manifest_syntax_error;
-        }
-        if( !file_is_simple_pathname(&zName[1]) ){
+        if( !file_is_simple_pathname(zName) ){
           goto manifest_syntax_error;
         }
         defossilize(zTarget);
         if( (blob_size(&a2)!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
            && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
           goto manifest_syntax_error;
         }
-        if( blob_size(&a3)!=UUID_SIZE ) goto manifest_syntax_error;
-        if( !validate16(zSrc, UUID_SIZE) ) goto manifest_syntax_error;
+        if( blob_size(&a3)>0
+         && (blob_size(&a3)!=UUID_SIZE || !validate16(zSrc, UUID_SIZE)) ){
+          goto manifest_syntax_error;
+        }
         p->zAttachName = zName;
         p->zAttachSrc = zSrc;
         p->zAttachTarget = zTarget;
         break;
       }
@@ -622,10 +623,11 @@
   }else if( p->zAttachName ){
     if( p->nCChild>0 ) goto manifest_syntax_error;
     if( p->rDate==0.0 ) goto manifest_syntax_error;
     if( p->zTicketUuid ) goto manifest_syntax_error;
     if( p->zWikiTitle ) goto manifest_syntax_error;
+    if( !seenZ ) goto manifest_syntax_error;
     p->type = CFTYPE_ATTACHMENT;
   }else{
     if( p->nCChild>0 ) goto manifest_syntax_error;
     if( p->rDate<=0.0 ) goto manifest_syntax_error;
     if( p->nParent>0 ) goto manifest_syntax_error;
@@ -1114,10 +1116,23 @@
     zTag = mprintf("tkt-%s", m.zTicketUuid);
     tag_insert(zTag, 1, 0, rid, m.rDate, rid);
     free(zTag);
     db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)",
                   m.zTicketUuid);
+  }
+  if( m.type==CFTYPE_ATTACHMENT ){
+    db_multi_exec(
+       "INSERT OR IGNORE INTO attachment(mtime, target, filename)"
+       "VALUES(0.0,%Q,%Q)",
+       m.zAttachTarget, m.zAttachName
+    );
+    db_multi_exec(
+       "UPDATE attachment SET mtime=%.17g, src=%Q, comment=%Q, user=%Q"
+       " WHERE mtime<%.17g AND target=%Q AND filename=%Q",
+       m.rDate, m.zAttachSrc, m.zComment, m.zUser,
+       m.rDate, m.zAttachTarget, m.zAttachName
+    );
   }
   db_end_transaction(0);
   manifest_clear(&m);
   return 1;
 }

Changes to src/schema.c

@@ -322,10 +322,23 @@
 @   srcid INT,             -- rid for checkin or wiki.  tkt_id for ticket.
 @   mtime TIMESTAMP,       -- time that the hyperlink was added
 @   UNIQUE(target, srctype, srcid)
 @ );
 @ CREATE INDEX backlink_src ON backlink(srcid, srctype);
+@
+@ -- Each attachment is an entry in the following table.  Only
+@ -- the most recent attachment (identified by the D card) is saved.
+@ --
+@ CREATE TABLE attachment(
+@   mtime TIMESTAMP,                -- Time when attachment last changed
+@   src TEXT,                       -- UUID of the attachment.  NULL to delete
+@   target TEXT,                    -- Object attached to
+@   filename TEXT,                  -- Filename for the attachment
+@   comment TEXT,                   -- Comment associated with this attachment
+@   user TEXT,                      -- Name of user adding attachment
+@   PRIMARY KEY(target, filename)
+@ );
 @
 @ -- Template for the TICKET table
 @ --
 @ -- NB: when changing the schema of the TICKET table here, also make the
 @ -- same change in tktsetup.c.

Changes to www/fileformat.wiki

@@ -380,23 +380,23 @@
 attachment (the source artifact) with a ticket or wiki page to which
 the attachment is connected (the target artifact).
 The following cards are allowed on an attachment artifact:
 
 <blockquote>
-<b>A</b> (<b>+</b>|<b>-</b>)<i>filename target source</i>
+<b>A</b> <i>filename target</i> ?<i>source</i>?
 <b>C</b> <i>comment</i><br>
 <b>D</b> <i>time-and-date-stamp</i><br />
 <b>U</b> <i>user-name</i><br />
 <b>Z</b> <i>checksum</i>
 </blockquote>
 
 The A card specifies a filename for the attachment in its first argument.
-The filename is preceeded by "+" to add the attachment or "-" to
-remove the attachment.  The second argument to the A card is the name
+The second argument to the A card is the name
 of the wiki page or ticket to which the attachment is connected.  The
-third argument is is the 40-character artifact ID of the attachment
-itself.  Every attachment artifact must have exactly one A card.
+third argument is either missing or else it is the 40-character artifact
+ID of the attachment itself.  A missing third argument means that the
+attachment should be deleted.
 
 The C card is an optional comment describing what the attachment is about.
 The C card is optional, but there can only be one.
 
 A single D card is required to give the date and time when the attachment
@@ -426,11 +426,11 @@
 <th>Wiki</th>
 <th>Ticket</th>
 <th>Attachment</th>
 </tr>
 <tr>
-<td><b>A</b> (<b>+</b>|<b>-</b>)<i>filename target source</i></td>
+<td><b>A</b> <i>filename target source</i></td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>