Fossil

Check-in [615a52f0]
Login

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

Overview
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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 615a52f0ba072ae9a1116b0a8d92e621687d3ce3
User & Date: drh 2010-03-16 16:52:37
Context
2010-03-17
00:40
Get the derivation graph working for individual file histories. check-in: c19467d6 user: drh tags: trunk
2010-03-16
21:33
Work toward adding support for attachments. Keep this on an experimental branch until it is actually working. check-in: c3d7df65 user: drh tags: experimental
16:52
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. check-in: 615a52f0 user: drh tags: trunk
15:38
Improved file format documentation. Added information on the attachment artifact. Redefine the A-card (which has not previously been used). Update the Manifest object to store attachment artifacts. check-in: d5a4e41c user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/manifest.c.

164
165
166
167
168
169
170
171
172
173
174


175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198

199

200
201
202
203
204
205
206
...
620
621
622
623
624
625
626

627
628
629
630
631
632
633
....
1112
1113
1114
1115
1116
1117
1118













1119
1120
1121
1122
1123
      goto manifest_syntax_error;
    }
    cPrevType = z[0];
    seenHeader = 1;
    if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error;
    switch( z[0] ){
      /*
      **     A (+|-)<filename> target source
      **
      ** Identifies an attachment to either a wiki page or a ticket.
      ** <uuid> is the artifact that is the attachment.


      */
      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);

        zSrc = blob_terminate(&a3);
        defossilize(zName);
        if( zName[0]!='+' && zName[0]!='-' ){
          goto manifest_syntax_error;
        }
        if( !file_is_simple_pathname(&zName[1]) ){
          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;

        p->zAttachName = zName;
        p->zAttachSrc = zSrc;
        p->zAttachTarget = zTarget;
        break;
      }

      /*
................................................................................
    if( !seenZ ) goto manifest_syntax_error;
    p->type = CFTYPE_CONTROL;
  }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;

    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;
    if( p->nField>0 ) goto manifest_syntax_error;
    if( p->zTicketUuid ) goto manifest_syntax_error;
................................................................................

    assert( manifest_crosslink_busy==1 );
    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);













  }
  db_end_transaction(0);
  manifest_clear(&m);
  return 1;
}







|


|
>
>






<



>


<
<
<
|







|
>
|
>







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>





164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
....
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
      goto manifest_syntax_error;
    }
    cPrevType = z[0];
    seenHeader = 1;
    if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error;
    switch( z[0] ){
      /*
      **     A <filename> <target> ?<source>?
      **
      ** Identifies an attachment to either a wiki page or a ticket.
      ** <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( 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( !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)>0
         && (blob_size(&a3)!=UUID_SIZE || !validate16(zSrc, UUID_SIZE)) ){
          goto manifest_syntax_error;
        }
        p->zAttachName = zName;
        p->zAttachSrc = zSrc;
        p->zAttachTarget = zTarget;
        break;
      }

      /*
................................................................................
    if( !seenZ ) goto manifest_syntax_error;
    p->type = CFTYPE_CONTROL;
  }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;
    if( p->nField>0 ) goto manifest_syntax_error;
    if( p->zTicketUuid ) goto manifest_syntax_error;
................................................................................

    assert( manifest_crosslink_busy==1 );
    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.

320
321
322
323
324
325
326













327
328
329
330
331
332
333
@   target TEXT,           -- Where the hyperlink points to
@   srctype INT,           -- 0: check-in  1: ticket  2: wiki
@   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);













@
@ -- Template for the TICKET table
@ --
@ -- NB: when changing the schema of the TICKET table here, also make the
@ -- same change in tktsetup.c.
@ --
@ CREATE TABLE ticket(







>
>
>
>
>
>
>
>
>
>
>
>
>







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
@   target TEXT,           -- Where the hyperlink points to
@   srctype INT,           -- 0: check-in  1: ticket  2: wiki
@   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.
@ --
@ CREATE TABLE ticket(

Changes to www/fileformat.wiki.

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

An attachment artifact associates some other artifact that is the
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>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
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.

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
was applied.

................................................................................
<th>Cluster</th>
<th>Control</th>
<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>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td align=center><b>X</b></td>
</tr>







|







<
|

>
|
|







 







|







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401
402
403
404
...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

An attachment artifact associates some other artifact that is the
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> <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 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 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
was applied.

................................................................................
<th>Cluster</th>
<th>Control</th>
<th>Wiki</th>
<th>Ticket</th>
<th>Attachment</th>
</tr>
<tr>
<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>
<td align=center><b>X</b></td>
</tr>