Fossil

Diff
Login

Differences From Artifact [d6f7e6001d]:

To Artifact [e294a1af8c]:


32
33
34
35
36
37
38

39
40

41
42
43
44
45
46
47
  char *zName;             /* Name of the database field */
  char *zValue;            /* Value to store */
  char *zAppend;           /* Value to append */
  unsigned mUsed;          /* 01: TICKET  02: TICKETCHNG */
} *aField;
#define USEDBY_TICKET      01
#define USEDBY_TICKETCHNG  02

static int haveTicket = 0;     /* True if the TICKET table exists */
static int haveTicketChng = 0; /* True if the TICKETCHNG table exists */


/*
** Compare two entries in aField[] for sorting purposes
*/
static int nameCmpr(const void *a, const void *b){
  return fossil_strcmp(((const struct tktFieldInfo*)a)->zName,
                       ((const struct tktFieldInfo*)b)->zName);







>


>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  char *zName;             /* Name of the database field */
  char *zValue;            /* Value to store */
  char *zAppend;           /* Value to append */
  unsigned mUsed;          /* 01: TICKET  02: TICKETCHNG */
} *aField;
#define USEDBY_TICKET      01
#define USEDBY_TICKETCHNG  02
#define USEDBY_BOTH        03
static int haveTicket = 0;     /* True if the TICKET table exists */
static int haveTicketChng = 0; /* True if the TICKETCHNG table exists */
static int haveTicketChngRid = 0;  /* True if TICKETCHNG.TKT_RID exists */

/*
** Compare two entries in aField[] for sorting purposes
*/
static int nameCmpr(const void *a, const void *b){
  return fossil_strcmp(((const struct tktFieldInfo*)a)->zName,
                       ((const struct tktFieldInfo*)b)->zName);
85
86
87
88
89
90
91

92
93
94
95
96
97
98
    nField++;
  }
  db_finalize(&q);
  db_prepare(&q, "PRAGMA table_info(ticketchng)");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFieldName = db_column_text(&q, 1);
    haveTicketChng = 1;

    if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
    if( (i = fieldId(zFieldName))>=0 ){
      aField[i].mUsed |= USEDBY_TICKETCHNG;
      continue;
    }
    if( nField%10==0 ){
      aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );







>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    nField++;
  }
  db_finalize(&q);
  db_prepare(&q, "PRAGMA table_info(ticketchng)");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFieldName = db_column_text(&q, 1);
    haveTicketChng = 1;
    if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
    if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
    if( (i = fieldId(zFieldName))>=0 ){
      aField[i].mUsed |= USEDBY_TICKETCHNG;
      continue;
    }
    if( nField%10==0 ){
      aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227















228




229
230

231
232
233
234
235
236

237
238
239
240
241
242
243
**
** Return the new rowid of the TICKET table entry.
*/
static int ticket_insert(const Manifest *p, int rid, int tktid){
  Blob sql1, sql2, sql3;
  Stmt q;
  int i, j;


  if( tktid==0 ){
    db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
                  "VALUES(%Q, 0)", p->zTicketUuid);
    tktid = db_last_insert_rowid();
  }
  blob_zero(&sql1);
  blob_zero(&sql2);
  blob_zero(&sql3);
  blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");


  for(i=0; i<p->nField; i++){
    const char *zName = p->aField[i].zName;
    if( zName[0]=='+' ){
      zName++;
      if( (j = fieldId(zName))<0 ) continue;

      if( aField[j].mUsed & USEDBY_TICKET ){


        blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
                     zName, zName, p->aField[i].zValue);
      }
    }else{
      if( (j = fieldId(zName))<0 ) continue;
      if( aField[j].mUsed & USEDBY_TICKET ){
        blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
      }
    }
    if( aField[j].mUsed & USEDBY_TICKETCHNG ){
      blob_appendf(&sql2, ",%s", zName);
      blob_appendf(&sql3, ",%Q", p->aField[i].zValue);
    }
    if( rid>0 ){
      wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
    }
  }
  blob_appendf(&sql1, " WHERE tkt_id=%d", tktid);
  db_prepare(&q, "%s", blob_str(&sql1));
  db_bind_double(&q, ":mtime", p->rDate);
  db_step(&q);
  db_finalize(&q);
  blob_reset(&sql1);
  if( blob_size(&sql2)>0 ){















    db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"




                   "VALUES(%d,:mtime%s)",
                  blob_str(&sql2), tktid, blob_str(&sql3));

    db_bind_double(&q, ":mtime", p->rDate);
    db_step(&q);
    db_finalize(&q);
  }
  blob_reset(&sql2);
  blob_reset(&sql3);

  return tktid;
}

/*
** Rebuild an entire entry in the TICKET table
*/
void ticket_rebuild_entry(const char *zTktUuid){







>










>
>


<
<
|
>
|
>
>


<
|
<
<


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
|
>






>







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205


206
207
208
209
210
211
212

213


214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
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
266
267
268
**
** Return the new rowid of the TICKET table entry.
*/
static int ticket_insert(const Manifest *p, int rid, int tktid){
  Blob sql1, sql2, sql3;
  Stmt q;
  int i, j;
  char *aUsed;

  if( tktid==0 ){
    db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
                  "VALUES(%Q, 0)", p->zTicketUuid);
    tktid = db_last_insert_rowid();
  }
  blob_zero(&sql1);
  blob_zero(&sql2);
  blob_zero(&sql3);
  blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
  aUsed = fossil_malloc( nField );
  memset(aUsed, 0, nField);
  for(i=0; i<p->nField; i++){
    const char *zName = p->aField[i].zName;


    if( (j = fieldId(zName))<0 ) continue;
    aUsed[j] = 1;
    if( aField[j].mUsed & USEDBY_TICKET ){
      if( zName[0]=='+' ){
        zName++;
        blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
                     zName, zName, p->aField[i].zValue);

      }else{


        blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
      }
    }
    if( aField[j].mUsed & USEDBY_TICKETCHNG ){
      blob_appendf(&sql2, ",%s", zName);
      blob_appendf(&sql3, ",%Q", p->aField[i].zValue);
    }
    if( rid>0 ){
      wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
    }
  }
  blob_appendf(&sql1, " WHERE tkt_id=%d", tktid);
  db_prepare(&q, "%s", blob_str(&sql1));
  db_bind_double(&q, ":mtime", p->rDate);
  db_step(&q);
  db_finalize(&q);
  blob_reset(&sql1);
  if( blob_size(&sql2)>0 ){
    int fromTkt = 0;
    if( haveTicketChngRid ){
      blob_append(&sql2, ",tkt_rid", -1);
      blob_appendf(&sql3, ",%d", rid);
    }
    for(i=0; i<nField; i++){
      if( aUsed[i]==0
       && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
      ){
        fromTkt = 1;
        blob_appendf(&sql2, ",%s", aField[i].zName);
        blob_appendf(&sql3, ",%s", aField[i].zName);
      }
    }
    if( fromTkt ){
      db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
                     "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
                     blob_str(&sql2), tktid, blob_str(&sql3), tktid);
    }else{
      db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
                     "VALUES(%d,:mtime%s)",
                     blob_str(&sql2), tktid, blob_str(&sql3));
    }
    db_bind_double(&q, ":mtime", p->rDate);
    db_step(&q);
    db_finalize(&q);
  }
  blob_reset(&sql2);
  blob_reset(&sql3);
  fossil_free(aUsed);
  return tktid;
}

/*
** Rebuild an entire entry in the TICKET table
*/
void ticket_rebuild_entry(const char *zTktUuid){
266
267
268
269
270
271
272

273
274
275
276
277
278
279
      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){
  const char *zConfig;
  Th_FossilInit(0, 0);







>







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
      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){
  const char *zConfig;
  Th_FossilInit(0, 0);
326
327
328
329
330
331
332






















333
334
335
336
337
338
339
    len = strlen(zName);
    if( len<20 || !validate16(zName, len) ) continue;
    ticket_rebuild_entry(zName);
  }
  db_finalize(&q);
  db_end_transaction(0);
}























/*
** For trouble-shooting purposes, render a dump of the aField[] table to
** the webpage currently under construction.
*/
static void showAllFields(void){
  int i;







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







352
353
354
355
356
357
358
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
387
    len = strlen(zName);
    if( len<20 || !validate16(zName, len) ) continue;
    ticket_rebuild_entry(zName);
  }
  db_finalize(&q);
  db_end_transaction(0);
}

/*
** COMMAND: test-ticket-rebuild
**
** Usage: %fossil test-ticket-rebuild TICKETID|all
**
** Rebuild the TICKET and TICKETCHNG tables for the given ticket ID
** or for ALL.
*/
void test_ticket_rebuild(void){
  db_find_and_open_repository(0, 0);
  if( g.argc!=3 ) usage("TICKETID|all");
  if( fossil_strcmp(g.argv[2], "all")==0 ){
    ticket_rebuild();
  }else{
    const char *zUuid;
    zUuid = db_text(0, "SELECT substr(tagname,5) FROM tag"
                       " WHERE tagname GLOB 'tkt-%q*'", g.argv[2]);
    if( zUuid==0 ) fossil_fatal("no such ticket: %s", g.argv[2]);
    ticket_rebuild_entry(zUuid);
  }
}

/*
** For trouble-shooting purposes, render a dump of the aField[] table to
** the webpage currently under construction.
*/
static void showAllFields(void){
  int i;