Fossil SCM

If "<var>mimetype</var>" column of the <var>TICKETCHNG</var> table is a [https://www.sqlite.org/gencol.html|generated column], than use these generated values for extraction of backlinks from the ticket-changes.

george 2022-05-14 18:27 generated-tkt-mimetype
Commit 5ab73ab8c7be3a0c6eba55843e95d68f4c72d219e1b31beb03b49de1e16a2ce8
1 file changed +36 -18
+36 -18
--- src/tkt.c
+++ src/tkt.c
@@ -40,10 +40,11 @@
4040
static u8 haveTicket = 0; /* True if the TICKET table exists */
4141
static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
4242
static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
4343
static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
4444
static u8 haveTicketChngUser = 0;/* True if TICKETCHNG.TKT_USER exists */
45
+static u8 haveTicketChngGenMt= 0;/* True if TICKETCHNG.MIMETYPE is generated */
4546
4647
/*
4748
** Compare two entries in aField[] for sorting purposes
4849
*/
4950
static int nameCmpr(const void *a, const void *b){
@@ -70,11 +71,11 @@
7071
** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
7172
** TICKETCHANGE tables exist, respectively.
7273
*/
7374
static void getAllTicketFields(void){
7475
Stmt q;
75
- int i;
76
+ int i, bRegularMimetype = 0;
7677
static int once = 0;
7778
if( once ) return;
7879
once = 1;
7980
db_prepare(&q, "PRAGMA table_info(ticket)");
8081
while( db_step(&q)==SQLITE_ROW ){
@@ -101,10 +102,13 @@
101102
haveTicketChngRid = 1; /* tkt_rid */
102103
}else if( strcmp(zFieldName+4,"user")==0 ){
103104
haveTicketChngUser = 1; /* tkt_user */
104105
}
105106
continue;
107
+ }
108
+ if( strcmp(zFieldName,"mimetype")==0 ){
109
+ bRegularMimetype = 1;
106110
}
107111
if( (i = fieldId(zFieldName))>=0 ){
108112
aField[i].mUsed |= USEDBY_TICKETCHNG;
109113
continue;
110114
}
@@ -119,10 +123,15 @@
119123
qsort(aField, nField, sizeof(aField[0]), nameCmpr);
120124
for(i=0; i<nField; i++){
121125
aField[i].zValue = "";
122126
aField[i].zAppend = 0;
123127
}
128
+ if( !bRegularMimetype &&
129
+ db_exists("SELECT 1 FROM pragma_table_xinfo('ticketchng') "
130
+ "WHERE name = 'mimetype'") ){
131
+ haveTicketChngGenMt = 1;
132
+ }
124133
}
125134
126135
/*
127136
** Query the database for all TICKET fields for the specific
128137
** ticket whose name is given by the "name" CGI parameter.
@@ -194,11 +203,11 @@
194203
**
195204
** Parameter rid is the recordID for the ticket artifact in the BLOB table.
196205
**
197206
** Return the new rowid of the TICKET table entry.
198207
*/
199
-static int ticket_insert(const Manifest *p, int rid, int tktid){
208
+static int ticket_insert(const Manifest *p, const int rid, int tktid){
200209
Blob sql1; /* update or replace TICKET ... */
201210
Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
202211
Blob sql3; /* list of values which correspond to the previous list */
203212
Stmt q;
204213
int i, j;
@@ -236,25 +245,14 @@
236245
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
237246
blob_append_sql(&sql2, ",\"%w\"", zBaseName);
238247
blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
239248
}
240249
if( strcmp(zBaseName,"mimetype")==0 ){
250
+ assert(!haveTicketChngGenMt); /* aField is for regular columns */
241251
zMimetype = p->aField[i].zValue;
242252
}
243253
}
244
- if( rid>0 ){
245
- int bReplace = 1;
246
- for(i=0; i<p->nField; i++){
247
- const char *zName = p->aField[i].zName;
248
- const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
249
- j = fieldId(zBaseName);
250
- if( j<0 ) continue;
251
- backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
252
- p->rDate, bReplace);
253
- bReplace = 0;
254
- }
255
- }
256254
blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
257255
db_prepare(&q, "%s", blob_sql_text(&sql1));
258256
db_bind_double(&q, ":mtime", p->rDate);
259257
db_step(&q);
260258
db_finalize(&q);
@@ -280,25 +278,45 @@
280278
blob_append_sql(&sql3, ",\"%w\"", z);
281279
}
282280
}
283281
if( fromTkt ){
284282
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
285
- "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
283
+ "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d%s",
286284
blob_sql_text(&sql2), tktid,
287
- blob_sql_text(&sql3), tktid);
285
+ blob_sql_text(&sql3), tktid,
286
+ haveTicketChngGenMt ? " RETURNING mimetype" : "");
288287
}else{
289288
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
290
- "VALUES(%d,:mtime%s)",
291
- blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
289
+ "VALUES(%d,:mtime%s)%s",
290
+ blob_sql_text(&sql2), tktid, blob_sql_text(&sql3),
291
+ haveTicketChngGenMt ? " RETURNING mimetype" : "");
292292
}
293293
db_bind_double(&q, ":mtime", p->rDate);
294294
db_step(&q);
295
+ if( haveTicketChngGenMt ){
296
+ zMimetype = db_column_malloc(&q, 0);
297
+ }
295298
db_finalize(&q);
296299
}
297300
blob_reset(&sql2);
298301
blob_reset(&sql3);
302
+ if( rid>0 ){
303
+ int bReplace = 1;
304
+ for(i=0; i<p->nField; i++){
305
+ const char *zName = p->aField[i].zName;
306
+ const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
307
+ j = fieldId(zBaseName);
308
+ if( j<0 /*|| strcmp(zBaseName,"mimetype")==0*/ ) continue;
309
+ backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
310
+ p->rDate, bReplace);
311
+ bReplace = 0;
312
+ }
313
+ }
299314
fossil_free(aUsed);
315
+ if( haveTicketChngGenMt && zMimetype ){
316
+ fossil_free((char*)zMimetype);
317
+ }
300318
return tktid;
301319
}
302320
303321
/*
304322
** Returns non-zero if moderation is required for ticket changes and ticket
305323
--- src/tkt.c
+++ src/tkt.c
@@ -40,10 +40,11 @@
40 static u8 haveTicket = 0; /* True if the TICKET table exists */
41 static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
42 static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
43 static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
44 static u8 haveTicketChngUser = 0;/* True if TICKETCHNG.TKT_USER exists */
 
45
46 /*
47 ** Compare two entries in aField[] for sorting purposes
48 */
49 static int nameCmpr(const void *a, const void *b){
@@ -70,11 +71,11 @@
70 ** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
71 ** TICKETCHANGE tables exist, respectively.
72 */
73 static void getAllTicketFields(void){
74 Stmt q;
75 int i;
76 static int once = 0;
77 if( once ) return;
78 once = 1;
79 db_prepare(&q, "PRAGMA table_info(ticket)");
80 while( db_step(&q)==SQLITE_ROW ){
@@ -101,10 +102,13 @@
101 haveTicketChngRid = 1; /* tkt_rid */
102 }else if( strcmp(zFieldName+4,"user")==0 ){
103 haveTicketChngUser = 1; /* tkt_user */
104 }
105 continue;
 
 
 
106 }
107 if( (i = fieldId(zFieldName))>=0 ){
108 aField[i].mUsed |= USEDBY_TICKETCHNG;
109 continue;
110 }
@@ -119,10 +123,15 @@
119 qsort(aField, nField, sizeof(aField[0]), nameCmpr);
120 for(i=0; i<nField; i++){
121 aField[i].zValue = "";
122 aField[i].zAppend = 0;
123 }
 
 
 
 
 
124 }
125
126 /*
127 ** Query the database for all TICKET fields for the specific
128 ** ticket whose name is given by the "name" CGI parameter.
@@ -194,11 +203,11 @@
194 **
195 ** Parameter rid is the recordID for the ticket artifact in the BLOB table.
196 **
197 ** Return the new rowid of the TICKET table entry.
198 */
199 static int ticket_insert(const Manifest *p, int rid, int tktid){
200 Blob sql1; /* update or replace TICKET ... */
201 Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
202 Blob sql3; /* list of values which correspond to the previous list */
203 Stmt q;
204 int i, j;
@@ -236,25 +245,14 @@
236 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
237 blob_append_sql(&sql2, ",\"%w\"", zBaseName);
238 blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
239 }
240 if( strcmp(zBaseName,"mimetype")==0 ){
 
241 zMimetype = p->aField[i].zValue;
242 }
243 }
244 if( rid>0 ){
245 int bReplace = 1;
246 for(i=0; i<p->nField; i++){
247 const char *zName = p->aField[i].zName;
248 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
249 j = fieldId(zBaseName);
250 if( j<0 ) continue;
251 backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
252 p->rDate, bReplace);
253 bReplace = 0;
254 }
255 }
256 blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
257 db_prepare(&q, "%s", blob_sql_text(&sql1));
258 db_bind_double(&q, ":mtime", p->rDate);
259 db_step(&q);
260 db_finalize(&q);
@@ -280,25 +278,45 @@
280 blob_append_sql(&sql3, ",\"%w\"", z);
281 }
282 }
283 if( fromTkt ){
284 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
285 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
286 blob_sql_text(&sql2), tktid,
287 blob_sql_text(&sql3), tktid);
 
288 }else{
289 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
290 "VALUES(%d,:mtime%s)",
291 blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
 
292 }
293 db_bind_double(&q, ":mtime", p->rDate);
294 db_step(&q);
 
 
 
295 db_finalize(&q);
296 }
297 blob_reset(&sql2);
298 blob_reset(&sql3);
 
 
 
 
 
 
 
 
 
 
 
 
299 fossil_free(aUsed);
 
 
 
300 return tktid;
301 }
302
303 /*
304 ** Returns non-zero if moderation is required for ticket changes and ticket
305
--- src/tkt.c
+++ src/tkt.c
@@ -40,10 +40,11 @@
40 static u8 haveTicket = 0; /* True if the TICKET table exists */
41 static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
42 static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
43 static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
44 static u8 haveTicketChngUser = 0;/* True if TICKETCHNG.TKT_USER exists */
45 static u8 haveTicketChngGenMt= 0;/* True if TICKETCHNG.MIMETYPE is generated */
46
47 /*
48 ** Compare two entries in aField[] for sorting purposes
49 */
50 static int nameCmpr(const void *a, const void *b){
@@ -70,11 +71,11 @@
71 ** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
72 ** TICKETCHANGE tables exist, respectively.
73 */
74 static void getAllTicketFields(void){
75 Stmt q;
76 int i, bRegularMimetype = 0;
77 static int once = 0;
78 if( once ) return;
79 once = 1;
80 db_prepare(&q, "PRAGMA table_info(ticket)");
81 while( db_step(&q)==SQLITE_ROW ){
@@ -101,10 +102,13 @@
102 haveTicketChngRid = 1; /* tkt_rid */
103 }else if( strcmp(zFieldName+4,"user")==0 ){
104 haveTicketChngUser = 1; /* tkt_user */
105 }
106 continue;
107 }
108 if( strcmp(zFieldName,"mimetype")==0 ){
109 bRegularMimetype = 1;
110 }
111 if( (i = fieldId(zFieldName))>=0 ){
112 aField[i].mUsed |= USEDBY_TICKETCHNG;
113 continue;
114 }
@@ -119,10 +123,15 @@
123 qsort(aField, nField, sizeof(aField[0]), nameCmpr);
124 for(i=0; i<nField; i++){
125 aField[i].zValue = "";
126 aField[i].zAppend = 0;
127 }
128 if( !bRegularMimetype &&
129 db_exists("SELECT 1 FROM pragma_table_xinfo('ticketchng') "
130 "WHERE name = 'mimetype'") ){
131 haveTicketChngGenMt = 1;
132 }
133 }
134
135 /*
136 ** Query the database for all TICKET fields for the specific
137 ** ticket whose name is given by the "name" CGI parameter.
@@ -194,11 +203,11 @@
203 **
204 ** Parameter rid is the recordID for the ticket artifact in the BLOB table.
205 **
206 ** Return the new rowid of the TICKET table entry.
207 */
208 static int ticket_insert(const Manifest *p, const int rid, int tktid){
209 Blob sql1; /* update or replace TICKET ... */
210 Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
211 Blob sql3; /* list of values which correspond to the previous list */
212 Stmt q;
213 int i, j;
@@ -236,25 +245,14 @@
245 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
246 blob_append_sql(&sql2, ",\"%w\"", zBaseName);
247 blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
248 }
249 if( strcmp(zBaseName,"mimetype")==0 ){
250 assert(!haveTicketChngGenMt); /* aField is for regular columns */
251 zMimetype = p->aField[i].zValue;
252 }
253 }
 
 
 
 
 
 
 
 
 
 
 
 
254 blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
255 db_prepare(&q, "%s", blob_sql_text(&sql1));
256 db_bind_double(&q, ":mtime", p->rDate);
257 db_step(&q);
258 db_finalize(&q);
@@ -280,25 +278,45 @@
278 blob_append_sql(&sql3, ",\"%w\"", z);
279 }
280 }
281 if( fromTkt ){
282 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
283 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d%s",
284 blob_sql_text(&sql2), tktid,
285 blob_sql_text(&sql3), tktid,
286 haveTicketChngGenMt ? " RETURNING mimetype" : "");
287 }else{
288 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
289 "VALUES(%d,:mtime%s)%s",
290 blob_sql_text(&sql2), tktid, blob_sql_text(&sql3),
291 haveTicketChngGenMt ? " RETURNING mimetype" : "");
292 }
293 db_bind_double(&q, ":mtime", p->rDate);
294 db_step(&q);
295 if( haveTicketChngGenMt ){
296 zMimetype = db_column_malloc(&q, 0);
297 }
298 db_finalize(&q);
299 }
300 blob_reset(&sql2);
301 blob_reset(&sql3);
302 if( rid>0 ){
303 int bReplace = 1;
304 for(i=0; i<p->nField; i++){
305 const char *zName = p->aField[i].zName;
306 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
307 j = fieldId(zBaseName);
308 if( j<0 /*|| strcmp(zBaseName,"mimetype")==0*/ ) continue;
309 backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
310 p->rDate, bReplace);
311 bReplace = 0;
312 }
313 }
314 fossil_free(aUsed);
315 if( haveTicketChngGenMt && zMimetype ){
316 fossil_free((char*)zMimetype);
317 }
318 return tktid;
319 }
320
321 /*
322 ** Returns non-zero if moderation is required for ticket changes and ticket
323

Keyboard Shortcuts

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