Fossil SCM

In /timeline allow p= and d= to have separate values, and the result is showing all check-ins that are both ancenstors of p= and descendents of d=.

drh 2025-03-10 14:14 trunk
Commit d1d4cc7529eefa9e31f486c697030087940930f9d1ee60d1d656830fdad76500
1 file changed +79 -37
+79 -37
--- src/timeline.c
+++ src/timeline.c
@@ -1703,11 +1703,11 @@
17031703
int to_rid = name_choice("to","to2",&zTo2); /* to= for path timelines */
17041704
int bShort = P("shortest")!=0; /* shortest possible path */
17051705
int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */
17061706
int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
17071707
int pd_rid;
1708
- const char *zDPName; /* Value of p=, d=, or dp= params */
1708
+ const char *zDPNameP, *zDPNameD; /* Value of p=, d=, or dp= params */
17091709
double rBefore, rAfter, rCirca; /* Boundary times */
17101710
const char *z;
17111711
char *zOlderButton = 0; /* URL for Older button at the bottom */
17121712
char *zOlderButtonLabel = 0; /* Label for the Older Button */
17131713
char *zNewerButton = 0; /* URL for Newer button at the top */
@@ -1770,20 +1770,20 @@
17701770
}else{
17711771
nEntry = 50;
17721772
}
17731773
17741774
/* Query parameters d=, p=, and f= and variants */
1775
- p_rid = name_choice("p","p2", &zDPName);
1776
- d_rid = name_choice("d","d2", &zDPName);
1775
+ p_rid = name_choice("p","p2", &zDPNameP);
1776
+ d_rid = name_choice("d","d2", &zDPNameD);
17771777
z = P("f");
17781778
f_rid = z ? name_to_typed_rid(z,"ci") : 0;
17791779
z = P("df");
17801780
if( z && (d_rid = name_to_typed_rid(z,"ci"))!=0 ){
17811781
nEntry = 0;
17821782
useDividers = 0;
17831783
cgi_replace_query_parameter("d",fossil_strdup(z));
1784
- zDPName = z;
1784
+ zDPNameD = zDPNameP = z;
17851785
}
17861786
17871787
/* Undocumented query parameter to set JS mode */
17881788
builtin_set_js_delivery_mode(P("jsmode"),1);
17891789
@@ -1803,13 +1803,14 @@
18031803
showCherrypicks = 0;
18041804
}
18051805
18061806
/* To view the timeline, must have permission to read project data.
18071807
*/
1808
- pd_rid = name_choice("dp","dp2",&zDPName);
1808
+ pd_rid = name_choice("dp","dp2",&zDPNameP);
18091809
if( pd_rid ){
18101810
p_rid = d_rid = pd_rid;
1811
+ zDPNameD = zDPNameP;
18111812
}
18121813
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
18131814
|| (bisectLocal && !g.perm.Setup)
18141815
){
18151816
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
@@ -2226,39 +2227,47 @@
22262227
}
22272228
}
22282229
}
22292230
addFileGlobDescription(zChng, &desc);
22302231
}else if( (p_rid || d_rid) && g.perm.Read && zTagSql==0 ){
2231
- /* If p= or d= is present, ignore all other parameters other than n= */
2232
- char *zUuid;
2233
- const char *zCiName;
2232
+ /* If either p= or d= or both are present, ignore all other parameters
2233
+ ** other than n=, ft=, and bt= */
2234
+ const char *zBaseName;
22342235
int np = 0, nd;
22352236
const char *zBackTo = 0;
22362237
const char *zFwdTo = 0;
22372238
int ridBackTo = 0;
22382239
int ridFwdTo = 0;
22392240
int bBackAdded = 0; /* True if the zBackTo node was added */
22402241
int bFwdAdded = 0; /* True if the zBackTo node was added */
2242
+ int bSeparateDandP = 0; /* p_rid & d_rid both exist and are distinct */
22412243
22422244
tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
2243
- if( p_rid && d_rid ){
2244
- if( p_rid!=d_rid ) p_rid = d_rid;
2245
- if( !haveParameterN ) nEntry = 10;
2245
+ if( p_rid && d_rid && p_rid!=d_rid ){
2246
+ bSeparateDandP = 1;
2247
+ db_multi_exec(
2248
+ "CREATE TEMP TABLE IF NOT EXISTS ok_d(rid INTEGER PRIMARY KEY)"
2249
+ );
2250
+ }else{
2251
+ zBaseName = p_rid ? zDPNameP : zDPNameD;
22462252
}
22472253
db_multi_exec(
2248
- "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
2254
+ "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
22492255
);
22502256
add_extra_rids("ok", P("x"));
2251
- zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
2252
- p_rid ? p_rid : d_rid);
2253
- zCiName = zDPName;
2254
- if( zCiName==0 ) zCiName = zUuid;
22552257
blob_append_sql(&sql, " AND event.objid IN ok");
22562258
nd = 0;
22572259
if( d_rid ){
22582260
double rStopTime = 9e99;
22592261
zFwdTo = P("ft");
2262
+ if( zFwdTo && bSeparateDandP ){
2263
+ if( zError==0 ){
2264
+ zError = "Cannot use the ft= query parameter when both p= and d= "
2265
+ "are used and have distinct values.";
2266
+ }
2267
+ zFwdTo = 0;
2268
+ }
22602269
if( zFwdTo ){
22612270
double rStartDate = mtime_of_rid(d_rid, 0.0);
22622271
ridFwdTo = first_checkin_with_tag_after_date(zFwdTo, rStartDate);
22632272
if( ridFwdTo==0 ){
22642273
ridFwdTo = name_to_typed_rid(zBackTo,"ci");
@@ -2265,10 +2274,13 @@
22652274
}
22662275
if( ridFwdTo ){
22672276
if( !haveParameterN ) nEntry = 0;
22682277
rStopTime = mtime_of_rid(ridFwdTo, 9e99);
22692278
}
2279
+ }else if( bSeparateDandP ){
2280
+ rStopTime = mtime_of_rid(p_rid, 9e99);
2281
+ nEntry = 0;
22702282
}
22712283
if( rStopTime<9e99 ){
22722284
rStopTime += 5.8e-6; /* Round up by 1/2 second */
22732285
}
22742286
db_multi_exec(
@@ -2285,49 +2297,85 @@
22852297
);
22862298
if( ridFwdTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridFwdTo) ){
22872299
db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridFwdTo);
22882300
bFwdAdded = 1;
22892301
}
2290
- nd = db_int(0, "SELECT count(*)-1 FROM ok");
2291
- if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
2292
- if( nd>0 || p_rid==0 ){
2293
- blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
2302
+ if( bSeparateDandP ){
2303
+ db_multi_exec(
2304
+ "INSERT INTO ok_d SELECT rid FROM ok;"
2305
+ "DELETE FROM ok;"
2306
+ );
2307
+ }else{
2308
+ nd = db_int(0, "SELECT count(*)-1 FROM ok");
2309
+ if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
2310
+ if( nd>0 || p_rid==0 ){
2311
+ blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
2312
+ }
2313
+ if( useDividers && !selectedRid ) selectedRid = d_rid;
2314
+ db_multi_exec("DELETE FROM ok");
22942315
}
2295
- if( useDividers && !selectedRid ) selectedRid = d_rid;
2296
- db_multi_exec("DELETE FROM ok");
22972316
}
22982317
if( p_rid ){
22992318
zBackTo = P("bt");
2319
+ if( zBackTo && bSeparateDandP ){
2320
+ if( zError==0 ){
2321
+ zError = "Cannot use the bt= query parameter when both p= and d= "
2322
+ "are used and have distinct values.";
2323
+ }
2324
+ zBackTo = 0;
2325
+ }
23002326
if( zBackTo ){
23012327
double rDateLimit = mtime_of_rid(p_rid, 0.0);
23022328
ridBackTo = last_checkin_with_tag_before_date(zBackTo, rDateLimit);
23032329
if( ridBackTo==0 ){
23042330
ridBackTo = name_to_typed_rid(zBackTo,"ci");
23052331
}
23062332
if( ridBackTo && !haveParameterN ) nEntry = 0;
2333
+ }else if( bSeparateDandP ){
2334
+ ridBackTo = d_rid;
2335
+ nEntry = 0;
23072336
}
23082337
compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
23092338
if( ridBackTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridBackTo) ){
23102339
db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
23112340
bBackAdded = 1;
23122341
}
2313
- np = db_int(0, "SELECT count(*)-1 FROM ok");
2314
- if( np>0 || nd==0 ){
2315
- if( nd>0 ) blob_appendf(&desc, " and ");
2316
- blob_appendf(&desc, "%d ancestor%s", np, (1==np)?"":"s");
2342
+ if( bSeparateDandP ){
2343
+ db_multi_exec("DELETE FROM ok WHERE rid NOT IN ok_d;");
23172344
db_multi_exec("%s", blob_sql_text(&sql));
2345
+ }else{
2346
+ np = db_int(0, "SELECT count(*)-1 FROM ok");
2347
+ if( np>0 || nd==0 ){
2348
+ if( nd>0 ) blob_appendf(&desc, " and ");
2349
+ blob_appendf(&desc, "%d ancestor%s", np, (1==np)?"":"s");
2350
+ db_multi_exec("%s", blob_sql_text(&sql));
2351
+ }
2352
+ if( useDividers && !selectedRid ) selectedRid = p_rid;
23182353
}
2319
- if( useDividers && !selectedRid ) selectedRid = p_rid;
23202354
}
2321
- blob_appendf(&desc, " of %z%h</a>",
2322
- href("%R/info?name=%h", zCiName), zCiName);
2355
+ if( bSeparateDandP ){
2356
+ int n = db_int(0, "SELECT count(*) FROM ok");
2357
+ blob_reset(&desc);
2358
+ blob_appendf(&desc,
2359
+ "%d check-ins that are both ancestors of %z%h</a>"
2360
+ " and descendents of %z%h</a>",
2361
+ n,
2362
+ href("%R/info?name=%h",zDPNameP),zDPNameP,
2363
+ href("%R/info/name=%h",zDPNameD),zDPNameD
2364
+ );
2365
+ ridBackTo = 0;
2366
+ ridFwdTo = 0;
2367
+ }else{
2368
+ blob_appendf(&desc, " of %z%h</a>",
2369
+ href("%R/info?name=%h", zBaseName), zBaseName);
2370
+ }
23232371
if( ridBackTo ){
23242372
if( np==0 ){
23252373
blob_reset(&desc);
23262374
blob_appendf(&desc,
23272375
"Check-in %z%h</a> only (%z%h</a> does not precede it)",
2328
- href("%R/info?name=%h",zCiName), zCiName,
2376
+ href("%R/info?name=%h",zBaseName), zBaseName,
23292377
href("%R/info?name=%h",zBackTo), zBackTo);
23302378
}else{
23312379
blob_appendf(&desc, " back to %z%h</a>%s",
23322380
href("%R/info?name=%h",zBackTo), zBackTo,
23332381
bBackAdded ? " (not a direct anscestor)" : "");
@@ -2340,24 +2388,18 @@
23402388
}else if( ridFwdTo ){
23412389
if( nd==0 ){
23422390
blob_reset(&desc);
23432391
blob_appendf(&desc,
23442392
"Check-in %z%h</a> only (%z%h</a> does not follow it)",
2345
- href("%R/info?name=%h",zCiName), zCiName,
2393
+ href("%R/info?name=%h",zBaseName), zBaseName,
23462394
href("%R/info?name=%h",zFwdTo), zFwdTo);
23472395
}else{
23482396
blob_appendf(&desc, " up to %z%h</a>%s",
23492397
href("%R/info?name=%h",zFwdTo), zFwdTo,
23502398
bFwdAdded ? " (not a direct descendent)":"");
23512399
}
23522400
}
2353
- if( d_rid ){
2354
- if( p_rid ){
2355
- /* If both p= and d= are set, we don't have the uuid of d yet. */
2356
- zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", d_rid);
2357
- }
2358
- }
23592401
if( advancedMenu ){
23602402
style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
23612403
}
23622404
style_submenu_entry("n","Max:",4,0);
23632405
timeline_y_submenu(1);
23642406
--- src/timeline.c
+++ src/timeline.c
@@ -1703,11 +1703,11 @@
1703 int to_rid = name_choice("to","to2",&zTo2); /* to= for path timelines */
1704 int bShort = P("shortest")!=0; /* shortest possible path */
1705 int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */
1706 int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
1707 int pd_rid;
1708 const char *zDPName; /* Value of p=, d=, or dp= params */
1709 double rBefore, rAfter, rCirca; /* Boundary times */
1710 const char *z;
1711 char *zOlderButton = 0; /* URL for Older button at the bottom */
1712 char *zOlderButtonLabel = 0; /* Label for the Older Button */
1713 char *zNewerButton = 0; /* URL for Newer button at the top */
@@ -1770,20 +1770,20 @@
1770 }else{
1771 nEntry = 50;
1772 }
1773
1774 /* Query parameters d=, p=, and f= and variants */
1775 p_rid = name_choice("p","p2", &zDPName);
1776 d_rid = name_choice("d","d2", &zDPName);
1777 z = P("f");
1778 f_rid = z ? name_to_typed_rid(z,"ci") : 0;
1779 z = P("df");
1780 if( z && (d_rid = name_to_typed_rid(z,"ci"))!=0 ){
1781 nEntry = 0;
1782 useDividers = 0;
1783 cgi_replace_query_parameter("d",fossil_strdup(z));
1784 zDPName = z;
1785 }
1786
1787 /* Undocumented query parameter to set JS mode */
1788 builtin_set_js_delivery_mode(P("jsmode"),1);
1789
@@ -1803,13 +1803,14 @@
1803 showCherrypicks = 0;
1804 }
1805
1806 /* To view the timeline, must have permission to read project data.
1807 */
1808 pd_rid = name_choice("dp","dp2",&zDPName);
1809 if( pd_rid ){
1810 p_rid = d_rid = pd_rid;
 
1811 }
1812 if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
1813 || (bisectLocal && !g.perm.Setup)
1814 ){
1815 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
@@ -2226,39 +2227,47 @@
2226 }
2227 }
2228 }
2229 addFileGlobDescription(zChng, &desc);
2230 }else if( (p_rid || d_rid) && g.perm.Read && zTagSql==0 ){
2231 /* If p= or d= is present, ignore all other parameters other than n= */
2232 char *zUuid;
2233 const char *zCiName;
2234 int np = 0, nd;
2235 const char *zBackTo = 0;
2236 const char *zFwdTo = 0;
2237 int ridBackTo = 0;
2238 int ridFwdTo = 0;
2239 int bBackAdded = 0; /* True if the zBackTo node was added */
2240 int bFwdAdded = 0; /* True if the zBackTo node was added */
 
2241
2242 tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
2243 if( p_rid && d_rid ){
2244 if( p_rid!=d_rid ) p_rid = d_rid;
2245 if( !haveParameterN ) nEntry = 10;
 
 
 
 
2246 }
2247 db_multi_exec(
2248 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
2249 );
2250 add_extra_rids("ok", P("x"));
2251 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
2252 p_rid ? p_rid : d_rid);
2253 zCiName = zDPName;
2254 if( zCiName==0 ) zCiName = zUuid;
2255 blob_append_sql(&sql, " AND event.objid IN ok");
2256 nd = 0;
2257 if( d_rid ){
2258 double rStopTime = 9e99;
2259 zFwdTo = P("ft");
 
 
 
 
 
 
 
2260 if( zFwdTo ){
2261 double rStartDate = mtime_of_rid(d_rid, 0.0);
2262 ridFwdTo = first_checkin_with_tag_after_date(zFwdTo, rStartDate);
2263 if( ridFwdTo==0 ){
2264 ridFwdTo = name_to_typed_rid(zBackTo,"ci");
@@ -2265,10 +2274,13 @@
2265 }
2266 if( ridFwdTo ){
2267 if( !haveParameterN ) nEntry = 0;
2268 rStopTime = mtime_of_rid(ridFwdTo, 9e99);
2269 }
 
 
 
2270 }
2271 if( rStopTime<9e99 ){
2272 rStopTime += 5.8e-6; /* Round up by 1/2 second */
2273 }
2274 db_multi_exec(
@@ -2285,49 +2297,85 @@
2285 );
2286 if( ridFwdTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridFwdTo) ){
2287 db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridFwdTo);
2288 bFwdAdded = 1;
2289 }
2290 nd = db_int(0, "SELECT count(*)-1 FROM ok");
2291 if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
2292 if( nd>0 || p_rid==0 ){
2293 blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
 
 
 
 
 
 
 
 
 
2294 }
2295 if( useDividers && !selectedRid ) selectedRid = d_rid;
2296 db_multi_exec("DELETE FROM ok");
2297 }
2298 if( p_rid ){
2299 zBackTo = P("bt");
 
 
 
 
 
 
 
2300 if( zBackTo ){
2301 double rDateLimit = mtime_of_rid(p_rid, 0.0);
2302 ridBackTo = last_checkin_with_tag_before_date(zBackTo, rDateLimit);
2303 if( ridBackTo==0 ){
2304 ridBackTo = name_to_typed_rid(zBackTo,"ci");
2305 }
2306 if( ridBackTo && !haveParameterN ) nEntry = 0;
 
 
 
2307 }
2308 compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
2309 if( ridBackTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridBackTo) ){
2310 db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
2311 bBackAdded = 1;
2312 }
2313 np = db_int(0, "SELECT count(*)-1 FROM ok");
2314 if( np>0 || nd==0 ){
2315 if( nd>0 ) blob_appendf(&desc, " and ");
2316 blob_appendf(&desc, "%d ancestor%s", np, (1==np)?"":"s");
2317 db_multi_exec("%s", blob_sql_text(&sql));
 
 
 
 
 
 
 
 
2318 }
2319 if( useDividers && !selectedRid ) selectedRid = p_rid;
2320 }
2321 blob_appendf(&desc, " of %z%h</a>",
2322 href("%R/info?name=%h", zCiName), zCiName);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2323 if( ridBackTo ){
2324 if( np==0 ){
2325 blob_reset(&desc);
2326 blob_appendf(&desc,
2327 "Check-in %z%h</a> only (%z%h</a> does not precede it)",
2328 href("%R/info?name=%h",zCiName), zCiName,
2329 href("%R/info?name=%h",zBackTo), zBackTo);
2330 }else{
2331 blob_appendf(&desc, " back to %z%h</a>%s",
2332 href("%R/info?name=%h",zBackTo), zBackTo,
2333 bBackAdded ? " (not a direct anscestor)" : "");
@@ -2340,24 +2388,18 @@
2340 }else if( ridFwdTo ){
2341 if( nd==0 ){
2342 blob_reset(&desc);
2343 blob_appendf(&desc,
2344 "Check-in %z%h</a> only (%z%h</a> does not follow it)",
2345 href("%R/info?name=%h",zCiName), zCiName,
2346 href("%R/info?name=%h",zFwdTo), zFwdTo);
2347 }else{
2348 blob_appendf(&desc, " up to %z%h</a>%s",
2349 href("%R/info?name=%h",zFwdTo), zFwdTo,
2350 bFwdAdded ? " (not a direct descendent)":"");
2351 }
2352 }
2353 if( d_rid ){
2354 if( p_rid ){
2355 /* If both p= and d= are set, we don't have the uuid of d yet. */
2356 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", d_rid);
2357 }
2358 }
2359 if( advancedMenu ){
2360 style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
2361 }
2362 style_submenu_entry("n","Max:",4,0);
2363 timeline_y_submenu(1);
2364
--- src/timeline.c
+++ src/timeline.c
@@ -1703,11 +1703,11 @@
1703 int to_rid = name_choice("to","to2",&zTo2); /* to= for path timelines */
1704 int bShort = P("shortest")!=0; /* shortest possible path */
1705 int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */
1706 int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
1707 int pd_rid;
1708 const char *zDPNameP, *zDPNameD; /* Value of p=, d=, or dp= params */
1709 double rBefore, rAfter, rCirca; /* Boundary times */
1710 const char *z;
1711 char *zOlderButton = 0; /* URL for Older button at the bottom */
1712 char *zOlderButtonLabel = 0; /* Label for the Older Button */
1713 char *zNewerButton = 0; /* URL for Newer button at the top */
@@ -1770,20 +1770,20 @@
1770 }else{
1771 nEntry = 50;
1772 }
1773
1774 /* Query parameters d=, p=, and f= and variants */
1775 p_rid = name_choice("p","p2", &zDPNameP);
1776 d_rid = name_choice("d","d2", &zDPNameD);
1777 z = P("f");
1778 f_rid = z ? name_to_typed_rid(z,"ci") : 0;
1779 z = P("df");
1780 if( z && (d_rid = name_to_typed_rid(z,"ci"))!=0 ){
1781 nEntry = 0;
1782 useDividers = 0;
1783 cgi_replace_query_parameter("d",fossil_strdup(z));
1784 zDPNameD = zDPNameP = z;
1785 }
1786
1787 /* Undocumented query parameter to set JS mode */
1788 builtin_set_js_delivery_mode(P("jsmode"),1);
1789
@@ -1803,13 +1803,14 @@
1803 showCherrypicks = 0;
1804 }
1805
1806 /* To view the timeline, must have permission to read project data.
1807 */
1808 pd_rid = name_choice("dp","dp2",&zDPNameP);
1809 if( pd_rid ){
1810 p_rid = d_rid = pd_rid;
1811 zDPNameD = zDPNameP;
1812 }
1813 if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
1814 || (bisectLocal && !g.perm.Setup)
1815 ){
1816 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
@@ -2226,39 +2227,47 @@
2227 }
2228 }
2229 }
2230 addFileGlobDescription(zChng, &desc);
2231 }else if( (p_rid || d_rid) && g.perm.Read && zTagSql==0 ){
2232 /* If either p= or d= or both are present, ignore all other parameters
2233 ** other than n=, ft=, and bt= */
2234 const char *zBaseName;
2235 int np = 0, nd;
2236 const char *zBackTo = 0;
2237 const char *zFwdTo = 0;
2238 int ridBackTo = 0;
2239 int ridFwdTo = 0;
2240 int bBackAdded = 0; /* True if the zBackTo node was added */
2241 int bFwdAdded = 0; /* True if the zBackTo node was added */
2242 int bSeparateDandP = 0; /* p_rid & d_rid both exist and are distinct */
2243
2244 tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
2245 if( p_rid && d_rid && p_rid!=d_rid ){
2246 bSeparateDandP = 1;
2247 db_multi_exec(
2248 "CREATE TEMP TABLE IF NOT EXISTS ok_d(rid INTEGER PRIMARY KEY)"
2249 );
2250 }else{
2251 zBaseName = p_rid ? zDPNameP : zDPNameD;
2252 }
2253 db_multi_exec(
2254 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
2255 );
2256 add_extra_rids("ok", P("x"));
 
 
 
 
2257 blob_append_sql(&sql, " AND event.objid IN ok");
2258 nd = 0;
2259 if( d_rid ){
2260 double rStopTime = 9e99;
2261 zFwdTo = P("ft");
2262 if( zFwdTo && bSeparateDandP ){
2263 if( zError==0 ){
2264 zError = "Cannot use the ft= query parameter when both p= and d= "
2265 "are used and have distinct values.";
2266 }
2267 zFwdTo = 0;
2268 }
2269 if( zFwdTo ){
2270 double rStartDate = mtime_of_rid(d_rid, 0.0);
2271 ridFwdTo = first_checkin_with_tag_after_date(zFwdTo, rStartDate);
2272 if( ridFwdTo==0 ){
2273 ridFwdTo = name_to_typed_rid(zBackTo,"ci");
@@ -2265,10 +2274,13 @@
2274 }
2275 if( ridFwdTo ){
2276 if( !haveParameterN ) nEntry = 0;
2277 rStopTime = mtime_of_rid(ridFwdTo, 9e99);
2278 }
2279 }else if( bSeparateDandP ){
2280 rStopTime = mtime_of_rid(p_rid, 9e99);
2281 nEntry = 0;
2282 }
2283 if( rStopTime<9e99 ){
2284 rStopTime += 5.8e-6; /* Round up by 1/2 second */
2285 }
2286 db_multi_exec(
@@ -2285,49 +2297,85 @@
2297 );
2298 if( ridFwdTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridFwdTo) ){
2299 db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridFwdTo);
2300 bFwdAdded = 1;
2301 }
2302 if( bSeparateDandP ){
2303 db_multi_exec(
2304 "INSERT INTO ok_d SELECT rid FROM ok;"
2305 "DELETE FROM ok;"
2306 );
2307 }else{
2308 nd = db_int(0, "SELECT count(*)-1 FROM ok");
2309 if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
2310 if( nd>0 || p_rid==0 ){
2311 blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
2312 }
2313 if( useDividers && !selectedRid ) selectedRid = d_rid;
2314 db_multi_exec("DELETE FROM ok");
2315 }
 
 
2316 }
2317 if( p_rid ){
2318 zBackTo = P("bt");
2319 if( zBackTo && bSeparateDandP ){
2320 if( zError==0 ){
2321 zError = "Cannot use the bt= query parameter when both p= and d= "
2322 "are used and have distinct values.";
2323 }
2324 zBackTo = 0;
2325 }
2326 if( zBackTo ){
2327 double rDateLimit = mtime_of_rid(p_rid, 0.0);
2328 ridBackTo = last_checkin_with_tag_before_date(zBackTo, rDateLimit);
2329 if( ridBackTo==0 ){
2330 ridBackTo = name_to_typed_rid(zBackTo,"ci");
2331 }
2332 if( ridBackTo && !haveParameterN ) nEntry = 0;
2333 }else if( bSeparateDandP ){
2334 ridBackTo = d_rid;
2335 nEntry = 0;
2336 }
2337 compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
2338 if( ridBackTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridBackTo) ){
2339 db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
2340 bBackAdded = 1;
2341 }
2342 if( bSeparateDandP ){
2343 db_multi_exec("DELETE FROM ok WHERE rid NOT IN ok_d;");
 
 
2344 db_multi_exec("%s", blob_sql_text(&sql));
2345 }else{
2346 np = db_int(0, "SELECT count(*)-1 FROM ok");
2347 if( np>0 || nd==0 ){
2348 if( nd>0 ) blob_appendf(&desc, " and ");
2349 blob_appendf(&desc, "%d ancestor%s", np, (1==np)?"":"s");
2350 db_multi_exec("%s", blob_sql_text(&sql));
2351 }
2352 if( useDividers && !selectedRid ) selectedRid = p_rid;
2353 }
 
2354 }
2355 if( bSeparateDandP ){
2356 int n = db_int(0, "SELECT count(*) FROM ok");
2357 blob_reset(&desc);
2358 blob_appendf(&desc,
2359 "%d check-ins that are both ancestors of %z%h</a>"
2360 " and descendents of %z%h</a>",
2361 n,
2362 href("%R/info?name=%h",zDPNameP),zDPNameP,
2363 href("%R/info/name=%h",zDPNameD),zDPNameD
2364 );
2365 ridBackTo = 0;
2366 ridFwdTo = 0;
2367 }else{
2368 blob_appendf(&desc, " of %z%h</a>",
2369 href("%R/info?name=%h", zBaseName), zBaseName);
2370 }
2371 if( ridBackTo ){
2372 if( np==0 ){
2373 blob_reset(&desc);
2374 blob_appendf(&desc,
2375 "Check-in %z%h</a> only (%z%h</a> does not precede it)",
2376 href("%R/info?name=%h",zBaseName), zBaseName,
2377 href("%R/info?name=%h",zBackTo), zBackTo);
2378 }else{
2379 blob_appendf(&desc, " back to %z%h</a>%s",
2380 href("%R/info?name=%h",zBackTo), zBackTo,
2381 bBackAdded ? " (not a direct anscestor)" : "");
@@ -2340,24 +2388,18 @@
2388 }else if( ridFwdTo ){
2389 if( nd==0 ){
2390 blob_reset(&desc);
2391 blob_appendf(&desc,
2392 "Check-in %z%h</a> only (%z%h</a> does not follow it)",
2393 href("%R/info?name=%h",zBaseName), zBaseName,
2394 href("%R/info?name=%h",zFwdTo), zFwdTo);
2395 }else{
2396 blob_appendf(&desc, " up to %z%h</a>%s",
2397 href("%R/info?name=%h",zFwdTo), zFwdTo,
2398 bFwdAdded ? " (not a direct descendent)":"");
2399 }
2400 }
 
 
 
 
 
 
2401 if( advancedMenu ){
2402 style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
2403 }
2404 style_submenu_entry("n","Max:",4,0);
2405 timeline_y_submenu(1);
2406

Keyboard Shortcuts

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