Fossil SCM

Ticket enhancements: Add the TICKET.TKT_CTIME field and make it hold the creation time of the ticket. Make sure that a TICKETCHNG entry is created for each change to the ticket if the TICKETCHNG.TKT_RID field exists.

drh 2013-01-15 03:02 trunk
Commit 8554d3e6569c434609b01f87c5003a5330586c69
--- src/schema.c
+++ src/schema.c
@@ -385,10 +385,11 @@
385385
@ CREATE TABLE ticket(
386386
@ -- Do not change any column that begins with tkt_
387387
@ tkt_id INTEGER PRIMARY KEY,
388388
@ tkt_uuid TEXT UNIQUE,
389389
@ tkt_mtime DATE,
390
+@ tkt_ctime DATE,
390391
@ -- Add as many field as required below this line
391392
@ type TEXT,
392393
@ status TEXT,
393394
@ subsystem TEXT,
394395
@ priority TEXT,
395396
--- src/schema.c
+++ src/schema.c
@@ -385,10 +385,11 @@
385 @ CREATE TABLE ticket(
386 @ -- Do not change any column that begins with tkt_
387 @ tkt_id INTEGER PRIMARY KEY,
388 @ tkt_uuid TEXT UNIQUE,
389 @ tkt_mtime DATE,
 
390 @ -- Add as many field as required below this line
391 @ type TEXT,
392 @ status TEXT,
393 @ subsystem TEXT,
394 @ priority TEXT,
395
--- src/schema.c
+++ src/schema.c
@@ -385,10 +385,11 @@
385 @ CREATE TABLE ticket(
386 @ -- Do not change any column that begins with tkt_
387 @ tkt_id INTEGER PRIMARY KEY,
388 @ tkt_uuid TEXT UNIQUE,
389 @ tkt_mtime DATE,
390 @ tkt_ctime DATE,
391 @ -- Add as many field as required below this line
392 @ type TEXT,
393 @ status TEXT,
394 @ subsystem TEXT,
395 @ priority TEXT,
396
+16 -7
--- src/tkt.c
+++ src/tkt.c
@@ -35,13 +35,14 @@
3535
unsigned mUsed; /* 01: TICKET 02: TICKETCHNG */
3636
} *aField;
3737
#define USEDBY_TICKET 01
3838
#define USEDBY_TICKETCHNG 02
3939
#define USEDBY_BOTH 03
40
-static int haveTicket = 0; /* True if the TICKET table exists */
41
-static int haveTicketChng = 0; /* True if the TICKETCHNG table exists */
42
-static int haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
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 */
4344
4445
/*
4546
** Compare two entries in aField[] for sorting purposes
4647
*/
4748
static int nameCmpr(const void *a, const void *b){
@@ -76,11 +77,14 @@
7677
once = 1;
7778
db_prepare(&q, "PRAGMA table_info(ticket)");
7879
while( db_step(&q)==SQLITE_ROW ){
7980
const char *zFieldName = db_column_text(&q, 1);
8081
haveTicket = 1;
81
- if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
82
+ if( memcmp(zFieldName,"tkt_",4)==0 ){
83
+ if( strcmp(zFieldName, "tkt_ctime")==0 ) haveTicketCTime = 1;
84
+ continue;
85
+ }
8286
if( nField%10==0 ){
8387
aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
8488
}
8589
aField[nField].zName = mprintf("%s", zFieldName);
8690
aField[nField].mUsed = USEDBY_TICKET;
@@ -89,12 +93,14 @@
8993
db_finalize(&q);
9094
db_prepare(&q, "PRAGMA table_info(ticketchng)");
9195
while( db_step(&q)==SQLITE_ROW ){
9296
const char *zFieldName = db_column_text(&q, 1);
9397
haveTicketChng = 1;
94
- if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
95
- if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
98
+ if( memcmp(zFieldName,"tkt_",4)==0 ){
99
+ if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
100
+ continue;
101
+ }
96102
if( (i = fieldId(zFieldName))>=0 ){
97103
aField[i].mUsed |= USEDBY_TICKETCHNG;
98104
continue;
99105
}
100106
if( nField%10==0 ){
@@ -197,10 +203,13 @@
197203
}
198204
blob_zero(&sql1);
199205
blob_zero(&sql2);
200206
blob_zero(&sql3);
201207
blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
208
+ if( haveTicketCTime ){
209
+ blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
210
+ }
202211
aUsed = fossil_malloc( nField );
203212
memset(aUsed, 0, nField);
204213
for(i=0; i<p->nField; i++){
205214
const char *zName = p->aField[i].zName;
206215
if( (j = fieldId(zName))<0 ) continue;
@@ -226,11 +235,11 @@
226235
db_prepare(&q, "%s", blob_str(&sql1));
227236
db_bind_double(&q, ":mtime", p->rDate);
228237
db_step(&q);
229238
db_finalize(&q);
230239
blob_reset(&sql1);
231
- if( blob_size(&sql2)>0 ){
240
+ if( blob_size(&sql2)>0 || haveTicketChngRid ){
232241
int fromTkt = 0;
233242
if( haveTicketChngRid ){
234243
blob_append(&sql2, ",tkt_rid", -1);
235244
blob_appendf(&sql3, ",%d", rid);
236245
}
237246
--- src/tkt.c
+++ src/tkt.c
@@ -35,13 +35,14 @@
35 unsigned mUsed; /* 01: TICKET 02: TICKETCHNG */
36 } *aField;
37 #define USEDBY_TICKET 01
38 #define USEDBY_TICKETCHNG 02
39 #define USEDBY_BOTH 03
40 static int haveTicket = 0; /* True if the TICKET table exists */
41 static int haveTicketChng = 0; /* True if the TICKETCHNG table exists */
42 static int haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
 
43
44 /*
45 ** Compare two entries in aField[] for sorting purposes
46 */
47 static int nameCmpr(const void *a, const void *b){
@@ -76,11 +77,14 @@
76 once = 1;
77 db_prepare(&q, "PRAGMA table_info(ticket)");
78 while( db_step(&q)==SQLITE_ROW ){
79 const char *zFieldName = db_column_text(&q, 1);
80 haveTicket = 1;
81 if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
 
 
 
82 if( nField%10==0 ){
83 aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
84 }
85 aField[nField].zName = mprintf("%s", zFieldName);
86 aField[nField].mUsed = USEDBY_TICKET;
@@ -89,12 +93,14 @@
89 db_finalize(&q);
90 db_prepare(&q, "PRAGMA table_info(ticketchng)");
91 while( db_step(&q)==SQLITE_ROW ){
92 const char *zFieldName = db_column_text(&q, 1);
93 haveTicketChng = 1;
94 if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
95 if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
 
 
96 if( (i = fieldId(zFieldName))>=0 ){
97 aField[i].mUsed |= USEDBY_TICKETCHNG;
98 continue;
99 }
100 if( nField%10==0 ){
@@ -197,10 +203,13 @@
197 }
198 blob_zero(&sql1);
199 blob_zero(&sql2);
200 blob_zero(&sql3);
201 blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
 
 
 
202 aUsed = fossil_malloc( nField );
203 memset(aUsed, 0, nField);
204 for(i=0; i<p->nField; i++){
205 const char *zName = p->aField[i].zName;
206 if( (j = fieldId(zName))<0 ) continue;
@@ -226,11 +235,11 @@
226 db_prepare(&q, "%s", blob_str(&sql1));
227 db_bind_double(&q, ":mtime", p->rDate);
228 db_step(&q);
229 db_finalize(&q);
230 blob_reset(&sql1);
231 if( blob_size(&sql2)>0 ){
232 int fromTkt = 0;
233 if( haveTicketChngRid ){
234 blob_append(&sql2, ",tkt_rid", -1);
235 blob_appendf(&sql3, ",%d", rid);
236 }
237
--- src/tkt.c
+++ src/tkt.c
@@ -35,13 +35,14 @@
35 unsigned mUsed; /* 01: TICKET 02: TICKETCHNG */
36 } *aField;
37 #define USEDBY_TICKET 01
38 #define USEDBY_TICKETCHNG 02
39 #define USEDBY_BOTH 03
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
45 /*
46 ** Compare two entries in aField[] for sorting purposes
47 */
48 static int nameCmpr(const void *a, const void *b){
@@ -76,11 +77,14 @@
77 once = 1;
78 db_prepare(&q, "PRAGMA table_info(ticket)");
79 while( db_step(&q)==SQLITE_ROW ){
80 const char *zFieldName = db_column_text(&q, 1);
81 haveTicket = 1;
82 if( memcmp(zFieldName,"tkt_",4)==0 ){
83 if( strcmp(zFieldName, "tkt_ctime")==0 ) haveTicketCTime = 1;
84 continue;
85 }
86 if( nField%10==0 ){
87 aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
88 }
89 aField[nField].zName = mprintf("%s", zFieldName);
90 aField[nField].mUsed = USEDBY_TICKET;
@@ -89,12 +93,14 @@
93 db_finalize(&q);
94 db_prepare(&q, "PRAGMA table_info(ticketchng)");
95 while( db_step(&q)==SQLITE_ROW ){
96 const char *zFieldName = db_column_text(&q, 1);
97 haveTicketChng = 1;
98 if( memcmp(zFieldName,"tkt_",4)==0 ){
99 if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
100 continue;
101 }
102 if( (i = fieldId(zFieldName))>=0 ){
103 aField[i].mUsed |= USEDBY_TICKETCHNG;
104 continue;
105 }
106 if( nField%10==0 ){
@@ -197,10 +203,13 @@
203 }
204 blob_zero(&sql1);
205 blob_zero(&sql2);
206 blob_zero(&sql3);
207 blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
208 if( haveTicketCTime ){
209 blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
210 }
211 aUsed = fossil_malloc( nField );
212 memset(aUsed, 0, nField);
213 for(i=0; i<p->nField; i++){
214 const char *zName = p->aField[i].zName;
215 if( (j = fieldId(zName))<0 ) continue;
@@ -226,11 +235,11 @@
235 db_prepare(&q, "%s", blob_str(&sql1));
236 db_bind_double(&q, ":mtime", p->rDate);
237 db_step(&q);
238 db_finalize(&q);
239 blob_reset(&sql1);
240 if( blob_size(&sql2)>0 || haveTicketChngRid ){
241 int fromTkt = 0;
242 if( haveTicketChngRid ){
243 blob_append(&sql2, ",tkt_rid", -1);
244 blob_appendf(&sql3, ",%d", rid);
245 }
246
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -67,10 +67,11 @@
6767
@ CREATE TABLE ticket(
6868
@ -- Do not change any column that begins with tkt_
6969
@ tkt_id INTEGER PRIMARY KEY,
7070
@ tkt_uuid TEXT UNIQUE,
7171
@ tkt_mtime DATE,
72
+@ tkt_ctime DATE,
7273
@ -- Add as many fields as required below this line
7374
@ type TEXT,
7475
@ status TEXT,
7576
@ subsystem TEXT,
7677
@ priority TEXT,
7778
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -67,10 +67,11 @@
67 @ CREATE TABLE ticket(
68 @ -- Do not change any column that begins with tkt_
69 @ tkt_id INTEGER PRIMARY KEY,
70 @ tkt_uuid TEXT UNIQUE,
71 @ tkt_mtime DATE,
 
72 @ -- Add as many fields as required below this line
73 @ type TEXT,
74 @ status TEXT,
75 @ subsystem TEXT,
76 @ priority TEXT,
77
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -67,10 +67,11 @@
67 @ CREATE TABLE ticket(
68 @ -- Do not change any column that begins with tkt_
69 @ tkt_id INTEGER PRIMARY KEY,
70 @ tkt_uuid TEXT UNIQUE,
71 @ tkt_mtime DATE,
72 @ tkt_ctime DATE,
73 @ -- Add as many fields as required below this line
74 @ type TEXT,
75 @ status TEXT,
76 @ subsystem TEXT,
77 @ priority TEXT,
78

Keyboard Shortcuts

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