24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
/*
** Propagate the tag given by tagid to the children of pid.
**
** This routine assumes that tagid is a tag that should be
** propagated and that the tag is already present in pid.
**
** If tagtype is 2 then the tag is being propagated from an
** ancestor node. If tagtype is 0 it means a branch tag is
** being cancelled.
*/
static void tag_propagate(
int pid, /* Propagate the tag to children of this node */
int tagid, /* Tag to propagate */
int tagType, /* 2 for a propagating tag. 0 for an antitag */
int origId, /* Artifact of tag, when tagType==2 */
const char *zValue, /* Value of the tag. Might be NULL */
double mtime /* Timestamp on the tag */
){
PQueue queue;
Stmt s, ins, eventupdate;
assert( tagType==0 || tagType==2 );
pqueue_init(&queue);
pqueue_insert(&queue, pid, 0.0);
db_prepare(&s,
"SELECT cid, plink.mtime,"
" coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit"
" FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
" WHERE pid=:pid AND isprim",
tagType!=0, tagid
);
db_bind_double(&s, ":mtime", mtime);
if( tagType==2 ){
db_prepare(&ins,
"REPLACE INTO tagxref(tagid, tagtype, srcid, origid, value, mtime, rid)"
"VALUES(%d,2,0,%d,%Q,:mtime,:rid)",
tagid, origId, zValue
);
db_bind_double(&ins, ":mtime", mtime);
}else{
zValue = 0;
db_prepare(&ins,
"DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
);
}
if( tagid==TAG_BGCOLOR ){
db_prepare(&eventupdate,
|
|
|
|
>
>
|
>
>
>
>
>
|
>
>
>
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
/*
** Propagate the tag given by tagid to the children of pid.
**
** This routine assumes that tagid is a tag that should be
** propagated and that the tag is already present in pid.
**
** If tagtype is 2 then the tag is being propagated from an
** ancestor node. If tagtype is 0 it means a propagating tag is
** being blocked.
*/
static void tag_propagate(
int pid, /* Propagate the tag to children of this node */
int tagid, /* Tag to propagate */
int tagType, /* 2 for a propagating tag. 0 for an antitag */
int origId, /* Artifact of tag, when tagType==2 */
const char *zValue, /* Value of the tag. Might be NULL */
double mtime /* Timestamp on the tag */
){
PQueue queue; /* Queue of check-ins to be tagged */
Stmt s; /* Query the children of :pid to which to propagate */
Stmt ins; /* INSERT INTO tagxref */
Stmt eventupdate; /* UPDATE event */
assert( tagType==0 || tagType==2 );
pqueue_init(&queue);
pqueue_insert(&queue, pid, 0.0);
/* Query for children of :pid to which to propagate the tag.
** Three returns: (1) rid of the child. (2) timestamp of child.
** (3) True to propagate or false to block.
*/
db_prepare(&s,
"SELECT cid, plink.mtime,"
" coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit"
" FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
" WHERE pid=:pid AND isprim",
tagType==2, tagid
);
db_bind_double(&s, ":mtime", mtime);
if( tagType==2 ){
/* Set the propagated tag marker on checkin :rid */
db_prepare(&ins,
"REPLACE INTO tagxref(tagid, tagtype, srcid, origid, value, mtime, rid)"
"VALUES(%d,2,0,%d,%Q,:mtime,:rid)",
tagid, origId, zValue
);
db_bind_double(&ins, ":mtime", mtime);
}else{
/* Remove all references to the tag from checkin :rid */
zValue = 0;
db_prepare(&ins,
"DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
);
}
if( tagid==TAG_BGCOLOR ){
db_prepare(&eventupdate,
|