Fossil SCM

Track the origin of tags and display that origin in the tag and properities information field of the "vinfo" page. Must "fossil rebuild" after this change.

drh 2009-01-21 23:40 trunk
Commit 08db9e11cb6f86f943893cc154bc86c6285ec7ab
+34
--- src/branch.c
+++ src/branch.c
@@ -257,10 +257,44 @@
257257
timeline_query_for_www(), TAG_NEWBRANCH
258258
);
259259
www_print_timeline(&q, 0, brlist_extra);
260260
db_finalize(&q);
261261
@ <br clear="both">
262
+ @ <script>
263
+ @ function xin(id){
264
+ @ }
265
+ @ function xout(id){
266
+ @ }
267
+ @ </script>
268
+ style_footer();
269
+}
270
+
271
+/*
272
+** WEBPAGE: symtaglist
273
+**
274
+** Show a timeline of all check-ins that have a primary symbolic tag.
275
+*/
276
+void symtaglist_page(void){
277
+ Stmt q;
278
+
279
+ login_check_credentials();
280
+ if( !g.okRead ){ login_needed(); return; }
281
+
282
+ style_header("Tagged Check-ins");
283
+ login_anonymous_available();
284
+ @ <h2>Check-ins that have one or more primary symbolic tags</h2>
285
+ db_prepare(&q,
286
+ "%s AND blob.rid IN (SELECT rid FROM tagxref"
287
+ " WHERE tagtype>1 AND srcid>0"
288
+ " AND tagid IN (SELECT tagid FROM tag "
289
+ " WHERE tagname GLOB 'sym-*'))"
290
+ " ORDER BY event.mtime DESC",
291
+ timeline_query_for_www(), TAG_NEWBRANCH
292
+ );
293
+ www_print_timeline(&q, 0, 0);
294
+ db_finalize(&q);
295
+ @ <br clear="both">
262296
@ <script>
263297
@ function xin(id){
264298
@ }
265299
@ function xout(id){
266300
@ }
267301
--- src/branch.c
+++ src/branch.c
@@ -257,10 +257,44 @@
257 timeline_query_for_www(), TAG_NEWBRANCH
258 );
259 www_print_timeline(&q, 0, brlist_extra);
260 db_finalize(&q);
261 @ <br clear="both">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262 @ <script>
263 @ function xin(id){
264 @ }
265 @ function xout(id){
266 @ }
267
--- src/branch.c
+++ src/branch.c
@@ -257,10 +257,44 @@
257 timeline_query_for_www(), TAG_NEWBRANCH
258 );
259 www_print_timeline(&q, 0, brlist_extra);
260 db_finalize(&q);
261 @ <br clear="both">
262 @ <script>
263 @ function xin(id){
264 @ }
265 @ function xout(id){
266 @ }
267 @ </script>
268 style_footer();
269 }
270
271 /*
272 ** WEBPAGE: symtaglist
273 **
274 ** Show a timeline of all check-ins that have a primary symbolic tag.
275 */
276 void symtaglist_page(void){
277 Stmt q;
278
279 login_check_credentials();
280 if( !g.okRead ){ login_needed(); return; }
281
282 style_header("Tagged Check-ins");
283 login_anonymous_available();
284 @ <h2>Check-ins that have one or more primary symbolic tags</h2>
285 db_prepare(&q,
286 "%s AND blob.rid IN (SELECT rid FROM tagxref"
287 " WHERE tagtype>1 AND srcid>0"
288 " AND tagid IN (SELECT tagid FROM tag "
289 " WHERE tagname GLOB 'sym-*'))"
290 " ORDER BY event.mtime DESC",
291 timeline_query_for_www(), TAG_NEWBRANCH
292 );
293 www_print_timeline(&q, 0, 0);
294 db_finalize(&q);
295 @ <br clear="both">
296 @ <script>
297 @ function xin(id){
298 @ }
299 @ function xout(id){
300 @ }
301
+27 -19
--- src/info.c
+++ src/info.c
@@ -269,45 +269,53 @@
269269
*/
270270
static void showTags(int rid, const char *zNotGlob){
271271
Stmt q;
272272
int cnt = 0;
273273
db_prepare(&q,
274
- "SELECT tag.tagid, tagname, srcid, blob.uuid, value,"
275
- " datetime(tagxref.mtime,'localtime'), tagtype"
274
+ "SELECT tag.tagid, tagname, "
275
+ " (SELECT uuid FROM blob WHERE rid=tagxref.srcid AND rid!=%d),"
276
+ " value, datetime(tagxref.mtime,'localtime'), tagtype,"
277
+ " (SELECT uuid FROM blob WHERE rid=tagxref.origid)"
276278
" FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
277
- " LEFT JOIN blob ON blob.rid=tagxref.srcid"
278279
" WHERE tagxref.rid=%d AND tagname NOT GLOB '%s'"
279
- " ORDER BY tagname", rid, zNotGlob
280
+ " ORDER BY tagname", rid, rid, zNotGlob
280281
);
281282
while( db_step(&q)==SQLITE_ROW ){
282283
const char *zTagname = db_column_text(&q, 1);
283
- int srcid = db_column_int(&q, 2);
284
- const char *zUuid = db_column_text(&q, 3);
285
- const char *zValue = db_column_text(&q, 4);
286
- const char *zDate = db_column_text(&q, 5);
287
- int tagtype = db_column_int(&q, 6);
284
+ const char *zSrcUuid = db_column_text(&q, 2);
285
+ const char *zValue = db_column_text(&q, 3);
286
+ const char *zDate = db_column_text(&q, 4);
287
+ int tagtype = db_column_int(&q, 5);
288
+ const char *zOrigUuid = db_column_text(&q, 6);
288289
cnt++;
289290
if( cnt==1 ){
290291
@ <div class="section">Tags And Properties</div>
291292
@ <ul>
292293
}
293294
@ <li>
294295
@ <b>%h(zTagname)</b>
295
- if( zValue ){
296
+ if( tagtype==0 ){
297
+ @ <i>cancelled.
298
+ }else if( zValue ){
296299
@ = %h(zValue)<i>
297
- }else if( tagtype==0 ){
298
- @ <i>Cancelled
299
- }else{
300
+ }else {
300301
@ <i>
301302
}
302
- if( srcid==0 ){
303
- @ Inherited
304
- }else if( zUuid ){
305
- @ From
306
- hyperlink_to_uuid(zUuid);
303
+ if( tagtype==2 ){
304
+ if( zOrigUuid && zOrigUuid[0] ){
305
+ @ inherited from
306
+ hyperlink_to_uuid(zOrigUuid);
307
+ }else{
308
+ @ propagates to descendants
309
+ }
310
+ }
311
+ if( zSrcUuid && zSrcUuid[0] ){
312
+ @ added by
313
+ hyperlink_to_uuid(zSrcUuid);
314
+ @ on %s(zDate)
307315
}
308
- @ on %s(zDate)</i>
316
+ @ </i>
309317
}
310318
db_finalize(&q);
311319
if( cnt ){
312320
@ </ul>
313321
}
314322
--- src/info.c
+++ src/info.c
@@ -269,45 +269,53 @@
269 */
270 static void showTags(int rid, const char *zNotGlob){
271 Stmt q;
272 int cnt = 0;
273 db_prepare(&q,
274 "SELECT tag.tagid, tagname, srcid, blob.uuid, value,"
275 " datetime(tagxref.mtime,'localtime'), tagtype"
 
 
276 " FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
277 " LEFT JOIN blob ON blob.rid=tagxref.srcid"
278 " WHERE tagxref.rid=%d AND tagname NOT GLOB '%s'"
279 " ORDER BY tagname", rid, zNotGlob
280 );
281 while( db_step(&q)==SQLITE_ROW ){
282 const char *zTagname = db_column_text(&q, 1);
283 int srcid = db_column_int(&q, 2);
284 const char *zUuid = db_column_text(&q, 3);
285 const char *zValue = db_column_text(&q, 4);
286 const char *zDate = db_column_text(&q, 5);
287 int tagtype = db_column_int(&q, 6);
288 cnt++;
289 if( cnt==1 ){
290 @ <div class="section">Tags And Properties</div>
291 @ <ul>
292 }
293 @ <li>
294 @ <b>%h(zTagname)</b>
295 if( zValue ){
 
 
296 @ = %h(zValue)<i>
297 }else if( tagtype==0 ){
298 @ <i>Cancelled
299 }else{
300 @ <i>
301 }
302 if( srcid==0 ){
303 @ Inherited
304 }else if( zUuid ){
305 @ From
306 hyperlink_to_uuid(zUuid);
 
 
 
 
 
 
 
307 }
308 @ on %s(zDate)</i>
309 }
310 db_finalize(&q);
311 if( cnt ){
312 @ </ul>
313 }
314
--- src/info.c
+++ src/info.c
@@ -269,45 +269,53 @@
269 */
270 static void showTags(int rid, const char *zNotGlob){
271 Stmt q;
272 int cnt = 0;
273 db_prepare(&q,
274 "SELECT tag.tagid, tagname, "
275 " (SELECT uuid FROM blob WHERE rid=tagxref.srcid AND rid!=%d),"
276 " value, datetime(tagxref.mtime,'localtime'), tagtype,"
277 " (SELECT uuid FROM blob WHERE rid=tagxref.origid)"
278 " FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
 
279 " WHERE tagxref.rid=%d AND tagname NOT GLOB '%s'"
280 " ORDER BY tagname", rid, rid, zNotGlob
281 );
282 while( db_step(&q)==SQLITE_ROW ){
283 const char *zTagname = db_column_text(&q, 1);
284 const char *zSrcUuid = db_column_text(&q, 2);
285 const char *zValue = db_column_text(&q, 3);
286 const char *zDate = db_column_text(&q, 4);
287 int tagtype = db_column_int(&q, 5);
288 const char *zOrigUuid = db_column_text(&q, 6);
289 cnt++;
290 if( cnt==1 ){
291 @ <div class="section">Tags And Properties</div>
292 @ <ul>
293 }
294 @ <li>
295 @ <b>%h(zTagname)</b>
296 if( tagtype==0 ){
297 @ <i>cancelled.
298 }else if( zValue ){
299 @ = %h(zValue)<i>
300 }else {
 
 
301 @ <i>
302 }
303 if( tagtype==2 ){
304 if( zOrigUuid && zOrigUuid[0] ){
305 @ inherited from
306 hyperlink_to_uuid(zOrigUuid);
307 }else{
308 @ propagates to descendants
309 }
310 }
311 if( zSrcUuid && zSrcUuid[0] ){
312 @ added by
313 hyperlink_to_uuid(zSrcUuid);
314 @ on %s(zDate)
315 }
316 @ </i>
317 }
318 db_finalize(&q);
319 if( cnt ){
320 @ </ul>
321 }
322
+4 -5
--- src/manifest.c
+++ src/manifest.c
@@ -501,11 +501,11 @@
501501
zUuid = 0;
502502
}else{
503503
goto manifest_syntax_error;
504504
}
505505
defossilize(zName);
506
- if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' && zName[0]!='0' ){
506
+ if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
507507
goto manifest_syntax_error;
508508
}
509509
if( validate16(&zName[1], strlen(&zName[1])) ){
510510
/* Do not allow tags whose names look like UUIDs */
511511
goto manifest_syntax_error;
@@ -948,14 +948,13 @@
948948
}else{
949949
tid = rid;
950950
}
951951
if( tid ){
952952
switch( m.aTag[i].zName[0] ){
953
- case '+': type = 1; break;
954
- case '*': type = 2; break;
955
- case '-': type = 0; break;
956
- case '0': type = -1; break;
953
+ case '-': type = 0; break; /* Cancel prior occurances */
954
+ case '+': type = 1; break; /* Apply to target only */
955
+ case '*': type = 2; break; /* Propagate to descendants */
957956
default:
958957
fossil_fatal("unknown tag type in manifest: %s", m.aTag);
959958
return 0;
960959
}
961960
tag_insert(&m.aTag[i].zName[1], type, m.aTag[i].zValue,
962961
--- src/manifest.c
+++ src/manifest.c
@@ -501,11 +501,11 @@
501 zUuid = 0;
502 }else{
503 goto manifest_syntax_error;
504 }
505 defossilize(zName);
506 if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' && zName[0]!='0' ){
507 goto manifest_syntax_error;
508 }
509 if( validate16(&zName[1], strlen(&zName[1])) ){
510 /* Do not allow tags whose names look like UUIDs */
511 goto manifest_syntax_error;
@@ -948,14 +948,13 @@
948 }else{
949 tid = rid;
950 }
951 if( tid ){
952 switch( m.aTag[i].zName[0] ){
953 case '+': type = 1; break;
954 case '*': type = 2; break;
955 case '-': type = 0; break;
956 case '0': type = -1; break;
957 default:
958 fossil_fatal("unknown tag type in manifest: %s", m.aTag);
959 return 0;
960 }
961 tag_insert(&m.aTag[i].zName[1], type, m.aTag[i].zValue,
962
--- src/manifest.c
+++ src/manifest.c
@@ -501,11 +501,11 @@
501 zUuid = 0;
502 }else{
503 goto manifest_syntax_error;
504 }
505 defossilize(zName);
506 if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
507 goto manifest_syntax_error;
508 }
509 if( validate16(&zName[1], strlen(&zName[1])) ){
510 /* Do not allow tags whose names look like UUIDs */
511 goto manifest_syntax_error;
@@ -948,14 +948,13 @@
948 }else{
949 tid = rid;
950 }
951 if( tid ){
952 switch( m.aTag[i].zName[0] ){
953 case '-': type = 0; break; /* Cancel prior occurances */
954 case '+': type = 1; break; /* Apply to target only */
955 case '*': type = 2; break; /* Propagate to descendants */
 
956 default:
957 fossil_fatal("unknown tag type in manifest: %s", m.aTag);
958 return 0;
959 }
960 tag_insert(&m.aTag[i].zName[1], type, m.aTag[i].zValue,
961
+3 -2
--- src/schema.c
+++ src/schema.c
@@ -290,14 +290,15 @@
290290
@ -- keep calling them tags because in many cases the value is ignored.
291291
@ --
292292
@ CREATE TABLE tagxref(
293293
@ tagid INTEGER REFERENCES tag, -- The tag that added or removed
294294
@ tagtype INTEGER, -- 0:cancel 1:single 2:branch
295
-@ srcid INTEGER REFERENCES blob, -- Origin of the tag. 0 for propagated tags
295
+@ srcid INTEGER REFERENCES blob, -- Artifact of tag. 0 for propagated tags
296
+@ origid INTEGER REFERENCES blob, -- check-in holding propagated tag
296297
@ value TEXT, -- Value of the tag. Might be NULL.
297298
@ mtime TIMESTAMP, -- Time of addition or removal
298
-@ rid INTEGER REFERENCE blob, -- Baseline that tag added/removed from
299
+@ rid INTEGER REFERENCE blob, -- Artifact tag is applied to
299300
@ UNIQUE(rid, tagid)
300301
@ );
301302
@ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);
302303
@
303304
@ -- Template for the TICKET table
304305
--- src/schema.c
+++ src/schema.c
@@ -290,14 +290,15 @@
290 @ -- keep calling them tags because in many cases the value is ignored.
291 @ --
292 @ CREATE TABLE tagxref(
293 @ tagid INTEGER REFERENCES tag, -- The tag that added or removed
294 @ tagtype INTEGER, -- 0:cancel 1:single 2:branch
295 @ srcid INTEGER REFERENCES blob, -- Origin of the tag. 0 for propagated tags
 
296 @ value TEXT, -- Value of the tag. Might be NULL.
297 @ mtime TIMESTAMP, -- Time of addition or removal
298 @ rid INTEGER REFERENCE blob, -- Baseline that tag added/removed from
299 @ UNIQUE(rid, tagid)
300 @ );
301 @ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);
302 @
303 @ -- Template for the TICKET table
304
--- src/schema.c
+++ src/schema.c
@@ -290,14 +290,15 @@
290 @ -- keep calling them tags because in many cases the value is ignored.
291 @ --
292 @ CREATE TABLE tagxref(
293 @ tagid INTEGER REFERENCES tag, -- The tag that added or removed
294 @ tagtype INTEGER, -- 0:cancel 1:single 2:branch
295 @ srcid INTEGER REFERENCES blob, -- Artifact of tag. 0 for propagated tags
296 @ origid INTEGER REFERENCES blob, -- check-in holding propagated tag
297 @ value TEXT, -- Value of the tag. Might be NULL.
298 @ mtime TIMESTAMP, -- Time of addition or removal
299 @ rid INTEGER REFERENCE blob, -- Artifact tag is applied to
300 @ UNIQUE(rid, tagid)
301 @ );
302 @ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);
303 @
304 @ -- Template for the TICKET table
305
+9 -11
--- src/tag.c
+++ src/tag.c
@@ -39,10 +39,11 @@
3939
*/
4040
void tag_propagate(
4141
int pid, /* Propagate the tag to children of this node */
4242
int tagid, /* Tag to propagate */
4343
int tagType, /* 2 for a propagating tag. 0 for an antitag */
44
+ int origId, /* Artifact of tag, when tagType==2 */
4445
const char *zValue, /* Value of the tag. Might be NULL */
4546
double mtime /* Timestamp on the tag */
4647
){
4748
PQueue queue;
4849
Stmt s, ins, eventupdate;
@@ -58,13 +59,13 @@
5859
tagType!=0, tagid
5960
);
6061
db_bind_double(&s, ":mtime", mtime);
6162
if( tagType==2 ){
6263
db_prepare(&ins,
63
- "REPLACE INTO tagxref(tagid, tagtype, srcid, value, mtime, rid)"
64
- "VALUES(%d,2,0,%Q,:mtime,:rid)",
65
- tagid, zValue
64
+ "REPLACE INTO tagxref(tagid, tagtype, srcid, origid, value, mtime, rid)"
65
+ "VALUES(%d,2,0,%d,%Q,:mtime,:rid)",
66
+ tagid, origId, zValue
6667
);
6768
db_bind_double(&ins, ":mtime", mtime);
6869
}else{
6970
zValue = 0;
7071
db_prepare(&ins,
@@ -108,21 +109,22 @@
108109
** Propagate all propagatable tags in pid to its children.
109110
*/
110111
void tag_propagate_all(int pid){
111112
Stmt q;
112113
db_prepare(&q,
113
- "SELECT tagid, tagtype, mtime, value FROM tagxref"
114
+ "SELECT tagid, tagtype, mtime, value, origid FROM tagxref"
114115
" WHERE rid=%d"
115116
" AND (tagtype=0 OR tagtype=2)",
116117
pid
117118
);
118119
while( db_step(&q)==SQLITE_ROW ){
119120
int tagid = db_column_int(&q, 0);
120121
int tagtype = db_column_int(&q, 1);
121122
double mtime = db_column_double(&q, 2);
122123
const char *zValue = db_column_text(&q, 3);
123
- tag_propagate(pid, tagid, tagtype, zValue, mtime);
124
+ int origid = db_column_int(&q, 4);
125
+ tag_propagate(pid, tagid, tagtype, origid, zValue, mtime);
124126
}
125127
db_finalize(&q);
126128
}
127129
128130
/*
@@ -142,11 +144,11 @@
142144
/*
143145
** Insert a tag into the database.
144146
*/
145147
void tag_insert(
146148
const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */
147
- int tagtype, /* 0:cancel 1:singleton 2:propagated -1:erase */
149
+ int tagtype, /* 0:cancel 1:singleton 2:propagated */
148150
const char *zValue, /* Value if the tag is really a property */
149151
int srcId, /* Artifact that contains this tag */
150152
double mtime, /* Timestamp. Use default if <=0.0 */
151153
int rid /* Artifact to which the tag is to attached */
152154
){
@@ -170,14 +172,10 @@
170172
db_finalize(&s);
171173
if( rc==SQLITE_ROW ){
172174
/* Another entry that is more recent already exists. Do nothing */
173175
return;
174176
}
175
- if( tagtype<0 ){
176
- return;
177
- /* TBD: erase tags */
178
- }
179177
db_prepare(&s,
180178
"REPLACE INTO tagxref(tagid,tagtype,srcId,value,mtime,rid)"
181179
" VALUES(%d,%d,%d,%Q,:mtime,%d)",
182180
tagid, tagtype, srcId, zValue, rid
183181
);
@@ -204,11 +202,11 @@
204202
}
205203
if( zCol ){
206204
db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
207205
}
208206
if( tagtype==0 || tagtype==2 ){
209
- tag_propagate(rid, tagid, tagtype, zValue, mtime);
207
+ tag_propagate(rid, tagid, tagtype, rid, zValue, mtime);
210208
}
211209
}
212210
213211
214212
/*
215213
--- src/tag.c
+++ src/tag.c
@@ -39,10 +39,11 @@
39 */
40 void tag_propagate(
41 int pid, /* Propagate the tag to children of this node */
42 int tagid, /* Tag to propagate */
43 int tagType, /* 2 for a propagating tag. 0 for an antitag */
 
44 const char *zValue, /* Value of the tag. Might be NULL */
45 double mtime /* Timestamp on the tag */
46 ){
47 PQueue queue;
48 Stmt s, ins, eventupdate;
@@ -58,13 +59,13 @@
58 tagType!=0, tagid
59 );
60 db_bind_double(&s, ":mtime", mtime);
61 if( tagType==2 ){
62 db_prepare(&ins,
63 "REPLACE INTO tagxref(tagid, tagtype, srcid, value, mtime, rid)"
64 "VALUES(%d,2,0,%Q,:mtime,:rid)",
65 tagid, zValue
66 );
67 db_bind_double(&ins, ":mtime", mtime);
68 }else{
69 zValue = 0;
70 db_prepare(&ins,
@@ -108,21 +109,22 @@
108 ** Propagate all propagatable tags in pid to its children.
109 */
110 void tag_propagate_all(int pid){
111 Stmt q;
112 db_prepare(&q,
113 "SELECT tagid, tagtype, mtime, value FROM tagxref"
114 " WHERE rid=%d"
115 " AND (tagtype=0 OR tagtype=2)",
116 pid
117 );
118 while( db_step(&q)==SQLITE_ROW ){
119 int tagid = db_column_int(&q, 0);
120 int tagtype = db_column_int(&q, 1);
121 double mtime = db_column_double(&q, 2);
122 const char *zValue = db_column_text(&q, 3);
123 tag_propagate(pid, tagid, tagtype, zValue, mtime);
 
124 }
125 db_finalize(&q);
126 }
127
128 /*
@@ -142,11 +144,11 @@
142 /*
143 ** Insert a tag into the database.
144 */
145 void tag_insert(
146 const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */
147 int tagtype, /* 0:cancel 1:singleton 2:propagated -1:erase */
148 const char *zValue, /* Value if the tag is really a property */
149 int srcId, /* Artifact that contains this tag */
150 double mtime, /* Timestamp. Use default if <=0.0 */
151 int rid /* Artifact to which the tag is to attached */
152 ){
@@ -170,14 +172,10 @@
170 db_finalize(&s);
171 if( rc==SQLITE_ROW ){
172 /* Another entry that is more recent already exists. Do nothing */
173 return;
174 }
175 if( tagtype<0 ){
176 return;
177 /* TBD: erase tags */
178 }
179 db_prepare(&s,
180 "REPLACE INTO tagxref(tagid,tagtype,srcId,value,mtime,rid)"
181 " VALUES(%d,%d,%d,%Q,:mtime,%d)",
182 tagid, tagtype, srcId, zValue, rid
183 );
@@ -204,11 +202,11 @@
204 }
205 if( zCol ){
206 db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
207 }
208 if( tagtype==0 || tagtype==2 ){
209 tag_propagate(rid, tagid, tagtype, zValue, mtime);
210 }
211 }
212
213
214 /*
215
--- src/tag.c
+++ src/tag.c
@@ -39,10 +39,11 @@
39 */
40 void tag_propagate(
41 int pid, /* Propagate the tag to children of this node */
42 int tagid, /* Tag to propagate */
43 int tagType, /* 2 for a propagating tag. 0 for an antitag */
44 int origId, /* Artifact of tag, when tagType==2 */
45 const char *zValue, /* Value of the tag. Might be NULL */
46 double mtime /* Timestamp on the tag */
47 ){
48 PQueue queue;
49 Stmt s, ins, eventupdate;
@@ -58,13 +59,13 @@
59 tagType!=0, tagid
60 );
61 db_bind_double(&s, ":mtime", mtime);
62 if( tagType==2 ){
63 db_prepare(&ins,
64 "REPLACE INTO tagxref(tagid, tagtype, srcid, origid, value, mtime, rid)"
65 "VALUES(%d,2,0,%d,%Q,:mtime,:rid)",
66 tagid, origId, zValue
67 );
68 db_bind_double(&ins, ":mtime", mtime);
69 }else{
70 zValue = 0;
71 db_prepare(&ins,
@@ -108,21 +109,22 @@
109 ** Propagate all propagatable tags in pid to its children.
110 */
111 void tag_propagate_all(int pid){
112 Stmt q;
113 db_prepare(&q,
114 "SELECT tagid, tagtype, mtime, value, origid FROM tagxref"
115 " WHERE rid=%d"
116 " AND (tagtype=0 OR tagtype=2)",
117 pid
118 );
119 while( db_step(&q)==SQLITE_ROW ){
120 int tagid = db_column_int(&q, 0);
121 int tagtype = db_column_int(&q, 1);
122 double mtime = db_column_double(&q, 2);
123 const char *zValue = db_column_text(&q, 3);
124 int origid = db_column_int(&q, 4);
125 tag_propagate(pid, tagid, tagtype, origid, zValue, mtime);
126 }
127 db_finalize(&q);
128 }
129
130 /*
@@ -142,11 +144,11 @@
144 /*
145 ** Insert a tag into the database.
146 */
147 void tag_insert(
148 const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */
149 int tagtype, /* 0:cancel 1:singleton 2:propagated */
150 const char *zValue, /* Value if the tag is really a property */
151 int srcId, /* Artifact that contains this tag */
152 double mtime, /* Timestamp. Use default if <=0.0 */
153 int rid /* Artifact to which the tag is to attached */
154 ){
@@ -170,14 +172,10 @@
172 db_finalize(&s);
173 if( rc==SQLITE_ROW ){
174 /* Another entry that is more recent already exists. Do nothing */
175 return;
176 }
 
 
 
 
177 db_prepare(&s,
178 "REPLACE INTO tagxref(tagid,tagtype,srcId,value,mtime,rid)"
179 " VALUES(%d,%d,%d,%Q,:mtime,%d)",
180 tagid, tagtype, srcId, zValue, rid
181 );
@@ -204,11 +202,11 @@
202 }
203 if( zCol ){
204 db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
205 }
206 if( tagtype==0 || tagtype==2 ){
207 tag_propagate(rid, tagid, tagtype, rid, zValue, mtime);
208 }
209 }
210
211
212 /*
213

Keyboard Shortcuts

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