Fossil SCM

For the bt=Y query parameter in /timeline that is used in conjunction with p=X, if Y is a tag then search backwards in time for Y beginning with X. Fix for ticket [ed62a4d35332595a].

drh 2023-03-24 15:22 trunk
Commit 507ebd8b3f37e5dfcb675bf59ef2ae5376c6b799a44a32720c34a52ba9e08e82
2 files changed +47 +10 -1
+47
--- src/name.c
+++ src/name.c
@@ -243,10 +243,57 @@
243243
" ORDER BY event.mtime DESC LIMIT 1"
244244
") LIMIT 1;",
245245
zType, zTag, zTag, zType
246246
);
247247
}
248
+
249
+/*
250
+** Find the RID for a check-in that is the most recent check-in with
251
+** tag zTag that occurs on or prior to rDate.
252
+**
253
+** See also the performance note on most_recent_event_with_tag() which
254
+** applies to this routine too.
255
+*/
256
+int most_recent_checkin_with_tag_before_date(const char *zTag, double rLimit){
257
+ Stmt s;
258
+ int rid = 0;
259
+ if( strncmp(zTag, "tag:", 4)==0 ) zTag += 4;
260
+ db_prepare(&s,
261
+ "SELECT objid FROM ("
262
+ /* Q1: Begin by looking for the tag in the 30 most recent events */
263
+ "SELECT objid"
264
+ " FROM (SELECT * FROM event WHERE mtime<=:datelimit"
265
+ " ORDER BY mtime DESC LIMIT 30) AS ex"
266
+ " WHERE type='ci'"
267
+ " AND EXISTS(SELECT 1 FROM tagxref, tag"
268
+ " WHERE tag.tagname='sym-%q'"
269
+ " AND tagxref.tagid=tag.tagid"
270
+ " AND tagxref.tagtype>0"
271
+ " AND tagxref.rid=ex.objid)"
272
+ " ORDER BY mtime DESC LIMIT 1"
273
+ ") UNION ALL SELECT * FROM ("
274
+ /* Q2: If the tag is not found in the 30 most recent events, then using
275
+ ** the tagxref table to index for the tag */
276
+ "SELECT event.objid"
277
+ " FROM tag, tagxref, event"
278
+ " WHERE tag.tagname='sym-%q'"
279
+ " AND tagxref.tagid=tag.tagid"
280
+ " AND tagxref.tagtype>0"
281
+ " AND event.objid=tagxref.rid"
282
+ " AND event.type='ci'"
283
+ " AND event.mtime<=:datelimit"
284
+ " ORDER BY event.mtime DESC LIMIT 1"
285
+ ") LIMIT 1;",
286
+ zTag, zTag
287
+ );
288
+ db_bind_double(&s, ":datelimit", rLimit);
289
+ if( db_step(&s)==SQLITE_ROW ){
290
+ rid = db_column_int(&s,0);
291
+ }
292
+ db_finalize(&s);
293
+ return rid;
294
+}
248295
249296
/*
250297
** Return true if character "c" is a character that might have been
251298
** accidentally appended to the end of a URL.
252299
*/
253300
--- src/name.c
+++ src/name.c
@@ -243,10 +243,57 @@
243 " ORDER BY event.mtime DESC LIMIT 1"
244 ") LIMIT 1;",
245 zType, zTag, zTag, zType
246 );
247 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
249 /*
250 ** Return true if character "c" is a character that might have been
251 ** accidentally appended to the end of a URL.
252 */
253
--- src/name.c
+++ src/name.c
@@ -243,10 +243,57 @@
243 " ORDER BY event.mtime DESC LIMIT 1"
244 ") LIMIT 1;",
245 zType, zTag, zTag, zType
246 );
247 }
248
249 /*
250 ** Find the RID for a check-in that is the most recent check-in with
251 ** tag zTag that occurs on or prior to rDate.
252 **
253 ** See also the performance note on most_recent_event_with_tag() which
254 ** applies to this routine too.
255 */
256 int most_recent_checkin_with_tag_before_date(const char *zTag, double rLimit){
257 Stmt s;
258 int rid = 0;
259 if( strncmp(zTag, "tag:", 4)==0 ) zTag += 4;
260 db_prepare(&s,
261 "SELECT objid FROM ("
262 /* Q1: Begin by looking for the tag in the 30 most recent events */
263 "SELECT objid"
264 " FROM (SELECT * FROM event WHERE mtime<=:datelimit"
265 " ORDER BY mtime DESC LIMIT 30) AS ex"
266 " WHERE type='ci'"
267 " AND EXISTS(SELECT 1 FROM tagxref, tag"
268 " WHERE tag.tagname='sym-%q'"
269 " AND tagxref.tagid=tag.tagid"
270 " AND tagxref.tagtype>0"
271 " AND tagxref.rid=ex.objid)"
272 " ORDER BY mtime DESC LIMIT 1"
273 ") UNION ALL SELECT * FROM ("
274 /* Q2: If the tag is not found in the 30 most recent events, then using
275 ** the tagxref table to index for the tag */
276 "SELECT event.objid"
277 " FROM tag, tagxref, event"
278 " WHERE tag.tagname='sym-%q'"
279 " AND tagxref.tagid=tag.tagid"
280 " AND tagxref.tagtype>0"
281 " AND event.objid=tagxref.rid"
282 " AND event.type='ci'"
283 " AND event.mtime<=:datelimit"
284 " ORDER BY event.mtime DESC LIMIT 1"
285 ") LIMIT 1;",
286 zTag, zTag
287 );
288 db_bind_double(&s, ":datelimit", rLimit);
289 if( db_step(&s)==SQLITE_ROW ){
290 rid = db_column_int(&s,0);
291 }
292 db_finalize(&s);
293 return rid;
294 }
295
296 /*
297 ** Return true if character "c" is a character that might have been
298 ** accidentally appended to the end of a URL.
299 */
300
+10 -1
--- src/timeline.c
+++ src/timeline.c
@@ -2116,12 +2116,21 @@
21162116
}
21172117
if( useDividers && !selectedRid ) selectedRid = d_rid;
21182118
db_multi_exec("DELETE FROM ok");
21192119
}
21202120
if( p_rid ){
2121
+ ridBackTo = 0;
21212122
zBackTo = P("bt");
2122
- ridBackTo = zBackTo ? name_to_typed_rid(zBackTo,"ci") : 0;
2123
+ if( zBackTo ){
2124
+ double rDateLimit = db_double(0.0,
2125
+ "SELECT mtime FROM event WHERE objid=%d", p_rid);
2126
+ ridBackTo =
2127
+ most_recent_checkin_with_tag_before_date(zBackTo, rDateLimit);
2128
+ if( ridBackTo==0 ){
2129
+ ridBackTo = name_to_typed_rid(zBackTo,"ci");
2130
+ }
2131
+ }
21232132
if( ridBackTo && !haveParameterN ) nEntry = 0;
21242133
compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
21252134
np = db_int(0, "SELECT count(*)-1 FROM ok");
21262135
if( np>0 || nd==0 ){
21272136
if( nd>0 ) blob_appendf(&desc, " and ");
21282137
--- src/timeline.c
+++ src/timeline.c
@@ -2116,12 +2116,21 @@
2116 }
2117 if( useDividers && !selectedRid ) selectedRid = d_rid;
2118 db_multi_exec("DELETE FROM ok");
2119 }
2120 if( p_rid ){
 
2121 zBackTo = P("bt");
2122 ridBackTo = zBackTo ? name_to_typed_rid(zBackTo,"ci") : 0;
 
 
 
 
 
 
 
 
2123 if( ridBackTo && !haveParameterN ) nEntry = 0;
2124 compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
2125 np = db_int(0, "SELECT count(*)-1 FROM ok");
2126 if( np>0 || nd==0 ){
2127 if( nd>0 ) blob_appendf(&desc, " and ");
2128
--- src/timeline.c
+++ src/timeline.c
@@ -2116,12 +2116,21 @@
2116 }
2117 if( useDividers && !selectedRid ) selectedRid = d_rid;
2118 db_multi_exec("DELETE FROM ok");
2119 }
2120 if( p_rid ){
2121 ridBackTo = 0;
2122 zBackTo = P("bt");
2123 if( zBackTo ){
2124 double rDateLimit = db_double(0.0,
2125 "SELECT mtime FROM event WHERE objid=%d", p_rid);
2126 ridBackTo =
2127 most_recent_checkin_with_tag_before_date(zBackTo, rDateLimit);
2128 if( ridBackTo==0 ){
2129 ridBackTo = name_to_typed_rid(zBackTo,"ci");
2130 }
2131 }
2132 if( ridBackTo && !haveParameterN ) nEntry = 0;
2133 compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
2134 np = db_int(0, "SELECT count(*)-1 FROM ok");
2135 if( np>0 || nd==0 ){
2136 if( nd>0 ) blob_appendf(&desc, " and ");
2137

Keyboard Shortcuts

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