Fossil SCM

Enhance the "showsql" query parameter on /timeline to show the complete SQL needed to generate the timeline, including all temp tables creation and initialization.

drh 2024-12-23 12:52 trunk
Commit ebd239de02c4b9f282f1d0bf3cb257e5149568e9f41a6de50d41a79b560462ec
+26 -23
--- src/bisect.c
+++ src/bisect.c
@@ -197,10 +197,26 @@
197197
static void bisect_append_skip(int rid){
198198
db_multi_exec(
199199
"UPDATE vvar SET value=value||' s%d' WHERE name='bisect-log'", rid
200200
);
201201
}
202
+
203
+/*
204
+** Append a VALUES entry to the bilog table insert
205
+*/
206
+static void bisect_log_append(Blob *pSql,int iSeq,const char *zStat,int iRid){
207
+ if( (iSeq%6)==3 ){
208
+ blob_append_sql(pSql, ",\n ");
209
+ }else if( iSeq>1 ){
210
+ blob_append_sql(pSql, ",");
211
+ }
212
+ if( zStat ){
213
+ blob_append_sql(pSql, "(%d,%Q,%d)", iSeq, zStat, iRid);
214
+ }else{
215
+ blob_append_sql(pSql, "(NULL,NULL,%d)", iRid);
216
+ }
217
+}
202218
203219
/*
204220
** Create a TEMP table named "bilog" that contains the complete history
205221
** of the current bisect.
206222
**
@@ -215,14 +231,14 @@
215231
** in between the inner-most GOOD and BAD nodes.
216232
*/
217233
int bisect_create_bilog_table(int iCurrent, const char *zDesc, int bDetail){
218234
char *zLog;
219235
Blob log, id;
220
- Stmt q;
221236
int cnt = 0;
222237
int lastGood = -1;
223238
int lastBad = -1;
239
+ Blob ins = BLOB_INITIALIZER;
224240
225241
if( zDesc!=0 ){
226242
blob_init(&log, 0, 0);
227243
while( zDesc[0]=='y' || zDesc[0]=='n' || zDesc[0]=='s' ){
228244
int i;
@@ -253,55 +269,42 @@
253269
" rid INTEGER PRIMARY KEY," /* Sequence of events */
254270
" stat TEXT," /* Type of occurrence */
255271
" seq INTEGER UNIQUE" /* Check-in number */
256272
");"
257273
);
258
- db_prepare(&q, "INSERT OR IGNORE INTO bilog(seq,stat,rid)"
259
- " VALUES(:seq,:stat,:rid)");
274
+ blob_append_sql(&ins, "INSERT OR IGNORE INTO bilog(seq,stat,rid) VALUES");
260275
while( blob_token(&log, &id) ){
261276
int rid;
262
- db_bind_int(&q, ":seq", ++cnt);
277
+ cnt++;
263278
if( blob_str(&id)[0]=='s' ){
264279
rid = atoi(blob_str(&id)+1);
265
- db_bind_text(&q, ":stat", "SKIP");
266
- db_bind_int(&q, ":rid", rid);
280
+ bisect_log_append(&ins, cnt, "SKIP", rid);
267281
}else{
268282
rid = atoi(blob_str(&id));
269283
if( rid>0 ){
270
- db_bind_text(&q, ":stat","GOOD");
271
- db_bind_int(&q, ":rid", rid);
284
+ bisect_log_append(&ins, cnt, "GOOD", rid);
272285
lastGood = rid;
273286
}else{
274
- db_bind_text(&q, ":stat", "BAD");
275
- db_bind_int(&q, ":rid", -rid);
287
+ bisect_log_append(&ins, cnt, "BAD", rid);
276288
lastBad = -rid;
277289
}
278290
}
279
- db_step(&q);
280
- db_reset(&q);
281291
}
282292
if( iCurrent>0 ){
283
- db_bind_int(&q, ":seq", ++cnt);
284
- db_bind_text(&q, ":stat", "CURRENT");
285
- db_bind_int(&q, ":rid", iCurrent);
286
- db_step(&q);
287
- db_reset(&q);
293
+ bisect_log_append(&ins, ++cnt, "CURRENT", iCurrent);
288294
}
289295
if( bDetail && lastGood>0 && lastBad>0 ){
290296
PathNode *p;
291297
p = path_shortest(lastGood, lastBad, bisect_option("direct-only"),0, 0);
292298
while( p ){
293
- db_bind_null(&q, ":seq");
294
- db_bind_null(&q, ":stat");
295
- db_bind_int(&q, ":rid", p->rid);
296
- db_step(&q);
297
- db_reset(&q);
299
+ bisect_log_append(&ins, ++cnt, 0, p->rid);
298300
p = p->u.pTo;
299301
}
300302
path_reset();
301303
}
302
- db_finalize(&q);
304
+ db_exec_sql(blob_sql_text(&ins));
305
+ blob_reset(&ins);
303306
return 1;
304307
}
305308
306309
/* Return a permalink description of a bisect. Space is obtained from
307310
** fossil_malloc() and should be freed by the caller.
308311
--- src/bisect.c
+++ src/bisect.c
@@ -197,10 +197,26 @@
197 static void bisect_append_skip(int rid){
198 db_multi_exec(
199 "UPDATE vvar SET value=value||' s%d' WHERE name='bisect-log'", rid
200 );
201 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
203 /*
204 ** Create a TEMP table named "bilog" that contains the complete history
205 ** of the current bisect.
206 **
@@ -215,14 +231,14 @@
215 ** in between the inner-most GOOD and BAD nodes.
216 */
217 int bisect_create_bilog_table(int iCurrent, const char *zDesc, int bDetail){
218 char *zLog;
219 Blob log, id;
220 Stmt q;
221 int cnt = 0;
222 int lastGood = -1;
223 int lastBad = -1;
 
224
225 if( zDesc!=0 ){
226 blob_init(&log, 0, 0);
227 while( zDesc[0]=='y' || zDesc[0]=='n' || zDesc[0]=='s' ){
228 int i;
@@ -253,55 +269,42 @@
253 " rid INTEGER PRIMARY KEY," /* Sequence of events */
254 " stat TEXT," /* Type of occurrence */
255 " seq INTEGER UNIQUE" /* Check-in number */
256 ");"
257 );
258 db_prepare(&q, "INSERT OR IGNORE INTO bilog(seq,stat,rid)"
259 " VALUES(:seq,:stat,:rid)");
260 while( blob_token(&log, &id) ){
261 int rid;
262 db_bind_int(&q, ":seq", ++cnt);
263 if( blob_str(&id)[0]=='s' ){
264 rid = atoi(blob_str(&id)+1);
265 db_bind_text(&q, ":stat", "SKIP");
266 db_bind_int(&q, ":rid", rid);
267 }else{
268 rid = atoi(blob_str(&id));
269 if( rid>0 ){
270 db_bind_text(&q, ":stat","GOOD");
271 db_bind_int(&q, ":rid", rid);
272 lastGood = rid;
273 }else{
274 db_bind_text(&q, ":stat", "BAD");
275 db_bind_int(&q, ":rid", -rid);
276 lastBad = -rid;
277 }
278 }
279 db_step(&q);
280 db_reset(&q);
281 }
282 if( iCurrent>0 ){
283 db_bind_int(&q, ":seq", ++cnt);
284 db_bind_text(&q, ":stat", "CURRENT");
285 db_bind_int(&q, ":rid", iCurrent);
286 db_step(&q);
287 db_reset(&q);
288 }
289 if( bDetail && lastGood>0 && lastBad>0 ){
290 PathNode *p;
291 p = path_shortest(lastGood, lastBad, bisect_option("direct-only"),0, 0);
292 while( p ){
293 db_bind_null(&q, ":seq");
294 db_bind_null(&q, ":stat");
295 db_bind_int(&q, ":rid", p->rid);
296 db_step(&q);
297 db_reset(&q);
298 p = p->u.pTo;
299 }
300 path_reset();
301 }
302 db_finalize(&q);
 
303 return 1;
304 }
305
306 /* Return a permalink description of a bisect. Space is obtained from
307 ** fossil_malloc() and should be freed by the caller.
308
--- src/bisect.c
+++ src/bisect.c
@@ -197,10 +197,26 @@
197 static void bisect_append_skip(int rid){
198 db_multi_exec(
199 "UPDATE vvar SET value=value||' s%d' WHERE name='bisect-log'", rid
200 );
201 }
202
203 /*
204 ** Append a VALUES entry to the bilog table insert
205 */
206 static void bisect_log_append(Blob *pSql,int iSeq,const char *zStat,int iRid){
207 if( (iSeq%6)==3 ){
208 blob_append_sql(pSql, ",\n ");
209 }else if( iSeq>1 ){
210 blob_append_sql(pSql, ",");
211 }
212 if( zStat ){
213 blob_append_sql(pSql, "(%d,%Q,%d)", iSeq, zStat, iRid);
214 }else{
215 blob_append_sql(pSql, "(NULL,NULL,%d)", iRid);
216 }
217 }
218
219 /*
220 ** Create a TEMP table named "bilog" that contains the complete history
221 ** of the current bisect.
222 **
@@ -215,14 +231,14 @@
231 ** in between the inner-most GOOD and BAD nodes.
232 */
233 int bisect_create_bilog_table(int iCurrent, const char *zDesc, int bDetail){
234 char *zLog;
235 Blob log, id;
 
236 int cnt = 0;
237 int lastGood = -1;
238 int lastBad = -1;
239 Blob ins = BLOB_INITIALIZER;
240
241 if( zDesc!=0 ){
242 blob_init(&log, 0, 0);
243 while( zDesc[0]=='y' || zDesc[0]=='n' || zDesc[0]=='s' ){
244 int i;
@@ -253,55 +269,42 @@
269 " rid INTEGER PRIMARY KEY," /* Sequence of events */
270 " stat TEXT," /* Type of occurrence */
271 " seq INTEGER UNIQUE" /* Check-in number */
272 ");"
273 );
274 blob_append_sql(&ins, "INSERT OR IGNORE INTO bilog(seq,stat,rid) VALUES");
 
275 while( blob_token(&log, &id) ){
276 int rid;
277 cnt++;
278 if( blob_str(&id)[0]=='s' ){
279 rid = atoi(blob_str(&id)+1);
280 bisect_log_append(&ins, cnt, "SKIP", rid);
 
281 }else{
282 rid = atoi(blob_str(&id));
283 if( rid>0 ){
284 bisect_log_append(&ins, cnt, "GOOD", rid);
 
285 lastGood = rid;
286 }else{
287 bisect_log_append(&ins, cnt, "BAD", rid);
 
288 lastBad = -rid;
289 }
290 }
 
 
291 }
292 if( iCurrent>0 ){
293 bisect_log_append(&ins, ++cnt, "CURRENT", iCurrent);
 
 
 
 
294 }
295 if( bDetail && lastGood>0 && lastBad>0 ){
296 PathNode *p;
297 p = path_shortest(lastGood, lastBad, bisect_option("direct-only"),0, 0);
298 while( p ){
299 bisect_log_append(&ins, ++cnt, 0, p->rid);
 
 
 
 
300 p = p->u.pTo;
301 }
302 path_reset();
303 }
304 db_exec_sql(blob_sql_text(&ins));
305 blob_reset(&ins);
306 return 1;
307 }
308
309 /* Return a permalink description of a bisect. Space is obtained from
310 ** fossil_malloc() and should be freed by the caller.
311
+37
--- src/db.c
+++ src/db.c
@@ -170,10 +170,12 @@
170170
void *pAuthArg; /* Argument to the authorizer */
171171
const char *zAuthName; /* Name of the authorizer */
172172
int bProtectTriggers; /* True if protection triggers already exist */
173173
int nProtect; /* Slots of aProtect used */
174174
unsigned aProtect[12]; /* Saved values of protectMask */
175
+ int pauseDmlLog; /* Ignore pDmlLog if positive */
176
+ Blob *pDmlLog; /* Append DML statements here, of not NULL */
175177
} db = {
176178
PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
177179
0, 0, 0, 0, 0, 0, 0, {{0}}, {0}, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}};
178180
179181
/*
@@ -643,10 +645,43 @@
643645
*/
644646
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
645647
#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
646648
#endif
647649
650
+/*
651
+** If zSql is a DML statement, append it db.pDmlLog.
652
+*/
653
+static void db_append_dml(const char *zSql){
654
+ size_t nSql;
655
+ if( db.pDmlLog==0 ) return;
656
+ if( db.pauseDmlLog ) return;
657
+ if( zSql==0 ) return;
658
+ nSql = strlen(zSql);
659
+ while( nSql>0 && fossil_isspace(zSql[0]) ){ nSql--; zSql++; }
660
+ while( nSql>0 && fossil_isspace(zSql[nSql-1]) ) nSql--;
661
+ if( nSql<6 ) return;
662
+ if( strncmp(zSql, "SELECT", 6)==0 ) return;
663
+ if( strncmp(zSql, "PRAGMA", 6)==0 ) return;
664
+ blob_append(db.pDmlLog, zSql, nSql);
665
+ if( zSql[nSql-1]!=';' ) blob_append_char(db.pDmlLog, ';');
666
+ blob_append_char(db.pDmlLog, '\n');
667
+}
668
+
669
+/*
670
+** Set the Blob to which DML statement text should be appended. Set it
671
+** to zero to stop appending DML statement text.
672
+*/
673
+void db_append_dml_to_blob(Blob *pBlob){
674
+ db.pDmlLog = pBlob;
675
+}
676
+
677
+/*
678
+** Pause or unpause the DML log
679
+*/
680
+void db_pause_dml_log(void){ db.pauseDmlLog++; }
681
+void db_unpause_dml_log(void){ db.pauseDmlLog--; }
682
+
648683
/*
649684
** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
650685
** If the input string contains multiple SQL statements, only the first
651686
** one is processed. All statements beyond the first are silently ignored.
652687
*/
@@ -658,10 +693,11 @@
658693
blob_zero(&pStmt->sql);
659694
blob_vappendf(&pStmt->sql, zFormat, ap);
660695
va_end(ap);
661696
zSql = blob_str(&pStmt->sql);
662697
db.nPrepare++;
698
+ db_append_dml(zSql);
663699
if( flags & DB_PREPARE_PERSISTENT ){
664700
prepFlags = SQLITE_PREPARE_PERSISTENT;
665701
}
666702
rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
667703
if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
@@ -1047,10 +1083,11 @@
10471083
rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
10481084
if( rc ){
10491085
db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
10501086
}else if( pStmt ){
10511087
db.nPrepare++;
1088
+ db_append_dml(sqlite3_sql(pStmt));
10521089
while( sqlite3_step(pStmt)==SQLITE_ROW ){}
10531090
rc = sqlite3_finalize(pStmt);
10541091
if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
10551092
}
10561093
z = zEnd;
10571094
--- src/db.c
+++ src/db.c
@@ -170,10 +170,12 @@
170 void *pAuthArg; /* Argument to the authorizer */
171 const char *zAuthName; /* Name of the authorizer */
172 int bProtectTriggers; /* True if protection triggers already exist */
173 int nProtect; /* Slots of aProtect used */
174 unsigned aProtect[12]; /* Saved values of protectMask */
 
 
175 } db = {
176 PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
177 0, 0, 0, 0, 0, 0, 0, {{0}}, {0}, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}};
178
179 /*
@@ -643,10 +645,43 @@
643 */
644 #define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
645 #define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
646 #endif
647
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648 /*
649 ** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
650 ** If the input string contains multiple SQL statements, only the first
651 ** one is processed. All statements beyond the first are silently ignored.
652 */
@@ -658,10 +693,11 @@
658 blob_zero(&pStmt->sql);
659 blob_vappendf(&pStmt->sql, zFormat, ap);
660 va_end(ap);
661 zSql = blob_str(&pStmt->sql);
662 db.nPrepare++;
 
663 if( flags & DB_PREPARE_PERSISTENT ){
664 prepFlags = SQLITE_PREPARE_PERSISTENT;
665 }
666 rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
667 if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
@@ -1047,10 +1083,11 @@
1047 rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
1048 if( rc ){
1049 db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
1050 }else if( pStmt ){
1051 db.nPrepare++;
 
1052 while( sqlite3_step(pStmt)==SQLITE_ROW ){}
1053 rc = sqlite3_finalize(pStmt);
1054 if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
1055 }
1056 z = zEnd;
1057
--- src/db.c
+++ src/db.c
@@ -170,10 +170,12 @@
170 void *pAuthArg; /* Argument to the authorizer */
171 const char *zAuthName; /* Name of the authorizer */
172 int bProtectTriggers; /* True if protection triggers already exist */
173 int nProtect; /* Slots of aProtect used */
174 unsigned aProtect[12]; /* Saved values of protectMask */
175 int pauseDmlLog; /* Ignore pDmlLog if positive */
176 Blob *pDmlLog; /* Append DML statements here, of not NULL */
177 } db = {
178 PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
179 0, 0, 0, 0, 0, 0, 0, {{0}}, {0}, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}};
180
181 /*
@@ -643,10 +645,43 @@
645 */
646 #define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
647 #define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
648 #endif
649
650 /*
651 ** If zSql is a DML statement, append it db.pDmlLog.
652 */
653 static void db_append_dml(const char *zSql){
654 size_t nSql;
655 if( db.pDmlLog==0 ) return;
656 if( db.pauseDmlLog ) return;
657 if( zSql==0 ) return;
658 nSql = strlen(zSql);
659 while( nSql>0 && fossil_isspace(zSql[0]) ){ nSql--; zSql++; }
660 while( nSql>0 && fossil_isspace(zSql[nSql-1]) ) nSql--;
661 if( nSql<6 ) return;
662 if( strncmp(zSql, "SELECT", 6)==0 ) return;
663 if( strncmp(zSql, "PRAGMA", 6)==0 ) return;
664 blob_append(db.pDmlLog, zSql, nSql);
665 if( zSql[nSql-1]!=';' ) blob_append_char(db.pDmlLog, ';');
666 blob_append_char(db.pDmlLog, '\n');
667 }
668
669 /*
670 ** Set the Blob to which DML statement text should be appended. Set it
671 ** to zero to stop appending DML statement text.
672 */
673 void db_append_dml_to_blob(Blob *pBlob){
674 db.pDmlLog = pBlob;
675 }
676
677 /*
678 ** Pause or unpause the DML log
679 */
680 void db_pause_dml_log(void){ db.pauseDmlLog++; }
681 void db_unpause_dml_log(void){ db.pauseDmlLog--; }
682
683 /*
684 ** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
685 ** If the input string contains multiple SQL statements, only the first
686 ** one is processed. All statements beyond the first are silently ignored.
687 */
@@ -658,10 +693,11 @@
693 blob_zero(&pStmt->sql);
694 blob_vappendf(&pStmt->sql, zFormat, ap);
695 va_end(ap);
696 zSql = blob_str(&pStmt->sql);
697 db.nPrepare++;
698 db_append_dml(zSql);
699 if( flags & DB_PREPARE_PERSISTENT ){
700 prepFlags = SQLITE_PREPARE_PERSISTENT;
701 }
702 rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
703 if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
@@ -1047,10 +1083,11 @@
1083 rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
1084 if( rc ){
1085 db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
1086 }else if( pStmt ){
1087 db.nPrepare++;
1088 db_append_dml(sqlite3_sql(pStmt));
1089 while( sqlite3_step(pStmt)==SQLITE_ROW ){}
1090 rc = sqlite3_finalize(pStmt);
1091 if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
1092 }
1093 z = zEnd;
1094
+49 -39
--- src/descendants.c
+++ src/descendants.c
@@ -202,29 +202,28 @@
202202
rLimitMtime = db_double(0.0,
203203
"SELECT mtime FROM event WHERE objid=%d",
204204
ridBackTo);
205205
}
206206
db_multi_exec(
207
- "WITH RECURSIVE "
208
- " parent(pid,cid,isCP) AS ("
209
- " SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink"
210
- " UNION ALL"
211
- " SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude"
212
- " ),"
213
- " ancestor(rid, mtime, isCP) AS ("
214
- " SELECT %d, mtime, 0 FROM event WHERE objid=%d "
215
- " UNION "
216
- " SELECT parent.pid, event.mtime, parent.isCP"
217
- " FROM ancestor, parent, event"
218
- " WHERE parent.cid=ancestor.rid"
219
- " AND event.objid=parent.pid"
220
- " AND NOT ancestor.isCP"
221
- " AND (event.mtime>=%.17g OR parent.pid=%d)"
222
- " ORDER BY mtime DESC LIMIT %d"
223
- " )"
224
- "INSERT OR IGNORE INTO ok"
225
- " SELECT rid FROM ancestor;",
207
+ "WITH RECURSIVE\n"
208
+ " parent(pid,cid,isCP) AS (\n"
209
+ " SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink\n"
210
+ " UNION ALL\n"
211
+ " SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude\n"
212
+ " ),\n"
213
+ " ancestor(rid, mtime, isCP) AS (\n"
214
+ " SELECT %d, mtime, 0 FROM event WHERE objid=%d\n"
215
+ " UNION\n"
216
+ " SELECT parent.pid, event.mtime, parent.isCP\n"
217
+ " FROM ancestor, parent, event\n"
218
+ " WHERE parent.cid=ancestor.rid\n"
219
+ " AND event.objid=parent.pid\n"
220
+ " AND NOT ancestor.isCP\n"
221
+ " AND (event.mtime>=%.17g OR parent.pid=%d)\n"
222
+ " ORDER BY mtime DESC LIMIT %d\n"
223
+ " )\n"
224
+ "INSERT OR IGNORE INTO ok SELECT rid FROM ancestor;",
226225
rid, rid, rLimitMtime, ridBackTo, N
227226
);
228227
if( ridBackTo && db_changes()>1 ){
229228
db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
230229
}
@@ -322,18 +321,18 @@
322321
N = -1;
323322
}else if( N<0 ){
324323
N = -N;
325324
}
326325
db_multi_exec(
327
- "WITH RECURSIVE"
328
- " dx(rid,mtime) AS ("
329
- " SELECT %d, 0"
330
- " UNION"
331
- " SELECT plink.cid, plink.mtime FROM dx, plink"
332
- " WHERE plink.pid=dx.rid"
333
- " ORDER BY 2"
334
- " )"
326
+ "WITH RECURSIVE\n"
327
+ " dx(rid,mtime) AS (\n"
328
+ " SELECT %d, 0\n"
329
+ " UNION\n"
330
+ " SELECT plink.cid, plink.mtime FROM dx, plink\n"
331
+ " WHERE plink.pid=dx.rid\n"
332
+ " ORDER BY 2\n"
333
+ " )\n"
335334
"INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
336335
rid, N
337336
);
338337
}
339338
@@ -639,44 +638,56 @@
639638
/* Flag parameters to compute_uses_file() */
640639
#define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
641640
642641
#endif
643642
643
+/*
644
+** Append a new VALUES term.
645
+*/
646
+static void uses_file_append_term(Blob *pSql, int *pnCnt, int rid){
647
+ if( *pnCnt==0 ){
648
+ blob_append_sql(pSql, "(%d)", rid);
649
+ *pnCnt = 4;
650
+ }else if( (*pnCnt)%10==9 ){
651
+ blob_append_sql(pSql, ",\n (%d)", rid);
652
+ }else{
653
+ blob_append_sql(pSql, ",(%d)", rid);
654
+ }
655
+ ++*pnCnt;
656
+}
657
+
644658
645659
/*
646660
** Add to table zTab the record ID (rid) of every check-in that contains
647661
** the file fid.
648662
*/
649663
void compute_uses_file(const char *zTab, int fid, int usesFlags){
650664
Bag seen;
651665
Bag pending;
652
- Stmt ins;
666
+ Blob ins = BLOB_INITIALIZER;
667
+ int nIns = 0;
653668
Stmt q;
654669
int rid;
655670
656671
bag_init(&seen);
657672
bag_init(&pending);
658
- db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab);
673
+ blob_append_sql(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES", zTab);
659674
db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
660675
while( db_step(&q)==SQLITE_ROW ){
661676
int mid = db_column_int(&q, 0);
662677
bag_insert(&pending, mid);
663678
bag_insert(&seen, mid);
664
- db_bind_int(&ins, ":rid", mid);
665
- db_step(&ins);
666
- db_reset(&ins);
679
+ uses_file_append_term(&ins, &nIns, mid);
667680
}
668681
db_finalize(&q);
669682
670683
db_prepare(&q, "SELECT mid FROM mlink WHERE pid=%d", fid);
671684
while( db_step(&q)==SQLITE_ROW ){
672685
int mid = db_column_int(&q, 0);
673686
bag_insert(&seen, mid);
674687
if( usesFlags & USESFILE_DELETE ){
675
- db_bind_int(&ins, ":rid", mid);
676
- db_step(&ins);
677
- db_reset(&ins);
688
+ uses_file_append_term(&ins, &nIns, mid);
678689
}
679690
}
680691
db_finalize(&q);
681692
db_prepare(&q, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
682693
@@ -686,16 +697,15 @@
686697
while( db_step(&q)==SQLITE_ROW ){
687698
int mid = db_column_int(&q, 0);
688699
if( bag_find(&seen, mid) ) continue;
689700
bag_insert(&seen, mid);
690701
bag_insert(&pending, mid);
691
- db_bind_int(&ins, ":rid", mid);
692
- db_step(&ins);
693
- db_reset(&ins);
702
+ uses_file_append_term(&ins, &nIns, mid);
694703
}
695704
db_reset(&q);
696705
}
697706
db_finalize(&q);
698
- db_finalize(&ins);
707
+ db_exec_sql(blob_str(&ins));
708
+ blob_reset(&ins);
699709
bag_clear(&seen);
700710
bag_clear(&pending);
701711
}
702712
--- src/descendants.c
+++ src/descendants.c
@@ -202,29 +202,28 @@
202 rLimitMtime = db_double(0.0,
203 "SELECT mtime FROM event WHERE objid=%d",
204 ridBackTo);
205 }
206 db_multi_exec(
207 "WITH RECURSIVE "
208 " parent(pid,cid,isCP) AS ("
209 " SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink"
210 " UNION ALL"
211 " SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude"
212 " ),"
213 " ancestor(rid, mtime, isCP) AS ("
214 " SELECT %d, mtime, 0 FROM event WHERE objid=%d "
215 " UNION "
216 " SELECT parent.pid, event.mtime, parent.isCP"
217 " FROM ancestor, parent, event"
218 " WHERE parent.cid=ancestor.rid"
219 " AND event.objid=parent.pid"
220 " AND NOT ancestor.isCP"
221 " AND (event.mtime>=%.17g OR parent.pid=%d)"
222 " ORDER BY mtime DESC LIMIT %d"
223 " )"
224 "INSERT OR IGNORE INTO ok"
225 " SELECT rid FROM ancestor;",
226 rid, rid, rLimitMtime, ridBackTo, N
227 );
228 if( ridBackTo && db_changes()>1 ){
229 db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
230 }
@@ -322,18 +321,18 @@
322 N = -1;
323 }else if( N<0 ){
324 N = -N;
325 }
326 db_multi_exec(
327 "WITH RECURSIVE"
328 " dx(rid,mtime) AS ("
329 " SELECT %d, 0"
330 " UNION"
331 " SELECT plink.cid, plink.mtime FROM dx, plink"
332 " WHERE plink.pid=dx.rid"
333 " ORDER BY 2"
334 " )"
335 "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
336 rid, N
337 );
338 }
339
@@ -639,44 +638,56 @@
639 /* Flag parameters to compute_uses_file() */
640 #define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
641
642 #endif
643
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
644
645 /*
646 ** Add to table zTab the record ID (rid) of every check-in that contains
647 ** the file fid.
648 */
649 void compute_uses_file(const char *zTab, int fid, int usesFlags){
650 Bag seen;
651 Bag pending;
652 Stmt ins;
 
653 Stmt q;
654 int rid;
655
656 bag_init(&seen);
657 bag_init(&pending);
658 db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab);
659 db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
660 while( db_step(&q)==SQLITE_ROW ){
661 int mid = db_column_int(&q, 0);
662 bag_insert(&pending, mid);
663 bag_insert(&seen, mid);
664 db_bind_int(&ins, ":rid", mid);
665 db_step(&ins);
666 db_reset(&ins);
667 }
668 db_finalize(&q);
669
670 db_prepare(&q, "SELECT mid FROM mlink WHERE pid=%d", fid);
671 while( db_step(&q)==SQLITE_ROW ){
672 int mid = db_column_int(&q, 0);
673 bag_insert(&seen, mid);
674 if( usesFlags & USESFILE_DELETE ){
675 db_bind_int(&ins, ":rid", mid);
676 db_step(&ins);
677 db_reset(&ins);
678 }
679 }
680 db_finalize(&q);
681 db_prepare(&q, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
682
@@ -686,16 +697,15 @@
686 while( db_step(&q)==SQLITE_ROW ){
687 int mid = db_column_int(&q, 0);
688 if( bag_find(&seen, mid) ) continue;
689 bag_insert(&seen, mid);
690 bag_insert(&pending, mid);
691 db_bind_int(&ins, ":rid", mid);
692 db_step(&ins);
693 db_reset(&ins);
694 }
695 db_reset(&q);
696 }
697 db_finalize(&q);
698 db_finalize(&ins);
 
699 bag_clear(&seen);
700 bag_clear(&pending);
701 }
702
--- src/descendants.c
+++ src/descendants.c
@@ -202,29 +202,28 @@
202 rLimitMtime = db_double(0.0,
203 "SELECT mtime FROM event WHERE objid=%d",
204 ridBackTo);
205 }
206 db_multi_exec(
207 "WITH RECURSIVE\n"
208 " parent(pid,cid,isCP) AS (\n"
209 " SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink\n"
210 " UNION ALL\n"
211 " SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude\n"
212 " ),\n"
213 " ancestor(rid, mtime, isCP) AS (\n"
214 " SELECT %d, mtime, 0 FROM event WHERE objid=%d\n"
215 " UNION\n"
216 " SELECT parent.pid, event.mtime, parent.isCP\n"
217 " FROM ancestor, parent, event\n"
218 " WHERE parent.cid=ancestor.rid\n"
219 " AND event.objid=parent.pid\n"
220 " AND NOT ancestor.isCP\n"
221 " AND (event.mtime>=%.17g OR parent.pid=%d)\n"
222 " ORDER BY mtime DESC LIMIT %d\n"
223 " )\n"
224 "INSERT OR IGNORE INTO ok SELECT rid FROM ancestor;",
 
225 rid, rid, rLimitMtime, ridBackTo, N
226 );
227 if( ridBackTo && db_changes()>1 ){
228 db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
229 }
@@ -322,18 +321,18 @@
321 N = -1;
322 }else if( N<0 ){
323 N = -N;
324 }
325 db_multi_exec(
326 "WITH RECURSIVE\n"
327 " dx(rid,mtime) AS (\n"
328 " SELECT %d, 0\n"
329 " UNION\n"
330 " SELECT plink.cid, plink.mtime FROM dx, plink\n"
331 " WHERE plink.pid=dx.rid\n"
332 " ORDER BY 2\n"
333 " )\n"
334 "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
335 rid, N
336 );
337 }
338
@@ -639,44 +638,56 @@
638 /* Flag parameters to compute_uses_file() */
639 #define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
640
641 #endif
642
643 /*
644 ** Append a new VALUES term.
645 */
646 static void uses_file_append_term(Blob *pSql, int *pnCnt, int rid){
647 if( *pnCnt==0 ){
648 blob_append_sql(pSql, "(%d)", rid);
649 *pnCnt = 4;
650 }else if( (*pnCnt)%10==9 ){
651 blob_append_sql(pSql, ",\n (%d)", rid);
652 }else{
653 blob_append_sql(pSql, ",(%d)", rid);
654 }
655 ++*pnCnt;
656 }
657
658
659 /*
660 ** Add to table zTab the record ID (rid) of every check-in that contains
661 ** the file fid.
662 */
663 void compute_uses_file(const char *zTab, int fid, int usesFlags){
664 Bag seen;
665 Bag pending;
666 Blob ins = BLOB_INITIALIZER;
667 int nIns = 0;
668 Stmt q;
669 int rid;
670
671 bag_init(&seen);
672 bag_init(&pending);
673 blob_append_sql(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES", zTab);
674 db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
675 while( db_step(&q)==SQLITE_ROW ){
676 int mid = db_column_int(&q, 0);
677 bag_insert(&pending, mid);
678 bag_insert(&seen, mid);
679 uses_file_append_term(&ins, &nIns, mid);
 
 
680 }
681 db_finalize(&q);
682
683 db_prepare(&q, "SELECT mid FROM mlink WHERE pid=%d", fid);
684 while( db_step(&q)==SQLITE_ROW ){
685 int mid = db_column_int(&q, 0);
686 bag_insert(&seen, mid);
687 if( usesFlags & USESFILE_DELETE ){
688 uses_file_append_term(&ins, &nIns, mid);
 
 
689 }
690 }
691 db_finalize(&q);
692 db_prepare(&q, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
693
@@ -686,16 +697,15 @@
697 while( db_step(&q)==SQLITE_ROW ){
698 int mid = db_column_int(&q, 0);
699 if( bag_find(&seen, mid) ) continue;
700 bag_insert(&seen, mid);
701 bag_insert(&pending, mid);
702 uses_file_append_term(&ins, &nIns, mid);
 
 
703 }
704 db_reset(&q);
705 }
706 db_finalize(&q);
707 db_exec_sql(blob_str(&ins));
708 blob_reset(&ins);
709 bag_clear(&seen);
710 bag_clear(&pending);
711 }
712
+57 -48
--- src/timeline.c
+++ src/timeline.c
@@ -1591,10 +1591,11 @@
15911591
tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
15921592
if( tagId==0 ){
15931593
endId = symbolic_name_to_rid(zEnd, "ci");
15941594
if( endId==0 ) return 0;
15951595
}
1596
+ db_pause_dml_log();
15961597
if( bForward ){
15971598
if( tagId ){
15981599
db_prepare(&q,
15991600
"WITH RECURSIVE dx(id,mtime) AS ("
16001601
" SELECT %d, event.mtime FROM event WHERE objid=%d"
@@ -1658,10 +1659,11 @@
16581659
}
16591660
if( db_step(&q)==SQLITE_ROW ){
16601661
ans = db_column_int(&q, 0);
16611662
}
16621663
db_finalize(&q);
1664
+ db_unpause_dml_log();
16631665
return ans;
16641666
}
16651667
16661668
/*
16671669
** COMMAND: test-endpoint
@@ -1862,14 +1864,17 @@
18621864
int advancedMenu = 0; /* Use the advanced menu design */
18631865
char *zPlural; /* Ending for plural forms */
18641866
int showCherrypicks = 1; /* True to show cherrypick merges */
18651867
int haveParameterN; /* True if n= query parameter present */
18661868
int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
1869
+ int showSql = PB("showsql"); /* True to show the SQL */
1870
+ Blob allSql; /* Copy of all SQL text */
18671871
18681872
login_check_credentials();
18691873
url_initialize(&url, "timeline");
18701874
cgi_query_parameters_to_url(&url);
1875
+ blob_init(&allSql, 0, 0);
18711876
18721877
(void)P_NoBot("ss")
18731878
/* "ss" is processed via the udc but at least one spider likes to
18741879
** try to SQL inject via this argument, so let's catch that. */;
18751880
@@ -2082,10 +2087,11 @@
20822087
}
20832088
if( PB("nc") ){
20842089
tmFlags &= ~(TIMELINE_DELTA|TIMELINE_BRCOLOR|TIMELINE_UCOLOR);
20852090
tmFlags |= TIMELINE_NOCOLOR;
20862091
}
2092
+ if( showSql ) db_append_dml_to_blob(&allSql);
20872093
if( zUses!=0 ){
20882094
int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
20892095
if( ufid ){
20902096
zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
20912097
db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
@@ -2099,42 +2105,42 @@
20992105
}
21002106
if( renameOnly ){
21012107
db_multi_exec(
21022108
"CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
21032109
"INSERT OR IGNORE INTO rnfile"
2104
- " SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
2110
+ " SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
21052111
);
21062112
disableY = 1;
21072113
}
21082114
if( forkOnly ){
21092115
db_multi_exec(
21102116
"CREATE TEMP TABLE rnfork(rid INTEGER PRIMARY KEY);\n"
21112117
"INSERT OR IGNORE INTO rnfork(rid)\n"
21122118
" SELECT pid FROM plink\n"
2113
- " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2114
- " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2115
- " GROUP BY pid"
2119
+ " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2120
+ " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2121
+ " GROUP BY pid\n"
21162122
" HAVING count(*)>1;\n"
2117
- "INSERT OR IGNORE INTO rnfork(rid)"
2123
+ "INSERT OR IGNORE INTO rnfork(rid)\n"
21182124
" SELECT cid FROM plink\n"
2119
- " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2120
- " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2121
- " GROUP BY cid"
2125
+ " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2126
+ " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2127
+ " GROUP BY cid\n"
21222128
" HAVING count(*)>1;\n",
21232129
TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
21242130
);
21252131
db_multi_exec(
21262132
"INSERT OR IGNORE INTO rnfork(rid)\n"
21272133
" SELECT cid FROM plink\n"
2128
- " WHERE pid IN rnfork"
2129
- " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2130
- " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2131
- " UNION "
2134
+ " WHERE pid IN rnfork\n"
2135
+ " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2136
+ " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2137
+ " UNION\n"
21322138
" SELECT pid FROM plink\n"
2133
- " WHERE cid IN rnfork"
2134
- " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2135
- " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n",
2139
+ " WHERE cid IN rnfork\n"
2140
+ " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2141
+ " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n",
21362142
TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
21372143
);
21382144
tmFlags |= TIMELINE_UNHIDE;
21392145
zType = "ci";
21402146
disableY = 1;
@@ -2239,45 +2245,52 @@
22392245
laterRid = you_rid;
22402246
}
22412247
}
22422248
blob_init(&ins, 0, 0);
22432249
db_multi_exec(
2244
- "CREATE TABLE IF NOT EXISTS temp.pathnode(x INTEGER PRIMARY KEY);"
2250
+ "CREATE TEMP TABLE IF NOT EXISTS pathnode(x INTEGER PRIMARY KEY);"
22452251
);
22462252
if( p ){
2253
+ int cnt = 4;
22472254
blob_init(&ins, 0, 0);
22482255
blob_append_sql(&ins, "INSERT INTO pathnode(x) VALUES(%d)", p->rid);
22492256
p = p->u.pTo;
22502257
while( p ){
2251
- blob_append_sql(&ins, ",(%d)", p->rid);
2258
+ if( cnt==8 ){
2259
+ blob_append_sql(&ins, ",\n (%d)", p->rid);
2260
+ cnt = 0;
2261
+ }else{
2262
+ cnt++;
2263
+ blob_append_sql(&ins, ",(%d)", p->rid);
2264
+ }
22522265
p = p->u.pTo;
22532266
}
22542267
}
22552268
path_reset();
22562269
db_multi_exec("%s", blob_str(&ins)/*safe-for-%s*/);
22572270
blob_reset(&ins);
22582271
if( related || P("mionly") ){
22592272
db_multi_exec(
2260
- "CREATE TABLE IF NOT EXISTS temp.related(x INTEGER PRIMARY KEY);"
2273
+ "CREATE TEMP TABLE IF NOT EXISTS related(x INTEGER PRIMARY KEY);"
22612274
"INSERT OR IGNORE INTO related(x)"
2262
- " SELECT pid FROM plink WHERE cid IN pathnode AND NOT isprim;"
2275
+ " SELECT pid FROM plink WHERE cid IN pathnode AND NOT isprim;"
22632276
);
22642277
if( P("mionly")==0 ){
22652278
db_multi_exec(
22662279
"INSERT OR IGNORE INTO related(x)"
2267
- " SELECT cid FROM plink WHERE pid IN pathnode;"
2280
+ " SELECT cid FROM plink WHERE pid IN pathnode;"
22682281
);
22692282
}
22702283
if( showCherrypicks ){
22712284
db_multi_exec(
22722285
"INSERT OR IGNORE INTO related(x)"
2273
- " SELECT parentid FROM cherrypick WHERE childid IN pathnode;"
2286
+ " SELECT parentid FROM cherrypick WHERE childid IN pathnode;"
22742287
);
22752288
if( P("mionly")==0 ){
22762289
db_multi_exec(
22772290
"INSERT OR IGNORE INTO related(x)"
2278
- " SELECT childid FROM cherrypick WHERE parentid IN pathnode;"
2291
+ " SELECT childid FROM cherrypick WHERE parentid IN pathnode;"
22792292
);
22802293
}
22812294
}
22822295
db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
22832296
if( earlierRid && laterRid && commonAncs==earlierRid ){
@@ -2363,11 +2376,10 @@
23632376
zCiName = zDPName;
23642377
if( zCiName==0 ) zCiName = zUuid;
23652378
blob_append_sql(&sql, " AND event.objid IN ok");
23662379
nd = 0;
23672380
if( d_rid ){
2368
- Stmt s;
23692381
double rStopTime = 9e99;
23702382
zFwdTo = P("ft");
23712383
if( zFwdTo ){
23722384
double rStartDate = db_double(0.0,
23732385
"SELECT mtime FROM event WHERE objid=%d", d_rid);
@@ -2379,27 +2391,25 @@
23792391
if( !haveParameterN ) nEntry = 0;
23802392
rStopTime = db_double(9e99,
23812393
"SELECT mtime FROM event WHERE objid=%d", ridFwdTo);
23822394
}
23832395
}
2384
- db_prepare(&s,
2385
- "WITH RECURSIVE"
2386
- " dx(rid,mtime) AS ("
2387
- " SELECT %d, 0"
2388
- " UNION"
2389
- " SELECT plink.cid, plink.mtime FROM dx, plink"
2390
- " WHERE plink.pid=dx.rid"
2391
- " AND (:stop>=8e99 OR plink.mtime<=:stop)"
2392
- " ORDER BY 2"
2393
- " )"
2396
+ if( rStopTime<9e99 ){
2397
+ rStopTime += 5.8e-6; /* Round up by 1/2 second */
2398
+ }
2399
+ db_multi_exec(
2400
+ "WITH RECURSIVE dx(rid,mtime) AS (\n"
2401
+ " SELECT %d, 0\n"
2402
+ " UNION\n"
2403
+ " SELECT plink.cid, plink.mtime FROM dx, plink\n"
2404
+ " WHERE plink.pid=dx.rid\n"
2405
+ " AND plink.mtime<=%.*g\n"
2406
+ " ORDER BY 2\n"
2407
+ ")\n"
23942408
"INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
2395
- d_rid, nEntry<=0 ? -1 : nEntry+1
2409
+ d_rid, rStopTime<8e99 ? 17 : 2, rStopTime, nEntry<=0 ? -1 : nEntry+1
23962410
);
2397
- db_bind_double(&s, ":stop", rStopTime);
2398
- db_step(&s);
2399
- db_finalize(&s);
2400
- /* compute_descendants(d_rid, nEntry==0 ? 0 : nEntry+1); */
24012411
nd = db_int(0, "SELECT count(*)-1 FROM ok");
24022412
if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
24032413
if( nd>0 || p_rid==0 ){
24042414
blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
24052415
}
@@ -2508,28 +2518,28 @@
25082518
if( zChng && *zChng ){
25092519
addFileGlobExclusion(zChng, &cond);
25102520
tmFlags |= TIMELINE_XMERGE;
25112521
}
25122522
if( zUses ){
2513
- blob_append_sql(&cond, " AND event.objid IN usesfile ");
2523
+ blob_append_sql(&cond, " AND event.objid IN usesfile\n");
25142524
}
25152525
if( renameOnly ){
2516
- blob_append_sql(&cond, " AND event.objid IN rnfile ");
2526
+ blob_append_sql(&cond, " AND event.objid IN rnfile\n");
25172527
}
25182528
if( forkOnly ){
2519
- blob_append_sql(&cond, " AND event.objid IN rnfork ");
2529
+ blob_append_sql(&cond, " AND event.objid IN rnfork\n");
25202530
}
25212531
if( cpOnly && showCherrypicks ){
25222532
db_multi_exec(
25232533
"CREATE TEMP TABLE IF NOT EXISTS cpnodes(rid INTEGER PRIMARY KEY);"
25242534
"INSERT OR IGNORE INTO cpnodes SELECT childid FROM cherrypick;"
25252535
"INSERT OR IGNORE INTO cpnodes SELECT parentid FROM cherrypick;"
25262536
);
2527
- blob_append_sql(&cond, " AND event.objid IN cpnodes ");
2537
+ blob_append_sql(&cond, " AND event.objid IN cpnodes\n");
25282538
}
25292539
if( bisectLocal || zBisect!=0 ){
2530
- blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) ");
2540
+ blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
25312541
}
25322542
if( zYearMonth ){
25332543
char *zNext;
25342544
zYearMonth = timeline_expand_datetime(zYearMonth);
25352545
if( strlen(zYearMonth)>7 ){
@@ -2878,13 +2888,10 @@
28782888
blob_append_sql(&sql2,
28792889
" AND event.mtime>=%f ORDER BY event.mtime ASC", rCirca);
28802890
if( nEntry>0 ){
28812891
blob_append_sql(&sql2," LIMIT %d", (nEntry+1)/2);
28822892
}
2883
- if( PB("showsql") ){
2884
- @ <pre>%h(blob_sql_text(&sql2))</pre>
2885
- }
28862893
db_multi_exec("%s", blob_sql_text(&sql2));
28872894
if( nEntry>0 ){
28882895
nEntry -= db_int(0,"select count(*) from timeline");
28892896
if( nEntry<=0 ) nEntry = 1;
28902897
}
@@ -3035,12 +3042,14 @@
30353042
style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
30363043
}
30373044
}
30383045
blob_zero(&cond);
30393046
}
3040
- if( PB("showsql") ){
3041
- @ <pre>%h(blob_sql_text(&sql))</pre>
3047
+ if( showSql ){
3048
+ db_append_dml_to_blob(0);
3049
+ @ <pre>%h(blob_str(&allSql))</pre>
3050
+ blob_reset(&allSql);
30423051
}
30433052
if( search_restrict(SRCH_CKIN)!=0 ){
30443053
style_submenu_element("Search", "%R/search?y=c");
30453054
}
30463055
if( advancedMenu ){
30473056
--- src/timeline.c
+++ src/timeline.c
@@ -1591,10 +1591,11 @@
1591 tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
1592 if( tagId==0 ){
1593 endId = symbolic_name_to_rid(zEnd, "ci");
1594 if( endId==0 ) return 0;
1595 }
 
1596 if( bForward ){
1597 if( tagId ){
1598 db_prepare(&q,
1599 "WITH RECURSIVE dx(id,mtime) AS ("
1600 " SELECT %d, event.mtime FROM event WHERE objid=%d"
@@ -1658,10 +1659,11 @@
1658 }
1659 if( db_step(&q)==SQLITE_ROW ){
1660 ans = db_column_int(&q, 0);
1661 }
1662 db_finalize(&q);
 
1663 return ans;
1664 }
1665
1666 /*
1667 ** COMMAND: test-endpoint
@@ -1862,14 +1864,17 @@
1862 int advancedMenu = 0; /* Use the advanced menu design */
1863 char *zPlural; /* Ending for plural forms */
1864 int showCherrypicks = 1; /* True to show cherrypick merges */
1865 int haveParameterN; /* True if n= query parameter present */
1866 int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
 
 
1867
1868 login_check_credentials();
1869 url_initialize(&url, "timeline");
1870 cgi_query_parameters_to_url(&url);
 
1871
1872 (void)P_NoBot("ss")
1873 /* "ss" is processed via the udc but at least one spider likes to
1874 ** try to SQL inject via this argument, so let's catch that. */;
1875
@@ -2082,10 +2087,11 @@
2082 }
2083 if( PB("nc") ){
2084 tmFlags &= ~(TIMELINE_DELTA|TIMELINE_BRCOLOR|TIMELINE_UCOLOR);
2085 tmFlags |= TIMELINE_NOCOLOR;
2086 }
 
2087 if( zUses!=0 ){
2088 int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
2089 if( ufid ){
2090 zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
2091 db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
@@ -2099,42 +2105,42 @@
2099 }
2100 if( renameOnly ){
2101 db_multi_exec(
2102 "CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
2103 "INSERT OR IGNORE INTO rnfile"
2104 " SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
2105 );
2106 disableY = 1;
2107 }
2108 if( forkOnly ){
2109 db_multi_exec(
2110 "CREATE TEMP TABLE rnfork(rid INTEGER PRIMARY KEY);\n"
2111 "INSERT OR IGNORE INTO rnfork(rid)\n"
2112 " SELECT pid FROM plink\n"
2113 " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2114 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2115 " GROUP BY pid"
2116 " HAVING count(*)>1;\n"
2117 "INSERT OR IGNORE INTO rnfork(rid)"
2118 " SELECT cid FROM plink\n"
2119 " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2120 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2121 " GROUP BY cid"
2122 " HAVING count(*)>1;\n",
2123 TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
2124 );
2125 db_multi_exec(
2126 "INSERT OR IGNORE INTO rnfork(rid)\n"
2127 " SELECT cid FROM plink\n"
2128 " WHERE pid IN rnfork"
2129 " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2130 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2131 " UNION "
2132 " SELECT pid FROM plink\n"
2133 " WHERE cid IN rnfork"
2134 " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
2135 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n",
2136 TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
2137 );
2138 tmFlags |= TIMELINE_UNHIDE;
2139 zType = "ci";
2140 disableY = 1;
@@ -2239,45 +2245,52 @@
2239 laterRid = you_rid;
2240 }
2241 }
2242 blob_init(&ins, 0, 0);
2243 db_multi_exec(
2244 "CREATE TABLE IF NOT EXISTS temp.pathnode(x INTEGER PRIMARY KEY);"
2245 );
2246 if( p ){
 
2247 blob_init(&ins, 0, 0);
2248 blob_append_sql(&ins, "INSERT INTO pathnode(x) VALUES(%d)", p->rid);
2249 p = p->u.pTo;
2250 while( p ){
2251 blob_append_sql(&ins, ",(%d)", p->rid);
 
 
 
 
 
 
2252 p = p->u.pTo;
2253 }
2254 }
2255 path_reset();
2256 db_multi_exec("%s", blob_str(&ins)/*safe-for-%s*/);
2257 blob_reset(&ins);
2258 if( related || P("mionly") ){
2259 db_multi_exec(
2260 "CREATE TABLE IF NOT EXISTS temp.related(x INTEGER PRIMARY KEY);"
2261 "INSERT OR IGNORE INTO related(x)"
2262 " SELECT pid FROM plink WHERE cid IN pathnode AND NOT isprim;"
2263 );
2264 if( P("mionly")==0 ){
2265 db_multi_exec(
2266 "INSERT OR IGNORE INTO related(x)"
2267 " SELECT cid FROM plink WHERE pid IN pathnode;"
2268 );
2269 }
2270 if( showCherrypicks ){
2271 db_multi_exec(
2272 "INSERT OR IGNORE INTO related(x)"
2273 " SELECT parentid FROM cherrypick WHERE childid IN pathnode;"
2274 );
2275 if( P("mionly")==0 ){
2276 db_multi_exec(
2277 "INSERT OR IGNORE INTO related(x)"
2278 " SELECT childid FROM cherrypick WHERE parentid IN pathnode;"
2279 );
2280 }
2281 }
2282 db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
2283 if( earlierRid && laterRid && commonAncs==earlierRid ){
@@ -2363,11 +2376,10 @@
2363 zCiName = zDPName;
2364 if( zCiName==0 ) zCiName = zUuid;
2365 blob_append_sql(&sql, " AND event.objid IN ok");
2366 nd = 0;
2367 if( d_rid ){
2368 Stmt s;
2369 double rStopTime = 9e99;
2370 zFwdTo = P("ft");
2371 if( zFwdTo ){
2372 double rStartDate = db_double(0.0,
2373 "SELECT mtime FROM event WHERE objid=%d", d_rid);
@@ -2379,27 +2391,25 @@
2379 if( !haveParameterN ) nEntry = 0;
2380 rStopTime = db_double(9e99,
2381 "SELECT mtime FROM event WHERE objid=%d", ridFwdTo);
2382 }
2383 }
2384 db_prepare(&s,
2385 "WITH RECURSIVE"
2386 " dx(rid,mtime) AS ("
2387 " SELECT %d, 0"
2388 " UNION"
2389 " SELECT plink.cid, plink.mtime FROM dx, plink"
2390 " WHERE plink.pid=dx.rid"
2391 " AND (:stop>=8e99 OR plink.mtime<=:stop)"
2392 " ORDER BY 2"
2393 " )"
 
 
2394 "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
2395 d_rid, nEntry<=0 ? -1 : nEntry+1
2396 );
2397 db_bind_double(&s, ":stop", rStopTime);
2398 db_step(&s);
2399 db_finalize(&s);
2400 /* compute_descendants(d_rid, nEntry==0 ? 0 : nEntry+1); */
2401 nd = db_int(0, "SELECT count(*)-1 FROM ok");
2402 if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
2403 if( nd>0 || p_rid==0 ){
2404 blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
2405 }
@@ -2508,28 +2518,28 @@
2508 if( zChng && *zChng ){
2509 addFileGlobExclusion(zChng, &cond);
2510 tmFlags |= TIMELINE_XMERGE;
2511 }
2512 if( zUses ){
2513 blob_append_sql(&cond, " AND event.objid IN usesfile ");
2514 }
2515 if( renameOnly ){
2516 blob_append_sql(&cond, " AND event.objid IN rnfile ");
2517 }
2518 if( forkOnly ){
2519 blob_append_sql(&cond, " AND event.objid IN rnfork ");
2520 }
2521 if( cpOnly && showCherrypicks ){
2522 db_multi_exec(
2523 "CREATE TEMP TABLE IF NOT EXISTS cpnodes(rid INTEGER PRIMARY KEY);"
2524 "INSERT OR IGNORE INTO cpnodes SELECT childid FROM cherrypick;"
2525 "INSERT OR IGNORE INTO cpnodes SELECT parentid FROM cherrypick;"
2526 );
2527 blob_append_sql(&cond, " AND event.objid IN cpnodes ");
2528 }
2529 if( bisectLocal || zBisect!=0 ){
2530 blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) ");
2531 }
2532 if( zYearMonth ){
2533 char *zNext;
2534 zYearMonth = timeline_expand_datetime(zYearMonth);
2535 if( strlen(zYearMonth)>7 ){
@@ -2878,13 +2888,10 @@
2878 blob_append_sql(&sql2,
2879 " AND event.mtime>=%f ORDER BY event.mtime ASC", rCirca);
2880 if( nEntry>0 ){
2881 blob_append_sql(&sql2," LIMIT %d", (nEntry+1)/2);
2882 }
2883 if( PB("showsql") ){
2884 @ <pre>%h(blob_sql_text(&sql2))</pre>
2885 }
2886 db_multi_exec("%s", blob_sql_text(&sql2));
2887 if( nEntry>0 ){
2888 nEntry -= db_int(0,"select count(*) from timeline");
2889 if( nEntry<=0 ) nEntry = 1;
2890 }
@@ -3035,12 +3042,14 @@
3035 style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
3036 }
3037 }
3038 blob_zero(&cond);
3039 }
3040 if( PB("showsql") ){
3041 @ <pre>%h(blob_sql_text(&sql))</pre>
 
 
3042 }
3043 if( search_restrict(SRCH_CKIN)!=0 ){
3044 style_submenu_element("Search", "%R/search?y=c");
3045 }
3046 if( advancedMenu ){
3047
--- src/timeline.c
+++ src/timeline.c
@@ -1591,10 +1591,11 @@
1591 tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
1592 if( tagId==0 ){
1593 endId = symbolic_name_to_rid(zEnd, "ci");
1594 if( endId==0 ) return 0;
1595 }
1596 db_pause_dml_log();
1597 if( bForward ){
1598 if( tagId ){
1599 db_prepare(&q,
1600 "WITH RECURSIVE dx(id,mtime) AS ("
1601 " SELECT %d, event.mtime FROM event WHERE objid=%d"
@@ -1658,10 +1659,11 @@
1659 }
1660 if( db_step(&q)==SQLITE_ROW ){
1661 ans = db_column_int(&q, 0);
1662 }
1663 db_finalize(&q);
1664 db_unpause_dml_log();
1665 return ans;
1666 }
1667
1668 /*
1669 ** COMMAND: test-endpoint
@@ -1862,14 +1864,17 @@
1864 int advancedMenu = 0; /* Use the advanced menu design */
1865 char *zPlural; /* Ending for plural forms */
1866 int showCherrypicks = 1; /* True to show cherrypick merges */
1867 int haveParameterN; /* True if n= query parameter present */
1868 int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
1869 int showSql = PB("showsql"); /* True to show the SQL */
1870 Blob allSql; /* Copy of all SQL text */
1871
1872 login_check_credentials();
1873 url_initialize(&url, "timeline");
1874 cgi_query_parameters_to_url(&url);
1875 blob_init(&allSql, 0, 0);
1876
1877 (void)P_NoBot("ss")
1878 /* "ss" is processed via the udc but at least one spider likes to
1879 ** try to SQL inject via this argument, so let's catch that. */;
1880
@@ -2082,10 +2087,11 @@
2087 }
2088 if( PB("nc") ){
2089 tmFlags &= ~(TIMELINE_DELTA|TIMELINE_BRCOLOR|TIMELINE_UCOLOR);
2090 tmFlags |= TIMELINE_NOCOLOR;
2091 }
2092 if( showSql ) db_append_dml_to_blob(&allSql);
2093 if( zUses!=0 ){
2094 int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
2095 if( ufid ){
2096 zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
2097 db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
@@ -2099,42 +2105,42 @@
2105 }
2106 if( renameOnly ){
2107 db_multi_exec(
2108 "CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
2109 "INSERT OR IGNORE INTO rnfile"
2110 " SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
2111 );
2112 disableY = 1;
2113 }
2114 if( forkOnly ){
2115 db_multi_exec(
2116 "CREATE TEMP TABLE rnfork(rid INTEGER PRIMARY KEY);\n"
2117 "INSERT OR IGNORE INTO rnfork(rid)\n"
2118 " SELECT pid FROM plink\n"
2119 " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2120 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2121 " GROUP BY pid\n"
2122 " HAVING count(*)>1;\n"
2123 "INSERT OR IGNORE INTO rnfork(rid)\n"
2124 " SELECT cid FROM plink\n"
2125 " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2126 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2127 " GROUP BY cid\n"
2128 " HAVING count(*)>1;\n",
2129 TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
2130 );
2131 db_multi_exec(
2132 "INSERT OR IGNORE INTO rnfork(rid)\n"
2133 " SELECT cid FROM plink\n"
2134 " WHERE pid IN rnfork\n"
2135 " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2136 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
2137 " UNION\n"
2138 " SELECT pid FROM plink\n"
2139 " WHERE cid IN rnfork\n"
2140 " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
2141 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n",
2142 TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
2143 );
2144 tmFlags |= TIMELINE_UNHIDE;
2145 zType = "ci";
2146 disableY = 1;
@@ -2239,45 +2245,52 @@
2245 laterRid = you_rid;
2246 }
2247 }
2248 blob_init(&ins, 0, 0);
2249 db_multi_exec(
2250 "CREATE TEMP TABLE IF NOT EXISTS pathnode(x INTEGER PRIMARY KEY);"
2251 );
2252 if( p ){
2253 int cnt = 4;
2254 blob_init(&ins, 0, 0);
2255 blob_append_sql(&ins, "INSERT INTO pathnode(x) VALUES(%d)", p->rid);
2256 p = p->u.pTo;
2257 while( p ){
2258 if( cnt==8 ){
2259 blob_append_sql(&ins, ",\n (%d)", p->rid);
2260 cnt = 0;
2261 }else{
2262 cnt++;
2263 blob_append_sql(&ins, ",(%d)", p->rid);
2264 }
2265 p = p->u.pTo;
2266 }
2267 }
2268 path_reset();
2269 db_multi_exec("%s", blob_str(&ins)/*safe-for-%s*/);
2270 blob_reset(&ins);
2271 if( related || P("mionly") ){
2272 db_multi_exec(
2273 "CREATE TEMP TABLE IF NOT EXISTS related(x INTEGER PRIMARY KEY);"
2274 "INSERT OR IGNORE INTO related(x)"
2275 " SELECT pid FROM plink WHERE cid IN pathnode AND NOT isprim;"
2276 );
2277 if( P("mionly")==0 ){
2278 db_multi_exec(
2279 "INSERT OR IGNORE INTO related(x)"
2280 " SELECT cid FROM plink WHERE pid IN pathnode;"
2281 );
2282 }
2283 if( showCherrypicks ){
2284 db_multi_exec(
2285 "INSERT OR IGNORE INTO related(x)"
2286 " SELECT parentid FROM cherrypick WHERE childid IN pathnode;"
2287 );
2288 if( P("mionly")==0 ){
2289 db_multi_exec(
2290 "INSERT OR IGNORE INTO related(x)"
2291 " SELECT childid FROM cherrypick WHERE parentid IN pathnode;"
2292 );
2293 }
2294 }
2295 db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
2296 if( earlierRid && laterRid && commonAncs==earlierRid ){
@@ -2363,11 +2376,10 @@
2376 zCiName = zDPName;
2377 if( zCiName==0 ) zCiName = zUuid;
2378 blob_append_sql(&sql, " AND event.objid IN ok");
2379 nd = 0;
2380 if( d_rid ){
 
2381 double rStopTime = 9e99;
2382 zFwdTo = P("ft");
2383 if( zFwdTo ){
2384 double rStartDate = db_double(0.0,
2385 "SELECT mtime FROM event WHERE objid=%d", d_rid);
@@ -2379,27 +2391,25 @@
2391 if( !haveParameterN ) nEntry = 0;
2392 rStopTime = db_double(9e99,
2393 "SELECT mtime FROM event WHERE objid=%d", ridFwdTo);
2394 }
2395 }
2396 if( rStopTime<9e99 ){
2397 rStopTime += 5.8e-6; /* Round up by 1/2 second */
2398 }
2399 db_multi_exec(
2400 "WITH RECURSIVE dx(rid,mtime) AS (\n"
2401 " SELECT %d, 0\n"
2402 " UNION\n"
2403 " SELECT plink.cid, plink.mtime FROM dx, plink\n"
2404 " WHERE plink.pid=dx.rid\n"
2405 " AND plink.mtime<=%.*g\n"
2406 " ORDER BY 2\n"
2407 ")\n"
2408 "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
2409 d_rid, rStopTime<8e99 ? 17 : 2, rStopTime, nEntry<=0 ? -1 : nEntry+1
2410 );
 
 
 
 
2411 nd = db_int(0, "SELECT count(*)-1 FROM ok");
2412 if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
2413 if( nd>0 || p_rid==0 ){
2414 blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
2415 }
@@ -2508,28 +2518,28 @@
2518 if( zChng && *zChng ){
2519 addFileGlobExclusion(zChng, &cond);
2520 tmFlags |= TIMELINE_XMERGE;
2521 }
2522 if( zUses ){
2523 blob_append_sql(&cond, " AND event.objid IN usesfile\n");
2524 }
2525 if( renameOnly ){
2526 blob_append_sql(&cond, " AND event.objid IN rnfile\n");
2527 }
2528 if( forkOnly ){
2529 blob_append_sql(&cond, " AND event.objid IN rnfork\n");
2530 }
2531 if( cpOnly && showCherrypicks ){
2532 db_multi_exec(
2533 "CREATE TEMP TABLE IF NOT EXISTS cpnodes(rid INTEGER PRIMARY KEY);"
2534 "INSERT OR IGNORE INTO cpnodes SELECT childid FROM cherrypick;"
2535 "INSERT OR IGNORE INTO cpnodes SELECT parentid FROM cherrypick;"
2536 );
2537 blob_append_sql(&cond, " AND event.objid IN cpnodes\n");
2538 }
2539 if( bisectLocal || zBisect!=0 ){
2540 blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
2541 }
2542 if( zYearMonth ){
2543 char *zNext;
2544 zYearMonth = timeline_expand_datetime(zYearMonth);
2545 if( strlen(zYearMonth)>7 ){
@@ -2878,13 +2888,10 @@
2888 blob_append_sql(&sql2,
2889 " AND event.mtime>=%f ORDER BY event.mtime ASC", rCirca);
2890 if( nEntry>0 ){
2891 blob_append_sql(&sql2," LIMIT %d", (nEntry+1)/2);
2892 }
 
 
 
2893 db_multi_exec("%s", blob_sql_text(&sql2));
2894 if( nEntry>0 ){
2895 nEntry -= db_int(0,"select count(*) from timeline");
2896 if( nEntry<=0 ) nEntry = 1;
2897 }
@@ -3035,12 +3042,14 @@
3042 style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
3043 }
3044 }
3045 blob_zero(&cond);
3046 }
3047 if( showSql ){
3048 db_append_dml_to_blob(0);
3049 @ <pre>%h(blob_str(&allSql))</pre>
3050 blob_reset(&allSql);
3051 }
3052 if( search_restrict(SRCH_CKIN)!=0 ){
3053 style_submenu_element("Search", "%R/search?y=c");
3054 }
3055 if( advancedMenu ){
3056

Keyboard Shortcuts

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