| ︙ | | | ︙ | |
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
#define USEDBY_TICKETCHNG 02
#define USEDBY_BOTH 03
static u8 haveTicket = 0; /* True if the TICKET table exists */
static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
static u8 haveTicketChngUser = 0;/* True if TICKETCHNG.TKT_USER 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);
|
>
|
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
#define USEDBY_TICKETCHNG 02
#define USEDBY_BOTH 03
static u8 haveTicket = 0; /* True if the TICKET table exists */
static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
static u8 haveTicketChngUser = 0;/* True if TICKETCHNG.TKT_USER exists */
static u8 haveTicketChngGenMt= 0;/* True if TICKETCHNG.MIMETYPE is generated */
/*
** 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);
|
| ︙ | | | ︙ | |
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
** in sorted order in aField[].
**
** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
** TICKETCHANGE tables exist, respectively.
*/
static void getAllTicketFields(void){
Stmt q;
int i;
static int once = 0;
if( once ) return;
once = 1;
db_prepare(&q, "PRAGMA table_info(ticket)");
while( db_step(&q)==SQLITE_ROW ){
const char *zFieldName = db_column_text(&q, 1);
haveTicket = 1;
|
|
|
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
** in sorted order in aField[].
**
** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
** TICKETCHANGE tables exist, respectively.
*/
static void getAllTicketFields(void){
Stmt q;
int i, bRegularMimetype = 0;
static int once = 0;
if( once ) return;
once = 1;
db_prepare(&q, "PRAGMA table_info(ticket)");
while( db_step(&q)==SQLITE_ROW ){
const char *zFieldName = db_column_text(&q, 1);
haveTicket = 1;
|
| ︙ | | | ︙ | |
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
if( memcmp(zFieldName,"tkt_",4)==0 ){
if( strcmp(zFieldName+4,"rid")==0 ){
haveTicketChngRid = 1; /* tkt_rid */
}else if( strcmp(zFieldName+4,"user")==0 ){
haveTicketChngUser = 1; /* tkt_user */
}
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) );
}
aField[nField].zName = mprintf("%s", zFieldName);
aField[nField].mUsed = USEDBY_TICKETCHNG;
nField++;
}
db_finalize(&q);
qsort(aField, nField, sizeof(aField[0]), nameCmpr);
for(i=0; i<nField; i++){
aField[i].zValue = "";
aField[i].zAppend = 0;
}
}
/*
** Query the database for all TICKET fields for the specific
** ticket whose name is given by the "name" CGI parameter.
** Load the values for all fields into the interpreter.
**
|
>
>
>
>
>
>
>
>
|
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
if( memcmp(zFieldName,"tkt_",4)==0 ){
if( strcmp(zFieldName+4,"rid")==0 ){
haveTicketChngRid = 1; /* tkt_rid */
}else if( strcmp(zFieldName+4,"user")==0 ){
haveTicketChngUser = 1; /* tkt_user */
}
continue;
}
if( strcmp(zFieldName,"mimetype")==0 ){
bRegularMimetype = 1;
}
if( (i = fieldId(zFieldName))>=0 ){
aField[i].mUsed |= USEDBY_TICKETCHNG;
continue;
}
if( nField%10==0 ){
aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
}
aField[nField].zName = mprintf("%s", zFieldName);
aField[nField].mUsed = USEDBY_TICKETCHNG;
nField++;
}
db_finalize(&q);
qsort(aField, nField, sizeof(aField[0]), nameCmpr);
for(i=0; i<nField; i++){
aField[i].zValue = "";
aField[i].zAppend = 0;
}
if( !bRegularMimetype &&
db_exists("SELECT 1 FROM pragma_table_xinfo('ticketchng') "
"WHERE name = 'mimetype'") ){
haveTicketChngGenMt = 1;
}
}
/*
** Query the database for all TICKET fields for the specific
** ticket whose name is given by the "name" CGI parameter.
** Load the values for all fields into the interpreter.
**
|
| ︙ | | | ︙ | |
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
** 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, 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;
const char *zMimetype = 0;
|
|
|
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
** 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;
const char *zMimetype = 0;
|
| ︙ | | | ︙ | |
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
|
}
}
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
blob_append_sql(&sql2, ",\"%w\"", zBaseName);
blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
}
if( strcmp(zBaseName,"mimetype")==0 ){
zMimetype = p->aField[i].zValue;
}
}
if( rid>0 ){
int bReplace = 1;
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;
backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
p->rDate, bReplace);
bReplace = 0;
}
}
blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
db_prepare(&q, "%s", blob_sql_text(&sql1));
db_bind_double(&q, ":mtime", p->rDate);
db_step(&q);
db_finalize(&q);
blob_reset(&sql1);
if( blob_size(&sql2)>0 || haveTicketChngRid || haveTicketChngUser ){
|
>
<
<
<
<
<
<
<
<
<
<
<
<
|
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
}
}
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
blob_append_sql(&sql2, ",\"%w\"", zBaseName);
blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
}
if( strcmp(zBaseName,"mimetype")==0 ){
assert(!haveTicketChngGenMt); /* aField is for regular columns */
zMimetype = p->aField[i].zValue;
}
}
blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
db_prepare(&q, "%s", blob_sql_text(&sql1));
db_bind_double(&q, ":mtime", p->rDate);
db_step(&q);
db_finalize(&q);
blob_reset(&sql1);
if( blob_size(&sql2)>0 || haveTicketChngRid || haveTicketChngUser ){
|
| ︙ | | | ︙ | |
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
fromTkt = 1;
blob_append_sql(&sql2, ",\"%w\"", z);
blob_append_sql(&sql3, ",\"%w\"", z);
}
}
if( fromTkt ){
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
"SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
blob_sql_text(&sql2), tktid,
blob_sql_text(&sql3), tktid);
}else{
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
"VALUES(%d,:mtime%s)",
blob_sql_text(&sql2), tktid, blob_sql_text(&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;
}
/*
** Returns non-zero if moderation is required for ticket changes and ticket
** attachments.
*/
|
|
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
fromTkt = 1;
blob_append_sql(&sql2, ",\"%w\"", z);
blob_append_sql(&sql3, ",\"%w\"", z);
}
}
if( fromTkt ){
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
"SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d%s",
blob_sql_text(&sql2), tktid,
blob_sql_text(&sql3), tktid,
haveTicketChngGenMt ? " RETURNING mimetype" : "");
}else{
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
"VALUES(%d,:mtime%s)%s",
blob_sql_text(&sql2), tktid, blob_sql_text(&sql3),
haveTicketChngGenMt ? " RETURNING mimetype" : "");
}
db_bind_double(&q, ":mtime", p->rDate);
db_step(&q);
if( haveTicketChngGenMt ){
zMimetype = db_column_malloc(&q, 0);
}
db_finalize(&q);
}
blob_reset(&sql2);
blob_reset(&sql3);
if( rid>0 ){
int bReplace = 1;
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 /*|| strcmp(zBaseName,"mimetype")==0*/ ) continue;
backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
p->rDate, bReplace);
bReplace = 0;
}
}
fossil_free(aUsed);
if( haveTicketChngGenMt && zMimetype ){
fossil_free((char*)zMimetype);
}
return tktid;
}
/*
** Returns non-zero if moderation is required for ticket changes and ticket
** attachments.
*/
|
| ︙ | | | ︙ | |