Fossil

Check-in Differences
Login

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

Difference From 6a5604f481d04426 To 4d5ded5eea57c709

2022-10-16
00:09
Highlight a ticket's change that corresponds to the URL's fragment of the /tkthistory page. ... (check-in: 7afd4db3 user: george tags: deltify-tkt-blobs)
2022-10-09
22:56
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]. ... (check-in: 4d5ded5e user: george tags: deltify-tkt-blobs)
2022-10-03
01:41
Fix redundant back-references originating from outdated/superseded values within TICKET table. See forum thread a6ba08e926. ... (check-in: 668e45ba user: george tags: deltify-tkt-blobs)
01:31
Fix naming of columns on the /test-backlinks page. ... (check-in: 6a5604f4 user: george tags: deltify-tkt-blobs)
2022-09-20
14:13
On the /tkthistory page supply each ticket change item with a corresponding id attribute and make the 'History' button within a submenu of a /tinfo page to link back to that particular element on the /tkthistory page. ... (check-in: 4bb91f38 user: george tags: deltify-tkt-blobs)

Changes to src/blob.c.
51
52
53
54
55
56
57





58
59
60
61
62
63
64
#define blob_size(X)  ((X)->nUsed)

/*
** The buffer holding the blob data
*/
#define blob_buffer(X)  ((X)->aData)






/*
** Append blob contents to another
*/
#define blob_appendb(dest, src) \
  blob_append((dest), blob_buffer(src), blob_size(src))

/*







>
>
>
>
>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#define blob_size(X)  ((X)->nUsed)

/*
** The buffer holding the blob data
*/
#define blob_buffer(X)  ((X)->aData)

/*
** Number of elements that fits into the current blob's size
*/
#define blob_count(X,elType)  (blob_size(X)/sizeof(elType))

/*
** Append blob contents to another
*/
#define blob_appendb(dest, src) \
  blob_append((dest), blob_buffer(src), blob_size(src))

/*
Changes to src/tkt.c.
230
231
232
233
234
235
236










237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
  const char *z;

  for(i=0; (z = cgi_parameter_name(i))!=0; i++){
    Th_Store(z, P(z));
  }
}











/*
** Update an entry of the TICKET and TICKETCHNG tables according to the
** information in the ticket artifact given in p.  Attempt to create
** the appropriate TICKET table entry if tktid is zero.  If tktid is nonzero
** then it will be the ROWID of an existing TICKET entry.
**
** Parameter rid is the recordID for the ticket artifact in the BLOB table.
**
** Return the new rowid of the TICKET table entry.
*/
static int ticket_insert(const Manifest *p, const int rid, int tktid){

  Blob sql1; /* update or replace TICKET ... */
  Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
  Blob sql3; /* list of values which correspond to the previous list */
  Stmt q;
  int i, j;
  char *aUsed;
  int mimetype_tkt = MT_NONE, mimetype_tktchng = MT_NONE;







>
>
>
>
>
>
>
>
>
>










|
>







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  const char *z;

  for(i=0; (z = cgi_parameter_name(i))!=0; i++){
    Th_Store(z, P(z));
  }
}

/*
** Information about a single J-card
*/
struct jCardInfo {
  char  *zValue;
  int    mimetype;
  int    rid;
  double mtime;
};

/*
** Update an entry of the TICKET and TICKETCHNG tables according to the
** information in the ticket artifact given in p.  Attempt to create
** the appropriate TICKET table entry if tktid is zero.  If tktid is nonzero
** then it will be the ROWID of an existing TICKET entry.
**
** Parameter rid is the recordID for the ticket artifact in the BLOB table.
**
** Return the new rowid of the TICKET table entry.
*/
static int ticket_insert(const Manifest *p, const int rid, int tktid,
                         Blob *fields){
  Blob sql1; /* update or replace TICKET ... */
  Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
  Blob sql3; /* list of values which correspond to the previous list */
  Stmt q;
  int i, j;
  char *aUsed;
  int mimetype_tkt = MT_NONE, mimetype_tktchng = MT_NONE;
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373



374




375
376




377

378
379



380
381
382
383
384
385
386
    }
    db_finalize(&q);
  }
  blob_reset(&sql2);
  blob_reset(&sql3);
  fossil_free(aUsed);
  if( rid>0 ){                   /* extract backlinks */
    int bReplace = 1, mimetype;
    for(i=0; i<p->nField; i++){
      const char *zName = p->aField[i].zName;
      const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
      j = fieldId(zBaseName);
      if( j<0 ) continue;
      if( aField[j].mUsed & USEDBY_TICKETCHNG ){
        mimetype = mimetype_tktchng;



      }else{




        mimetype = mimetype_tkt;
      }




      backlink_extract(p->aField[i].zValue, mimetype, rid, BKLNK_TICKET,

                       p->rDate, bReplace);
      bReplace = 0;



    }
  }
  return tktid;
}

/*
** Returns non-zero if moderation is required for ticket changes and ticket







<






|
>
>
>

>
>
>
>
|
|
>
>
>
>
|
>
|
<
>
>
>







370
371
372
373
374
375
376

377
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
405
406
407
408
409
410
    }
    db_finalize(&q);
  }
  blob_reset(&sql2);
  blob_reset(&sql3);
  fossil_free(aUsed);
  if( rid>0 ){                   /* extract backlinks */

    for(i=0; i<p->nField; i++){
      const char *zName = p->aField[i].zName;
      const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
      j = fieldId(zBaseName);
      if( j<0 ) continue;
      if( aField[j].mUsed & USEDBY_TICKETCHNG ){
        backlink_extract(p->aField[i].zValue, mimetype_tktchng,
                         rid, BKLNK_TICKET, p->rDate,
                          /* existing backlinks must have been
                           * already deleted by the caller */ 0 );
      }else{
        /* update field's data with the most recent values */
        Blob *cards = fields + j;
        struct jCardInfo card = {
          fossil_strdup(p->aField[i].zValue),
          mimetype_tkt, rid, p->rDate
        };
        if( blob_size(cards) && zName[0]!='+' ){
          struct jCardInfo *x = (struct jCardInfo *)blob_buffer(cards);
          struct jCardInfo *end = x + blob_count(cards,struct jCardInfo);
          for(; x!=end; x++){
            fossil_free( x->zValue );
          }
          blob_truncate(cards,0);

        }
        blob_append(cards, (const char*)(&card), sizeof(card));
      }
    }
  }
  return tktid;
}

/*
** Returns non-zero if moderation is required for ticket changes and ticket
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425
426
427
428



429
430
431
432
433
434
435
436
437
438
439
440
















441
442
443
444
445
446
447
** Rebuild an entire entry in the TICKET table
*/
void ticket_rebuild_entry(const char *zTktUuid){
  char *zTag = mprintf("tkt-%s", zTktUuid);
  int tagid = tag_findid(zTag, 1);
  Stmt q;
  Manifest *pTicket;
  int tktid;
  int createFlag = 1;


  fossil_free(zTag);
  getAllTicketFields();
  if( haveTicket==0 ) return;
  tktid = db_int(0, "SELECT tkt_id FROM ticket WHERE tkt_uuid=%Q", zTktUuid);
  search_doc_touch('t', tktid, 0);
  if( haveTicketChng ){
    db_multi_exec("DELETE FROM ticketchng WHERE tkt_id=%d;", tktid);
  }
  db_multi_exec("DELETE FROM ticket WHERE tkt_id=%d", tktid);
  tktid = 0;



  db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    pTicket = manifest_get(rid, CFTYPE_TICKET, 0);
    if( pTicket ){
      tktid = ticket_insert(pTicket, rid, tktid);
      manifest_ticket_event(rid, pTicket, createFlag, tagid);
      manifest_destroy(pTicket);
    }
    createFlag = 0;
  }
  db_finalize(&q);
















}


/*
** Create the TH1 interpreter and load the "common" code.
*/
void ticket_init(void){







|

>











>
>
>





|






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







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
** Rebuild an entire entry in the TICKET table
*/
void ticket_rebuild_entry(const char *zTktUuid){
  char *zTag = mprintf("tkt-%s", zTktUuid);
  int tagid = tag_findid(zTag, 1);
  Stmt q;
  Manifest *pTicket;
  int tktid, i;
  int createFlag = 1;
  Blob *fields;  /* array of blobs; each blob holds array of jCardInfo */

  fossil_free(zTag);
  getAllTicketFields();
  if( haveTicket==0 ) return;
  tktid = db_int(0, "SELECT tkt_id FROM ticket WHERE tkt_uuid=%Q", zTktUuid);
  search_doc_touch('t', tktid, 0);
  if( haveTicketChng ){
    db_multi_exec("DELETE FROM ticketchng WHERE tkt_id=%d;", tktid);
  }
  db_multi_exec("DELETE FROM ticket WHERE tkt_id=%d", tktid);
  tktid = 0;
  fields = blobarray_new( nField );
  db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid IN "
                "(SELECT rid FROM tagxref WHERE tagid=%d)",BKLNK_TICKET, tagid);
  db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    pTicket = manifest_get(rid, CFTYPE_TICKET, 0);
    if( pTicket ){
      tktid = ticket_insert(pTicket, rid, tktid, fields);
      manifest_ticket_event(rid, pTicket, createFlag, tagid);
      manifest_destroy(pTicket);
    }
    createFlag = 0;
  }
  db_finalize(&q);
  /* Extract backlinks from the most recent values of TICKET fields */
  for(i=0; i<nField; i++){
    Blob *cards = fields + i;
    if( blob_size(cards) ){
      struct jCardInfo *x = (struct jCardInfo *)blob_buffer(cards);
      struct jCardInfo *end = x + blob_count(cards,struct jCardInfo);
      for(; x!=end; x++){
        assert( x->zValue );
        backlink_extract(x->zValue,x->mimetype,
                         x->rid,BKLNK_TICKET,x->mtime,0);
        fossil_free( x->zValue );
      }
    }
    blob_truncate(cards,0);
  }
  blobarray_delete(fields,nField);
}


/*
** Create the TH1 interpreter and load the "common" code.
*/
void ticket_init(void){