Fossil SCM

Fix redundant back-references originating from outdated/superseded values within TICKET table. See forum thread [forum:/forumthread/a6ba08e926a8cfdf|a6ba08e926].

george 2022-10-03 01:41 deltify-tkt-blobs
Commit 668e45baff990c0779cf54b54d367519991691b9023f80b99e1e296de0134c2d
1 file changed +39 -9
+39 -9
--- src/tkt.c
+++ src/tkt.c
@@ -232,10 +232,17 @@
232232
for(i=0; (z = cgi_parameter_name(i))!=0; i++){
233233
Th_Store(z, P(z));
234234
}
235235
}
236236
237
+struct TicketField {
238
+ char *zValue;
239
+ int mimetype;
240
+ int rid;
241
+ double mtime;
242
+};
243
+
237244
/*
238245
** Update an entry of the TICKET and TICKETCHNG tables according to the
239246
** information in the ticket artifact given in p. Attempt to create
240247
** the appropriate TICKET table entry if tktid is zero. If tktid is nonzero
241248
** then it will be the ROWID of an existing TICKET entry.
@@ -242,11 +249,12 @@
242249
**
243250
** Parameter rid is the recordID for the ticket artifact in the BLOB table.
244251
**
245252
** Return the new rowid of the TICKET table entry.
246253
*/
247
-static int ticket_insert(const Manifest *p, const int rid, int tktid){
254
+static int ticket_insert(const Manifest *p, const int rid, int tktid,
255
+ struct TicketField *fields){
248256
Blob sql1; /* update or replace TICKET ... */
249257
Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
250258
Blob sql3; /* list of values which correspond to the previous list */
251259
Stmt q;
252260
int i, j;
@@ -361,24 +369,34 @@
361369
}
362370
blob_reset(&sql2);
363371
blob_reset(&sql3);
364372
fossil_free(aUsed);
365373
if( rid>0 ){ /* extract backlinks */
366
- int bReplace = 1, mimetype;
367374
for(i=0; i<p->nField; i++){
368375
const char *zName = p->aField[i].zName;
369376
const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
370377
j = fieldId(zBaseName);
371378
if( j<0 ) continue;
372379
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
373
- mimetype = mimetype_tktchng;
380
+ backlink_extract(p->aField[i].zValue, mimetype_tktchng,
381
+ rid, BKLNK_TICKET, p->rDate,
382
+ /* existing backlinks must have been
383
+ * already deleted by the caller */ 0 );
374384
}else{
375
- mimetype = mimetype_tkt;
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;
376397
}
377
- backlink_extract(p->aField[i].zValue, mimetype, rid, BKLNK_TICKET,
378
- p->rDate, bReplace);
379
- bReplace = 0;
380398
}
381399
}
382400
return tktid;
383401
}
384402
@@ -411,12 +429,13 @@
411429
void ticket_rebuild_entry(const char *zTktUuid){
412430
char *zTag = mprintf("tkt-%s", zTktUuid);
413431
int tagid = tag_findid(zTag, 1);
414432
Stmt q;
415433
Manifest *pTicket;
416
- int tktid;
434
+ int tktid, i;
417435
int createFlag = 1;
436
+ struct TicketField *fields;
418437
419438
fossil_free(zTag);
420439
getAllTicketFields();
421440
if( haveTicket==0 ) return;
422441
tktid = db_int(0, "SELECT tkt_id FROM ticket WHERE tkt_uuid=%Q", zTktUuid);
@@ -424,22 +443,33 @@
424443
if( haveTicketChng ){
425444
db_multi_exec("DELETE FROM ticketchng WHERE tkt_id=%d;", tktid);
426445
}
427446
db_multi_exec("DELETE FROM ticket WHERE tkt_id=%d", tktid);
428447
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);
429451
db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
430452
while( db_step(&q)==SQLITE_ROW ){
431453
int rid = db_column_int(&q, 0);
432454
pTicket = manifest_get(rid, CFTYPE_TICKET, 0);
433455
if( pTicket ){
434
- tktid = ticket_insert(pTicket, rid, tktid);
456
+ tktid = ticket_insert(pTicket, rid, tktid, fields);
435457
manifest_ticket_event(rid, pTicket, createFlag, tagid);
436458
manifest_destroy(pTicket);
437459
}
438460
createFlag = 0;
439461
}
440462
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);
441471
}
442472
443473
444474
/*
445475
** Create the TH1 interpreter and load the "common" code.
446476
--- src/tkt.c
+++ src/tkt.c
@@ -232,10 +232,17 @@
232 for(i=0; (z = cgi_parameter_name(i))!=0; i++){
233 Th_Store(z, P(z));
234 }
235 }
236
 
 
 
 
 
 
 
237 /*
238 ** Update an entry of the TICKET and TICKETCHNG tables according to the
239 ** information in the ticket artifact given in p. Attempt to create
240 ** the appropriate TICKET table entry if tktid is zero. If tktid is nonzero
241 ** then it will be the ROWID of an existing TICKET entry.
@@ -242,11 +249,12 @@
242 **
243 ** Parameter rid is the recordID for the ticket artifact in the BLOB table.
244 **
245 ** Return the new rowid of the TICKET table entry.
246 */
247 static int ticket_insert(const Manifest *p, const int rid, int tktid){
 
248 Blob sql1; /* update or replace TICKET ... */
249 Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
250 Blob sql3; /* list of values which correspond to the previous list */
251 Stmt q;
252 int i, j;
@@ -361,24 +369,34 @@
361 }
362 blob_reset(&sql2);
363 blob_reset(&sql3);
364 fossil_free(aUsed);
365 if( rid>0 ){ /* extract backlinks */
366 int bReplace = 1, mimetype;
367 for(i=0; i<p->nField; i++){
368 const char *zName = p->aField[i].zName;
369 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
370 j = fieldId(zBaseName);
371 if( j<0 ) continue;
372 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
373 mimetype = mimetype_tktchng;
 
 
 
374 }else{
375 mimetype = mimetype_tkt;
 
 
 
 
 
 
 
 
 
 
 
376 }
377 backlink_extract(p->aField[i].zValue, mimetype, rid, BKLNK_TICKET,
378 p->rDate, bReplace);
379 bReplace = 0;
380 }
381 }
382 return tktid;
383 }
384
@@ -411,12 +429,13 @@
411 void ticket_rebuild_entry(const char *zTktUuid){
412 char *zTag = mprintf("tkt-%s", zTktUuid);
413 int tagid = tag_findid(zTag, 1);
414 Stmt q;
415 Manifest *pTicket;
416 int tktid;
417 int createFlag = 1;
 
418
419 fossil_free(zTag);
420 getAllTicketFields();
421 if( haveTicket==0 ) return;
422 tktid = db_int(0, "SELECT tkt_id FROM ticket WHERE tkt_uuid=%Q", zTktUuid);
@@ -424,22 +443,33 @@
424 if( haveTicketChng ){
425 db_multi_exec("DELETE FROM ticketchng WHERE tkt_id=%d;", tktid);
426 }
427 db_multi_exec("DELETE FROM ticket WHERE tkt_id=%d", tktid);
428 tktid = 0;
 
 
 
429 db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
430 while( db_step(&q)==SQLITE_ROW ){
431 int rid = db_column_int(&q, 0);
432 pTicket = manifest_get(rid, CFTYPE_TICKET, 0);
433 if( pTicket ){
434 tktid = ticket_insert(pTicket, rid, tktid);
435 manifest_ticket_event(rid, pTicket, createFlag, tagid);
436 manifest_destroy(pTicket);
437 }
438 createFlag = 0;
439 }
440 db_finalize(&q);
 
 
 
 
 
 
 
 
441 }
442
443
444 /*
445 ** Create the TH1 interpreter and load the "common" code.
446
--- src/tkt.c
+++ src/tkt.c
@@ -232,10 +232,17 @@
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 };
243
244 /*
245 ** Update an entry of the TICKET and TICKETCHNG tables according to the
246 ** information in the ticket artifact given in p. Attempt to create
247 ** the appropriate TICKET table entry if tktid is zero. If tktid is nonzero
248 ** then it will be the ROWID of an existing TICKET entry.
@@ -242,11 +249,12 @@
249 **
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;
@@ -361,24 +369,34 @@
369 }
370 blob_reset(&sql2);
371 blob_reset(&sql3);
372 fossil_free(aUsed);
373 if( rid>0 ){ /* extract backlinks */
 
374 for(i=0; i<p->nField; i++){
375 const char *zName = p->aField[i].zName;
376 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
377 j = fieldId(zBaseName);
378 if( j<0 ) continue;
379 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
380 backlink_extract(p->aField[i].zValue, mimetype_tktchng,
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 }
402
@@ -411,12 +429,13 @@
429 void ticket_rebuild_entry(const char *zTktUuid){
430 char *zTag = mprintf("tkt-%s", zTktUuid);
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);
@@ -424,22 +443,33 @@
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);
454 pTicket = manifest_get(rid, CFTYPE_TICKET, 0);
455 if( pTicket ){
456 tktid = ticket_insert(pTicket, rid, tktid, fields);
457 manifest_ticket_event(rid, pTicket, createFlag, tagid);
458 manifest_destroy(pTicket);
459 }
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

Keyboard Shortcuts

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