Fossil SCM

Turn tags into properties. Allow properties to control background color on timelines. Still experimental.

drh 2007-09-22 01:40 trunk
Commit 5e2392307d800c3fda2610e42f7b6fed545d1ff5
--- src/descendents.c
+++ src/descendents.c
@@ -196,11 +196,11 @@
196196
if( !g.okRead ){ login_needed(); return; }
197197
198198
style_header("Leaves");
199199
db_prepare(&q,
200200
"SELECT blob.rid, blob.uuid, datetime(event.mtime,'localtime'),"
201
- " event.comment, event.user, 1, 1, 0"
201
+ " event.comment, event.user, 1, 1, 0, NULL"
202202
" FROM blob, event"
203203
" WHERE blob.rid IN"
204204
" (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
205205
" AND event.objid=blob.rid"
206206
" ORDER BY event.mtime DESC"
207207
--- src/descendents.c
+++ src/descendents.c
@@ -196,11 +196,11 @@
196 if( !g.okRead ){ login_needed(); return; }
197
198 style_header("Leaves");
199 db_prepare(&q,
200 "SELECT blob.rid, blob.uuid, datetime(event.mtime,'localtime'),"
201 " event.comment, event.user, 1, 1, 0"
202 " FROM blob, event"
203 " WHERE blob.rid IN"
204 " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
205 " AND event.objid=blob.rid"
206 " ORDER BY event.mtime DESC"
207
--- src/descendents.c
+++ src/descendents.c
@@ -196,11 +196,11 @@
196 if( !g.okRead ){ login_needed(); return; }
197
198 style_header("Leaves");
199 db_prepare(&q,
200 "SELECT blob.rid, blob.uuid, datetime(event.mtime,'localtime'),"
201 " event.comment, event.user, 1, 1, 0, NULL"
202 " FROM blob, event"
203 " WHERE blob.rid IN"
204 " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
205 " AND event.objid=blob.rid"
206 " ORDER BY event.mtime DESC"
207
+6 -1
--- src/schema.c
+++ src/schema.c
@@ -200,20 +200,25 @@
200200
@ CREATE TABLE tag(
201201
@ tagid INTEGER PRIMARY KEY, -- Numeric tag ID
202202
@ tagname TEXT UNIQUE -- Tag name. Prefixed by 'v' or 'b'
203203
@ );
204204
@
205
-@ -- Assignments of tags to baselines
205
+@ -- Assignments of tags to baselines. Note that we allow tags to
206
+@ -- have values assigned to them. So we are not really dealing with
207
+@ -- tags here. These are really properties. But we are going to
208
+@ -- keep calling them tags because in many cases the value is ignored.
206209
@ --
207210
@ CREATE TABLE tagxref(
208211
@ tagid INTEGER REFERENCES tag, -- The tag that added or removed
209212
@ addFlag BOOLEAN, -- True to add the tag, False to remove
210213
@ srcid INTEGER REFERENCES blob, -- Origin of the tag. 0 for propagated tags
214
+@ value TEXT, -- Value of the tag. Might be NULL.
211215
@ mtime TIMESTAMP, -- Time of addition or removal
212216
@ rid INTEGER REFERENCE blob, -- Baseline that tag added/removed from
213217
@ UNIQUE(rid, tagid)
214218
@ );
219
+@ CREATE INDEX tagxref_i1 ON tagxref(tagid);
215220
;
216221
217222
/*
218223
** The schema for the locate FOSSIL database file found at the root
219224
** of very check-out. This database contains the complete state of
220225
--- src/schema.c
+++ src/schema.c
@@ -200,20 +200,25 @@
200 @ CREATE TABLE tag(
201 @ tagid INTEGER PRIMARY KEY, -- Numeric tag ID
202 @ tagname TEXT UNIQUE -- Tag name. Prefixed by 'v' or 'b'
203 @ );
204 @
205 @ -- Assignments of tags to baselines
 
 
 
206 @ --
207 @ CREATE TABLE tagxref(
208 @ tagid INTEGER REFERENCES tag, -- The tag that added or removed
209 @ addFlag BOOLEAN, -- True to add the tag, False to remove
210 @ srcid INTEGER REFERENCES blob, -- Origin of the tag. 0 for propagated tags
 
211 @ mtime TIMESTAMP, -- Time of addition or removal
212 @ rid INTEGER REFERENCE blob, -- Baseline that tag added/removed from
213 @ UNIQUE(rid, tagid)
214 @ );
 
215 ;
216
217 /*
218 ** The schema for the locate FOSSIL database file found at the root
219 ** of very check-out. This database contains the complete state of
220
--- src/schema.c
+++ src/schema.c
@@ -200,20 +200,25 @@
200 @ CREATE TABLE tag(
201 @ tagid INTEGER PRIMARY KEY, -- Numeric tag ID
202 @ tagname TEXT UNIQUE -- Tag name. Prefixed by 'v' or 'b'
203 @ );
204 @
205 @ -- Assignments of tags to baselines. Note that we allow tags to
206 @ -- have values assigned to them. So we are not really dealing with
207 @ -- tags here. These are really properties. But we are going to
208 @ -- keep calling them tags because in many cases the value is ignored.
209 @ --
210 @ CREATE TABLE tagxref(
211 @ tagid INTEGER REFERENCES tag, -- The tag that added or removed
212 @ addFlag BOOLEAN, -- True to add the tag, False to remove
213 @ srcid INTEGER REFERENCES blob, -- Origin of the tag. 0 for propagated tags
214 @ value TEXT, -- Value of the tag. Might be NULL.
215 @ mtime TIMESTAMP, -- Time of addition or removal
216 @ rid INTEGER REFERENCE blob, -- Baseline that tag added/removed from
217 @ UNIQUE(rid, tagid)
218 @ );
219 @ CREATE INDEX tagxref_i1 ON tagxref(tagid);
220 ;
221
222 /*
223 ** The schema for the locate FOSSIL database file found at the root
224 ** of very check-out. This database contains the complete state of
225
+67 -10
--- src/tag.c
+++ src/tag.c
@@ -35,31 +35,33 @@
3535
**
3636
** If addFlag is true then the tag is added. If false, then the
3737
** tag is removed.
3838
*/
3939
void tag_propagate(
40
- int pid, /* Propagate the tag to children of this node */
41
- int tagid, /* Tag to propagate */
42
- int addFlag, /* True to add the tag. False to delete it. */
43
- double mtime /* Timestamp on the tag */
40
+ int pid, /* Propagate the tag to children of this node */
41
+ int tagid, /* Tag to propagate */
42
+ int addFlag, /* True to add the tag. False to delete it. */
43
+ const char *zValue, /* Value of the tag. Might be NULL */
44
+ double mtime /* Timestamp on the tag */
4445
){
4546
PQueue queue;
4647
Stmt s, ins;
4748
pqueue_init(&queue);
4849
pqueue_insert(&queue, pid, 0.0);
4950
db_prepare(&s,
50
- "SELECT cid, mtime, coalesce(srcid=0 AND mtime<:mtime, %d) AS doit"
51
+ "SELECT cid, plink.mtime,"
52
+ " coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit"
5153
" FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
5254
" WHERE pid=:pid AND isprim",
5355
addFlag, tagid
5456
);
5557
db_bind_double(&s, ":mtime", mtime);
5658
if( addFlag ){
5759
db_prepare(&ins,
58
- "REPLACE INTO tagxref(tagid, addFlag, srcid, mtime, rid)"
59
- "VALUES(%d,1,0,:mtime,:rid)",
60
- tagid
60
+ "REPLACE INTO tagxref(tagid, addFlag, srcid, value, mtime, rid)"
61
+ "VALUES(%d,1,0,%Q,:mtime,:rid)",
62
+ tagid, zValue
6163
);
6264
db_bind_double(&ins, ":mtime", mtime);
6365
}else{
6466
db_prepare(&ins,
6567
"DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
@@ -89,18 +91,73 @@
8991
** Propagate all propagatable tags in pid to its children.
9092
*/
9193
void tag_propagate_all(int pid){
9294
Stmt q;
9395
db_prepare(&q,
94
- "SELECT tagid, addflag, mtime FROM tagxref"
96
+ "SELECT tagid, addflag, mtime, value FROM tagxref"
9597
" WHERE rid=%d"
9698
" AND (SELECT tagname FROM tag WHERE tagid=tagxref.tagid) LIKE 'br%'",
9799
pid
98100
);
99101
while( db_step(&q)==SQLITE_ROW ){
100102
int tagid = db_column_int(&q, 0);
101103
int addflag = db_column_int(&q, 1);
102104
double mtime = db_column_double(&q, 2);
103
- tag_propagate(pid, tagid, addflag, mtime);
105
+ const char *zValue = db_column_text(&q, 3);
106
+ tag_propagate(pid, tagid, addflag, zValue, mtime);
104107
}
105108
db_finalize(&q);
106109
}
110
+
111
+/*
112
+** Get a tagid for the given TAG. Create a new tag if necessary
113
+** if createFlag is 1.
114
+*/
115
+int tag_findid(const char *zTag, int createFlag){
116
+ int id;
117
+ id = db_int(0, "SELECT tagid FROM tag WHERE tagname=%Q", zTag);
118
+ if( id==0 && createFlag ){
119
+ db_multi_exec("INSERT INTO tag(tagname) VALUES(%Q)", zTag);
120
+ id = db_last_insert_rowid();
121
+ }
122
+ return id;
123
+}
124
+
125
+
126
+/*
127
+** COMMAND: test-addtag
128
+** %fossil test-addtag TAGNAME UUID ?VALUE?
129
+**
130
+** Add a tag to the rebuildable tables of the local repository.
131
+** No tag artifact is created so the new tag is erased the next
132
+** time the repository is rebuilt. This routine is for testing
133
+** use only.
134
+*/
135
+void addtag_cmd(void){
136
+ const char *zTag;
137
+ const char *zValue;
138
+ int tagid;
139
+ int rid;
140
+ double now;
141
+ db_must_be_within_tree();
142
+ if( g.argc!=4 && g.argc!=5 ){
143
+ usage("TAGNAME UUID ?VALUE?");
144
+ }
145
+ zTag = g.argv[2];
146
+ rid = name_to_rid(g.argv[3]);
147
+ if( rid==0 ){
148
+ fossil_fatal("no such object: %s", g.argv[3]);
149
+ }
150
+ db_begin_transaction();
151
+ tagid = tag_findid(zTag, 1);
152
+ zValue = g.argc==5 ? g.argv[4] : 0;
153
+ db_multi_exec(
154
+ "REPLACE INTO tagxref(tagid,addFlag,srcId,value,mtime,rid)"
155
+ " VALUES(%d,1,-1,%Q,julianday('now'),%d)",
156
+ tagid, rid, zValue, rid
157
+ );
158
+ if( strncmp(zTag, "br", 2)==0 ){
159
+ now = db_double(0.0, "SELECT julianday('now')");
160
+ tag_propagate(rid, tagid, 1, zValue, now);
161
+ }
162
+ db_end_transaction(0);
163
+}
107164
--- src/tag.c
+++ src/tag.c
@@ -35,31 +35,33 @@
35 **
36 ** If addFlag is true then the tag is added. If false, then the
37 ** tag is removed.
38 */
39 void tag_propagate(
40 int pid, /* Propagate the tag to children of this node */
41 int tagid, /* Tag to propagate */
42 int addFlag, /* True to add the tag. False to delete it. */
43 double mtime /* Timestamp on the tag */
 
44 ){
45 PQueue queue;
46 Stmt s, ins;
47 pqueue_init(&queue);
48 pqueue_insert(&queue, pid, 0.0);
49 db_prepare(&s,
50 "SELECT cid, mtime, coalesce(srcid=0 AND mtime<:mtime, %d) AS doit"
 
51 " FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
52 " WHERE pid=:pid AND isprim",
53 addFlag, tagid
54 );
55 db_bind_double(&s, ":mtime", mtime);
56 if( addFlag ){
57 db_prepare(&ins,
58 "REPLACE INTO tagxref(tagid, addFlag, srcid, mtime, rid)"
59 "VALUES(%d,1,0,:mtime,:rid)",
60 tagid
61 );
62 db_bind_double(&ins, ":mtime", mtime);
63 }else{
64 db_prepare(&ins,
65 "DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
@@ -89,18 +91,73 @@
89 ** Propagate all propagatable tags in pid to its children.
90 */
91 void tag_propagate_all(int pid){
92 Stmt q;
93 db_prepare(&q,
94 "SELECT tagid, addflag, mtime FROM tagxref"
95 " WHERE rid=%d"
96 " AND (SELECT tagname FROM tag WHERE tagid=tagxref.tagid) LIKE 'br%'",
97 pid
98 );
99 while( db_step(&q)==SQLITE_ROW ){
100 int tagid = db_column_int(&q, 0);
101 int addflag = db_column_int(&q, 1);
102 double mtime = db_column_double(&q, 2);
103 tag_propagate(pid, tagid, addflag, mtime);
 
104 }
105 db_finalize(&q);
106 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
--- src/tag.c
+++ src/tag.c
@@ -35,31 +35,33 @@
35 **
36 ** If addFlag is true then the tag is added. If false, then the
37 ** tag is removed.
38 */
39 void tag_propagate(
40 int pid, /* Propagate the tag to children of this node */
41 int tagid, /* Tag to propagate */
42 int addFlag, /* True to add the tag. False to delete it. */
43 const char *zValue, /* Value of the tag. Might be NULL */
44 double mtime /* Timestamp on the tag */
45 ){
46 PQueue queue;
47 Stmt s, ins;
48 pqueue_init(&queue);
49 pqueue_insert(&queue, pid, 0.0);
50 db_prepare(&s,
51 "SELECT cid, plink.mtime,"
52 " coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit"
53 " FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
54 " WHERE pid=:pid AND isprim",
55 addFlag, tagid
56 );
57 db_bind_double(&s, ":mtime", mtime);
58 if( addFlag ){
59 db_prepare(&ins,
60 "REPLACE INTO tagxref(tagid, addFlag, srcid, value, mtime, rid)"
61 "VALUES(%d,1,0,%Q,:mtime,:rid)",
62 tagid, zValue
63 );
64 db_bind_double(&ins, ":mtime", mtime);
65 }else{
66 db_prepare(&ins,
67 "DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
@@ -89,18 +91,73 @@
91 ** Propagate all propagatable tags in pid to its children.
92 */
93 void tag_propagate_all(int pid){
94 Stmt q;
95 db_prepare(&q,
96 "SELECT tagid, addflag, mtime, value FROM tagxref"
97 " WHERE rid=%d"
98 " AND (SELECT tagname FROM tag WHERE tagid=tagxref.tagid) LIKE 'br%'",
99 pid
100 );
101 while( db_step(&q)==SQLITE_ROW ){
102 int tagid = db_column_int(&q, 0);
103 int addflag = db_column_int(&q, 1);
104 double mtime = db_column_double(&q, 2);
105 const char *zValue = db_column_text(&q, 3);
106 tag_propagate(pid, tagid, addflag, zValue, mtime);
107 }
108 db_finalize(&q);
109 }
110
111 /*
112 ** Get a tagid for the given TAG. Create a new tag if necessary
113 ** if createFlag is 1.
114 */
115 int tag_findid(const char *zTag, int createFlag){
116 int id;
117 id = db_int(0, "SELECT tagid FROM tag WHERE tagname=%Q", zTag);
118 if( id==0 && createFlag ){
119 db_multi_exec("INSERT INTO tag(tagname) VALUES(%Q)", zTag);
120 id = db_last_insert_rowid();
121 }
122 return id;
123 }
124
125
126 /*
127 ** COMMAND: test-addtag
128 ** %fossil test-addtag TAGNAME UUID ?VALUE?
129 **
130 ** Add a tag to the rebuildable tables of the local repository.
131 ** No tag artifact is created so the new tag is erased the next
132 ** time the repository is rebuilt. This routine is for testing
133 ** use only.
134 */
135 void addtag_cmd(void){
136 const char *zTag;
137 const char *zValue;
138 int tagid;
139 int rid;
140 double now;
141 db_must_be_within_tree();
142 if( g.argc!=4 && g.argc!=5 ){
143 usage("TAGNAME UUID ?VALUE?");
144 }
145 zTag = g.argv[2];
146 rid = name_to_rid(g.argv[3]);
147 if( rid==0 ){
148 fossil_fatal("no such object: %s", g.argv[3]);
149 }
150 db_begin_transaction();
151 tagid = tag_findid(zTag, 1);
152 zValue = g.argc==5 ? g.argv[4] : 0;
153 db_multi_exec(
154 "REPLACE INTO tagxref(tagid,addFlag,srcId,value,mtime,rid)"
155 " VALUES(%d,1,-1,%Q,julianday('now'),%d)",
156 tagid, rid, zValue, rid
157 );
158 if( strncmp(zTag, "br", 2)==0 ){
159 now = db_double(0.0, "SELECT julianday('now')");
160 tag_propagate(rid, tagid, 1, zValue, now);
161 }
162 db_end_transaction(0);
163 }
164
+17 -4
--- src/timeline.c
+++ src/timeline.c
@@ -85,10 +85,11 @@
8585
** 3. Comment string
8686
** 4. User
8787
** 5. Number of non-merge children
8888
** 6. Number of parents
8989
** 7. True if is a leaf
90
+** 8. background color
9091
*/
9192
void www_print_timeline(
9293
Stmt *pQuery,
9394
int *pFirstEvent,
9495
int *pLastEvent,
@@ -96,10 +97,11 @@
9697
Blob *pArg
9798
){
9899
char zPrevDate[20];
99100
int cnt = 0;
100101
zPrevDate[0] = 0;
102
+
101103
db_multi_exec(
102104
"CREATE TEMP TABLE IF NOT EXISTS seen(rid INTEGER PRIMARY KEY);"
103105
"DELETE FROM seen;"
104106
);
105107
@ <table cellspacing=0 border=0 cellpadding=0>
@@ -107,10 +109,11 @@
107109
int rid = db_column_int(pQuery, 0);
108110
const char *zUuid = db_column_text(pQuery, 1);
109111
int nPChild = db_column_int(pQuery, 5);
110112
int nParent = db_column_int(pQuery, 6);
111113
int isLeaf = db_column_int(pQuery, 7);
114
+ const char *zBgClr = db_column_text(pQuery, 8);
112115
const char *zDate = db_column_text(pQuery, 2);
113116
if( cnt==0 && pFirstEvent ){
114117
*pFirstEvent = rid;
115118
}
116119
if( pLastEvent ){
@@ -133,11 +136,15 @@
133136
}
134137
@ <tr>
135138
@ <td valign="top">%s(&zDate[11])</td>
136139
@ <td width="20" align="center" valign="top">
137140
@ <font id="m%d(rid)" size="+1" color="white">*</font></td>
138
- @ <td valign="top" align="left">
141
+ if( zBgClr && zBgClr[0] ){
142
+ @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
143
+ }else{
144
+ @ <td valign="top" align="left">
145
+ }
139146
hyperlink_to_uuid_with_mouseover(zUuid, "xin", "xout", rid);
140147
if( nParent>1 ){
141148
@ <b>Merge</b>
142149
}
143150
if( nPChild>1 ){
@@ -206,17 +213,20 @@
206213
int objid = atoi(PD("e","0"));
207214
int relatedEvents = P("r")!=0;
208215
int afterFlag = P("a")!=0;
209216
int firstEvent;
210217
int lastEvent;
218
+ int clr1, clr2; /* Tag IDs for specifying background colors */
211219
212220
/* To view the timeline, must have permission to read project data.
213221
*/
214222
login_check_credentials();
215223
if( !g.okRead ){ login_needed(); return; }
216224
217225
style_header("Timeline");
226
+ clr1 = db_int(0, "SELECT tagid FROM tag WHERE tagname='br-bg-color'");
227
+ clr2 = db_int(0, "SELECT tagid FROM tag WHERE tagname='bg-color'");
218228
if( !g.okHistory &&
219229
db_exists("SELECT 1 FROM user"
220230
" WHERE login='anonymous'"
221231
" AND cap LIKE '%%h%%'") ){
222232
@ <p><b>Note:</b> You will be able to access <u>much</u> more
@@ -224,13 +234,16 @@
224234
}
225235
zSQL = mprintf(
226236
"SELECT blob.rid, uuid, datetime(event.mtime,'localtime'), comment, user,"
227237
" (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),"
228238
" (SELECT count(*) FROM plink WHERE cid=blob.rid),"
229
- " NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid)"
230
- " FROM event, blob"
231
- " WHERE event.type='ci' AND blob.rid=event.objid"
239
+ " NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),"
240
+ " (SELECT value FROM tagxref WHERE rid=blob.rid AND tagid=%d"
241
+ " UNION ALL"
242
+ " SELECT value FROM tagxref WHERE rid=blob.rid AND tagid=%d)"
243
+ " FROM event JOIN blob"
244
+ " WHERE event.type='ci' AND blob.rid=event.objid", clr2, clr1
232245
);
233246
if( zUser ){
234247
zSQL = mprintf("%z AND event.user=%Q", zSQL, zUser);
235248
}
236249
if( objid ){
237250
--- src/timeline.c
+++ src/timeline.c
@@ -85,10 +85,11 @@
85 ** 3. Comment string
86 ** 4. User
87 ** 5. Number of non-merge children
88 ** 6. Number of parents
89 ** 7. True if is a leaf
 
90 */
91 void www_print_timeline(
92 Stmt *pQuery,
93 int *pFirstEvent,
94 int *pLastEvent,
@@ -96,10 +97,11 @@
96 Blob *pArg
97 ){
98 char zPrevDate[20];
99 int cnt = 0;
100 zPrevDate[0] = 0;
 
101 db_multi_exec(
102 "CREATE TEMP TABLE IF NOT EXISTS seen(rid INTEGER PRIMARY KEY);"
103 "DELETE FROM seen;"
104 );
105 @ <table cellspacing=0 border=0 cellpadding=0>
@@ -107,10 +109,11 @@
107 int rid = db_column_int(pQuery, 0);
108 const char *zUuid = db_column_text(pQuery, 1);
109 int nPChild = db_column_int(pQuery, 5);
110 int nParent = db_column_int(pQuery, 6);
111 int isLeaf = db_column_int(pQuery, 7);
 
112 const char *zDate = db_column_text(pQuery, 2);
113 if( cnt==0 && pFirstEvent ){
114 *pFirstEvent = rid;
115 }
116 if( pLastEvent ){
@@ -133,11 +136,15 @@
133 }
134 @ <tr>
135 @ <td valign="top">%s(&zDate[11])</td>
136 @ <td width="20" align="center" valign="top">
137 @ <font id="m%d(rid)" size="+1" color="white">*</font></td>
138 @ <td valign="top" align="left">
 
 
 
 
139 hyperlink_to_uuid_with_mouseover(zUuid, "xin", "xout", rid);
140 if( nParent>1 ){
141 @ <b>Merge</b>
142 }
143 if( nPChild>1 ){
@@ -206,17 +213,20 @@
206 int objid = atoi(PD("e","0"));
207 int relatedEvents = P("r")!=0;
208 int afterFlag = P("a")!=0;
209 int firstEvent;
210 int lastEvent;
 
211
212 /* To view the timeline, must have permission to read project data.
213 */
214 login_check_credentials();
215 if( !g.okRead ){ login_needed(); return; }
216
217 style_header("Timeline");
 
 
218 if( !g.okHistory &&
219 db_exists("SELECT 1 FROM user"
220 " WHERE login='anonymous'"
221 " AND cap LIKE '%%h%%'") ){
222 @ <p><b>Note:</b> You will be able to access <u>much</u> more
@@ -224,13 +234,16 @@
224 }
225 zSQL = mprintf(
226 "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'), comment, user,"
227 " (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),"
228 " (SELECT count(*) FROM plink WHERE cid=blob.rid),"
229 " NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid)"
230 " FROM event, blob"
231 " WHERE event.type='ci' AND blob.rid=event.objid"
 
 
 
232 );
233 if( zUser ){
234 zSQL = mprintf("%z AND event.user=%Q", zSQL, zUser);
235 }
236 if( objid ){
237
--- src/timeline.c
+++ src/timeline.c
@@ -85,10 +85,11 @@
85 ** 3. Comment string
86 ** 4. User
87 ** 5. Number of non-merge children
88 ** 6. Number of parents
89 ** 7. True if is a leaf
90 ** 8. background color
91 */
92 void www_print_timeline(
93 Stmt *pQuery,
94 int *pFirstEvent,
95 int *pLastEvent,
@@ -96,10 +97,11 @@
97 Blob *pArg
98 ){
99 char zPrevDate[20];
100 int cnt = 0;
101 zPrevDate[0] = 0;
102
103 db_multi_exec(
104 "CREATE TEMP TABLE IF NOT EXISTS seen(rid INTEGER PRIMARY KEY);"
105 "DELETE FROM seen;"
106 );
107 @ <table cellspacing=0 border=0 cellpadding=0>
@@ -107,10 +109,11 @@
109 int rid = db_column_int(pQuery, 0);
110 const char *zUuid = db_column_text(pQuery, 1);
111 int nPChild = db_column_int(pQuery, 5);
112 int nParent = db_column_int(pQuery, 6);
113 int isLeaf = db_column_int(pQuery, 7);
114 const char *zBgClr = db_column_text(pQuery, 8);
115 const char *zDate = db_column_text(pQuery, 2);
116 if( cnt==0 && pFirstEvent ){
117 *pFirstEvent = rid;
118 }
119 if( pLastEvent ){
@@ -133,11 +136,15 @@
136 }
137 @ <tr>
138 @ <td valign="top">%s(&zDate[11])</td>
139 @ <td width="20" align="center" valign="top">
140 @ <font id="m%d(rid)" size="+1" color="white">*</font></td>
141 if( zBgClr && zBgClr[0] ){
142 @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
143 }else{
144 @ <td valign="top" align="left">
145 }
146 hyperlink_to_uuid_with_mouseover(zUuid, "xin", "xout", rid);
147 if( nParent>1 ){
148 @ <b>Merge</b>
149 }
150 if( nPChild>1 ){
@@ -206,17 +213,20 @@
213 int objid = atoi(PD("e","0"));
214 int relatedEvents = P("r")!=0;
215 int afterFlag = P("a")!=0;
216 int firstEvent;
217 int lastEvent;
218 int clr1, clr2; /* Tag IDs for specifying background colors */
219
220 /* To view the timeline, must have permission to read project data.
221 */
222 login_check_credentials();
223 if( !g.okRead ){ login_needed(); return; }
224
225 style_header("Timeline");
226 clr1 = db_int(0, "SELECT tagid FROM tag WHERE tagname='br-bg-color'");
227 clr2 = db_int(0, "SELECT tagid FROM tag WHERE tagname='bg-color'");
228 if( !g.okHistory &&
229 db_exists("SELECT 1 FROM user"
230 " WHERE login='anonymous'"
231 " AND cap LIKE '%%h%%'") ){
232 @ <p><b>Note:</b> You will be able to access <u>much</u> more
@@ -224,13 +234,16 @@
234 }
235 zSQL = mprintf(
236 "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'), comment, user,"
237 " (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),"
238 " (SELECT count(*) FROM plink WHERE cid=blob.rid),"
239 " NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),"
240 " (SELECT value FROM tagxref WHERE rid=blob.rid AND tagid=%d"
241 " UNION ALL"
242 " SELECT value FROM tagxref WHERE rid=blob.rid AND tagid=%d)"
243 " FROM event JOIN blob"
244 " WHERE event.type='ci' AND blob.rid=event.objid", clr2, clr1
245 );
246 if( zUser ){
247 zSQL = mprintf("%z AND event.user=%Q", zSQL, zUser);
248 }
249 if( objid ){
250

Keyboard Shortcuts

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