Fossil SCM

Rework the previous check-in to fix incorrect backlinks' sources for the case when values are appended to a field (i.e. a value of J-card starts with '+'). Consider a reference to 77ab05a0e9 from [caeb7d672df20] for an example which was handled incorrectly by [668e45baff99].

george 2022-10-09 22:56 deltify-tkt-blobs
Commit 4d5ded5eea57c709069682bb4d7babd6c1fa11a4ea8a5536488df47316bc0496
2 files changed +5 +34 -20
+5
--- src/blob.c
+++ src/blob.c
@@ -53,10 +53,15 @@
5353
/*
5454
** The buffer holding the blob data
5555
*/
5656
#define blob_buffer(X) ((X)->aData)
5757
58
+/*
59
+** Number of elements that fits into the current blob's size
60
+*/
61
+#define blob_count(X,elType) (blob_size(X)/sizeof(elType))
62
+
5863
/*
5964
** Append blob contents to another
6065
*/
6166
#define blob_appendb(dest, src) \
6267
blob_append((dest), blob_buffer(src), blob_size(src))
6368
--- src/blob.c
+++ src/blob.c
@@ -53,10 +53,15 @@
53 /*
54 ** The buffer holding the blob data
55 */
56 #define blob_buffer(X) ((X)->aData)
57
 
 
 
 
 
58 /*
59 ** Append blob contents to another
60 */
61 #define blob_appendb(dest, src) \
62 blob_append((dest), blob_buffer(src), blob_size(src))
63
--- src/blob.c
+++ src/blob.c
@@ -53,10 +53,15 @@
53 /*
54 ** The buffer holding the blob data
55 */
56 #define blob_buffer(X) ((X)->aData)
57
58 /*
59 ** Number of elements that fits into the current blob's size
60 */
61 #define blob_count(X,elType) (blob_size(X)/sizeof(elType))
62
63 /*
64 ** Append blob contents to another
65 */
66 #define blob_appendb(dest, src) \
67 blob_append((dest), blob_buffer(src), blob_size(src))
68
+34 -20
--- src/tkt.c
+++ src/tkt.c
@@ -232,11 +232,14 @@
232232
for(i=0; (z = cgi_parameter_name(i))!=0; i++){
233233
Th_Store(z, P(z));
234234
}
235235
}
236236
237
-struct TicketField {
237
+/*
238
+** Information about a single J-card
239
+*/
240
+struct jCardInfo {
238241
char *zValue;
239242
int mimetype;
240243
int rid;
241244
double mtime;
242245
};
@@ -250,11 +253,11 @@
250253
** Parameter rid is the recordID for the ticket artifact in the BLOB table.
251254
**
252255
** Return the new rowid of the TICKET table entry.
253256
*/
254257
static int ticket_insert(const Manifest *p, const int rid, int tktid,
255
- struct TicketField *fields){
258
+ Blob *fields){
256259
Blob sql1; /* update or replace TICKET ... */
257260
Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
258261
Blob sql3; /* list of values which correspond to the previous list */
259262
Stmt q;
260263
int i, j;
@@ -381,21 +384,24 @@
381384
rid, BKLNK_TICKET, p->rDate,
382385
/* existing backlinks must have been
383386
* already deleted by the caller */ 0 );
384387
}else{
385388
/* update field's data with the most recent values */
386
- struct TicketField *f = fields + j;
387
- char *zOld = f->zValue;
388
- if( zOld && zName[0]=='+' ){
389
- f->zValue = mprintf("%s%s", zOld, p->aField[i].zValue);
390
- }else{
391
- f->zValue = fossil_strdup(p->aField[i].zValue);
392
- }
393
- if( zOld ) fossil_free(zOld);
394
- f->mimetype = mimetype_tkt;
395
- f->rid = rid;
396
- f->mtime = p->rDate;
389
+ Blob *cards = fields + j;
390
+ struct jCardInfo card = {
391
+ fossil_strdup(p->aField[i].zValue),
392
+ mimetype_tkt, rid, p->rDate
393
+ };
394
+ if( blob_size(cards) && zName[0]!='+' ){
395
+ struct jCardInfo *x = (struct jCardInfo *)blob_buffer(cards);
396
+ struct jCardInfo *end = x + blob_count(cards,struct jCardInfo);
397
+ for(; x!=end; x++){
398
+ fossil_free( x->zValue );
399
+ }
400
+ blob_truncate(cards,0);
401
+ }
402
+ blob_append(cards, (const char*)(&card), sizeof(card));
397403
}
398404
}
399405
}
400406
return tktid;
401407
}
@@ -431,11 +437,11 @@
431437
int tagid = tag_findid(zTag, 1);
432438
Stmt q;
433439
Manifest *pTicket;
434440
int tktid, i;
435441
int createFlag = 1;
436
- struct TicketField *fields;
442
+ Blob *fields; /* array of blobs; each blob holds array of jCardInfo */
437443
438444
fossil_free(zTag);
439445
getAllTicketFields();
440446
if( haveTicket==0 ) return;
441447
tktid = db_int(0, "SELECT tkt_id FROM ticket WHERE tkt_uuid=%Q", zTktUuid);
@@ -443,11 +449,11 @@
443449
if( haveTicketChng ){
444450
db_multi_exec("DELETE FROM ticketchng WHERE tkt_id=%d;", tktid);
445451
}
446452
db_multi_exec("DELETE FROM ticket WHERE tkt_id=%d", tktid);
447453
tktid = 0;
448
- fields = fossil_malloc_zero( sizeof(fields[0]) * nField );
454
+ fields = blobarray_new( nField );
449455
db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid IN "
450456
"(SELECT rid FROM tagxref WHERE tagid=%d)",BKLNK_TICKET, tagid);
451457
db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
452458
while( db_step(&q)==SQLITE_ROW ){
453459
int rid = db_column_int(&q, 0);
@@ -460,16 +466,24 @@
460466
createFlag = 0;
461467
}
462468
db_finalize(&q);
463469
/* Extract backlinks from the most recent values of TICKET fields */
464470
for(i=0; i<nField; i++){
465
- struct TicketField *f = fields + i;
466
- if( f->zValue==0 ) continue;
467
- backlink_extract(f->zValue,f->mimetype,f->rid,BKLNK_TICKET,f->mtime,0);
468
- fossil_free(f->zValue);
471
+ Blob *cards = fields + i;
472
+ if( blob_size(cards) ){
473
+ struct jCardInfo *x = (struct jCardInfo *)blob_buffer(cards);
474
+ struct jCardInfo *end = x + blob_count(cards,struct jCardInfo);
475
+ for(; x!=end; x++){
476
+ assert( x->zValue );
477
+ backlink_extract(x->zValue,x->mimetype,
478
+ x->rid,BKLNK_TICKET,x->mtime,0);
479
+ fossil_free( x->zValue );
480
+ }
481
+ }
482
+ blob_truncate(cards,0);
469483
}
470
- fossil_free(fields);
484
+ blobarray_delete(fields,nField);
471485
}
472486
473487
474488
/*
475489
** Create the TH1 interpreter and load the "common" code.
476490
--- src/tkt.c
+++ src/tkt.c
@@ -232,11 +232,14 @@
232 for(i=0; (z = cgi_parameter_name(i))!=0; i++){
233 Th_Store(z, P(z));
234 }
235 }
236
237 struct TicketField {
 
 
 
238 char *zValue;
239 int mimetype;
240 int rid;
241 double mtime;
242 };
@@ -250,11 +253,11 @@
250 ** Parameter rid is the recordID for the ticket artifact in the BLOB table.
251 **
252 ** Return the new rowid of the TICKET table entry.
253 */
254 static int ticket_insert(const Manifest *p, const int rid, int tktid,
255 struct TicketField *fields){
256 Blob sql1; /* update or replace TICKET ... */
257 Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
258 Blob sql3; /* list of values which correspond to the previous list */
259 Stmt q;
260 int i, j;
@@ -381,21 +384,24 @@
381 rid, BKLNK_TICKET, p->rDate,
382 /* existing backlinks must have been
383 * already deleted by the caller */ 0 );
384 }else{
385 /* update field's data with the most recent values */
386 struct TicketField *f = fields + j;
387 char *zOld = f->zValue;
388 if( zOld && zName[0]=='+' ){
389 f->zValue = mprintf("%s%s", zOld, p->aField[i].zValue);
390 }else{
391 f->zValue = fossil_strdup(p->aField[i].zValue);
392 }
393 if( zOld ) fossil_free(zOld);
394 f->mimetype = mimetype_tkt;
395 f->rid = rid;
396 f->mtime = p->rDate;
 
 
 
397 }
398 }
399 }
400 return tktid;
401 }
@@ -431,11 +437,11 @@
431 int tagid = tag_findid(zTag, 1);
432 Stmt q;
433 Manifest *pTicket;
434 int tktid, i;
435 int createFlag = 1;
436 struct TicketField *fields;
437
438 fossil_free(zTag);
439 getAllTicketFields();
440 if( haveTicket==0 ) return;
441 tktid = db_int(0, "SELECT tkt_id FROM ticket WHERE tkt_uuid=%Q", zTktUuid);
@@ -443,11 +449,11 @@
443 if( haveTicketChng ){
444 db_multi_exec("DELETE FROM ticketchng WHERE tkt_id=%d;", tktid);
445 }
446 db_multi_exec("DELETE FROM ticket WHERE tkt_id=%d", tktid);
447 tktid = 0;
448 fields = fossil_malloc_zero( sizeof(fields[0]) * nField );
449 db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid IN "
450 "(SELECT rid FROM tagxref WHERE tagid=%d)",BKLNK_TICKET, tagid);
451 db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
452 while( db_step(&q)==SQLITE_ROW ){
453 int rid = db_column_int(&q, 0);
@@ -460,16 +466,24 @@
460 createFlag = 0;
461 }
462 db_finalize(&q);
463 /* Extract backlinks from the most recent values of TICKET fields */
464 for(i=0; i<nField; i++){
465 struct TicketField *f = fields + i;
466 if( f->zValue==0 ) continue;
467 backlink_extract(f->zValue,f->mimetype,f->rid,BKLNK_TICKET,f->mtime,0);
468 fossil_free(f->zValue);
 
 
 
 
 
 
 
 
469 }
470 fossil_free(fields);
471 }
472
473
474 /*
475 ** Create the TH1 interpreter and load the "common" code.
476
--- src/tkt.c
+++ src/tkt.c
@@ -232,11 +232,14 @@
232 for(i=0; (z = cgi_parameter_name(i))!=0; i++){
233 Th_Store(z, P(z));
234 }
235 }
236
237 /*
238 ** Information about a single J-card
239 */
240 struct jCardInfo {
241 char *zValue;
242 int mimetype;
243 int rid;
244 double mtime;
245 };
@@ -250,11 +253,11 @@
253 ** Parameter rid is the recordID for the ticket artifact in the BLOB table.
254 **
255 ** Return the new rowid of the TICKET table entry.
256 */
257 static int ticket_insert(const Manifest *p, const int rid, int tktid,
258 Blob *fields){
259 Blob sql1; /* update or replace TICKET ... */
260 Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
261 Blob sql3; /* list of values which correspond to the previous list */
262 Stmt q;
263 int i, j;
@@ -381,21 +384,24 @@
384 rid, BKLNK_TICKET, p->rDate,
385 /* existing backlinks must have been
386 * already deleted by the caller */ 0 );
387 }else{
388 /* update field's data with the most recent values */
389 Blob *cards = fields + j;
390 struct jCardInfo card = {
391 fossil_strdup(p->aField[i].zValue),
392 mimetype_tkt, rid, p->rDate
393 };
394 if( blob_size(cards) && zName[0]!='+' ){
395 struct jCardInfo *x = (struct jCardInfo *)blob_buffer(cards);
396 struct jCardInfo *end = x + blob_count(cards,struct jCardInfo);
397 for(; x!=end; x++){
398 fossil_free( x->zValue );
399 }
400 blob_truncate(cards,0);
401 }
402 blob_append(cards, (const char*)(&card), sizeof(card));
403 }
404 }
405 }
406 return tktid;
407 }
@@ -431,11 +437,11 @@
437 int tagid = tag_findid(zTag, 1);
438 Stmt q;
439 Manifest *pTicket;
440 int tktid, i;
441 int createFlag = 1;
442 Blob *fields; /* array of blobs; each blob holds array of jCardInfo */
443
444 fossil_free(zTag);
445 getAllTicketFields();
446 if( haveTicket==0 ) return;
447 tktid = db_int(0, "SELECT tkt_id FROM ticket WHERE tkt_uuid=%Q", zTktUuid);
@@ -443,11 +449,11 @@
449 if( haveTicketChng ){
450 db_multi_exec("DELETE FROM ticketchng WHERE tkt_id=%d;", tktid);
451 }
452 db_multi_exec("DELETE FROM ticket WHERE tkt_id=%d", tktid);
453 tktid = 0;
454 fields = blobarray_new( nField );
455 db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid IN "
456 "(SELECT rid FROM tagxref WHERE tagid=%d)",BKLNK_TICKET, tagid);
457 db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
458 while( db_step(&q)==SQLITE_ROW ){
459 int rid = db_column_int(&q, 0);
@@ -460,16 +466,24 @@
466 createFlag = 0;
467 }
468 db_finalize(&q);
469 /* Extract backlinks from the most recent values of TICKET fields */
470 for(i=0; i<nField; i++){
471 Blob *cards = fields + i;
472 if( blob_size(cards) ){
473 struct jCardInfo *x = (struct jCardInfo *)blob_buffer(cards);
474 struct jCardInfo *end = x + blob_count(cards,struct jCardInfo);
475 for(; x!=end; x++){
476 assert( x->zValue );
477 backlink_extract(x->zValue,x->mimetype,
478 x->rid,BKLNK_TICKET,x->mtime,0);
479 fossil_free( x->zValue );
480 }
481 }
482 blob_truncate(cards,0);
483 }
484 blobarray_delete(fields,nField);
485 }
486
487
488 /*
489 ** Create the TH1 interpreter and load the "common" code.
490

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button