Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Enhance the "showsql" query parameter on /timeline to show the complete SQL needed to generate the timeline, including all temp tables creation and initialization. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
ebd239de02c4b9f282f1d0bf3cb257e5 |
| User & Date: | drh 2024-12-23 12:52:18.330 |
References
|
2025-01-06
| ||
| 20:52 | Fix a bug in "fossil bisect" introduced by [ebd239de02c4b9f2]. check-in: 680acb2831 user: drh tags: trunk | |
Context
|
2024-12-23
| ||
| 13:20 | Additional tweaks and improvements to the "showsql" query parameter. check-in: 02491c2684 user: drh tags: trunk | |
| 12:52 | Enhance the "showsql" query parameter on /timeline to show the complete SQL needed to generate the timeline, including all temp tables creation and initialization. check-in: ebd239de02 user: drh tags: trunk | |
|
2024-12-22
| ||
| 11:37 | Fix to the "rl" query parameter in /timeline. check-in: f46de1f16b user: drh tags: trunk | |
Changes
Changes to src/bisect.c.
| ︙ | ︙ | |||
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
** Append a new skip entry to the bisect log.
*/
static void bisect_append_skip(int rid){
db_multi_exec(
"UPDATE vvar SET value=value||' s%d' WHERE name='bisect-log'", rid
);
}
/*
** Create a TEMP table named "bilog" that contains the complete history
** of the current bisect.
**
** If iCurrent>0 then it is the RID of the current check-out and is included
** in the history table.
**
** If zDesc is not NULL, then it is the bid= query parameter to /timeline
** that describes a bisect. Use the information in zDesc rather than in
** the bisect-log variable.
**
** If bDetail is true, then also include information about every node
** in between the inner-most GOOD and BAD nodes.
*/
int bisect_create_bilog_table(int iCurrent, const char *zDesc, int bDetail){
char *zLog;
Blob log, id;
| > > > > > > > > > > > > > > > > < > | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
** Append a new skip entry to the bisect log.
*/
static void bisect_append_skip(int rid){
db_multi_exec(
"UPDATE vvar SET value=value||' s%d' WHERE name='bisect-log'", rid
);
}
/*
** Append a VALUES entry to the bilog table insert
*/
static void bisect_log_append(Blob *pSql,int iSeq,const char *zStat,int iRid){
if( (iSeq%6)==3 ){
blob_append_sql(pSql, ",\n ");
}else if( iSeq>1 ){
blob_append_sql(pSql, ",");
}
if( zStat ){
blob_append_sql(pSql, "(%d,%Q,%d)", iSeq, zStat, iRid);
}else{
blob_append_sql(pSql, "(NULL,NULL,%d)", iRid);
}
}
/*
** Create a TEMP table named "bilog" that contains the complete history
** of the current bisect.
**
** If iCurrent>0 then it is the RID of the current check-out and is included
** in the history table.
**
** If zDesc is not NULL, then it is the bid= query parameter to /timeline
** that describes a bisect. Use the information in zDesc rather than in
** the bisect-log variable.
**
** If bDetail is true, then also include information about every node
** in between the inner-most GOOD and BAD nodes.
*/
int bisect_create_bilog_table(int iCurrent, const char *zDesc, int bDetail){
char *zLog;
Blob log, id;
int cnt = 0;
int lastGood = -1;
int lastBad = -1;
Blob ins = BLOB_INITIALIZER;
if( zDesc!=0 ){
blob_init(&log, 0, 0);
while( zDesc[0]=='y' || zDesc[0]=='n' || zDesc[0]=='s' ){
int i;
char c;
int rid;
|
| ︙ | ︙ | |||
251 252 253 254 255 256 257 |
db_multi_exec(
"CREATE TEMP TABLE bilog("
" rid INTEGER PRIMARY KEY," /* Sequence of events */
" stat TEXT," /* Type of occurrence */
" seq INTEGER UNIQUE" /* Check-in number */
");"
);
| | < | | < | < < | < < < | < < < < < | < < | > | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
db_multi_exec(
"CREATE TEMP TABLE bilog("
" rid INTEGER PRIMARY KEY," /* Sequence of events */
" stat TEXT," /* Type of occurrence */
" seq INTEGER UNIQUE" /* Check-in number */
");"
);
blob_append_sql(&ins, "INSERT OR IGNORE INTO bilog(seq,stat,rid) VALUES");
while( blob_token(&log, &id) ){
int rid;
cnt++;
if( blob_str(&id)[0]=='s' ){
rid = atoi(blob_str(&id)+1);
bisect_log_append(&ins, cnt, "SKIP", rid);
}else{
rid = atoi(blob_str(&id));
if( rid>0 ){
bisect_log_append(&ins, cnt, "GOOD", rid);
lastGood = rid;
}else{
bisect_log_append(&ins, cnt, "BAD", rid);
lastBad = -rid;
}
}
}
if( iCurrent>0 ){
bisect_log_append(&ins, ++cnt, "CURRENT", iCurrent);
}
if( bDetail && lastGood>0 && lastBad>0 ){
PathNode *p;
p = path_shortest(lastGood, lastBad, bisect_option("direct-only"),0, 0);
while( p ){
bisect_log_append(&ins, ++cnt, 0, p->rid);
p = p->u.pTo;
}
path_reset();
}
db_exec_sql(blob_sql_text(&ins));
blob_reset(&ins);
return 1;
}
/* Return a permalink description of a bisect. Space is obtained from
** fossil_malloc() and should be freed by the caller.
**
** A bisect description consists of characters 'y' and 'n' and lowercase
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
int iStartLine; /* Line of zStartFile where transaction started */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* Argument to the authorizer */
const char *zAuthName; /* Name of the authorizer */
int bProtectTriggers; /* True if protection triggers already exist */
int nProtect; /* Slots of aProtect used */
unsigned aProtect[12]; /* Saved values of protectMask */
} db = {
PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
0, 0, 0, 0, 0, 0, 0, {{0}}, {0}, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}};
/*
** Arrange for the given file to be deleted on a failure.
*/
| > > | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
int iStartLine; /* Line of zStartFile where transaction started */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* Argument to the authorizer */
const char *zAuthName; /* Name of the authorizer */
int bProtectTriggers; /* True if protection triggers already exist */
int nProtect; /* Slots of aProtect used */
unsigned aProtect[12]; /* Saved values of protectMask */
int pauseDmlLog; /* Ignore pDmlLog if positive */
Blob *pDmlLog; /* Append DML statements here, of not NULL */
} db = {
PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
0, 0, 0, 0, 0, 0, 0, {{0}}, {0}, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}};
/*
** Arrange for the given file to be deleted on a failure.
*/
|
| ︙ | ︙ | |||
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
/*
** Possible flags to db_vprepare
*/
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
#endif
/*
** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
** If the input string contains multiple SQL statements, only the first
** one is processed. All statements beyond the first are silently ignored.
*/
int db_vprepare(Stmt *pStmt, int flags, const char *zFormat, va_list ap){
int rc;
int prepFlags = 0;
char *zSql;
const char *zExtra = 0;
blob_zero(&pStmt->sql);
blob_vappendf(&pStmt->sql, zFormat, ap);
va_end(ap);
zSql = blob_str(&pStmt->sql);
db.nPrepare++;
if( flags & DB_PREPARE_PERSISTENT ){
prepFlags = SQLITE_PREPARE_PERSISTENT;
}
rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
db_err("%s\n%s", sqlite3_errmsg(g.db), zSql);
}else if( zExtra && !fossil_all_whitespace(zExtra) ){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
/*
** Possible flags to db_vprepare
*/
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
#endif
/*
** If zSql is a DML statement, append it db.pDmlLog.
*/
static void db_append_dml(const char *zSql){
size_t nSql;
if( db.pDmlLog==0 ) return;
if( db.pauseDmlLog ) return;
if( zSql==0 ) return;
nSql = strlen(zSql);
while( nSql>0 && fossil_isspace(zSql[0]) ){ nSql--; zSql++; }
while( nSql>0 && fossil_isspace(zSql[nSql-1]) ) nSql--;
if( nSql<6 ) return;
if( strncmp(zSql, "SELECT", 6)==0 ) return;
if( strncmp(zSql, "PRAGMA", 6)==0 ) return;
blob_append(db.pDmlLog, zSql, nSql);
if( zSql[nSql-1]!=';' ) blob_append_char(db.pDmlLog, ';');
blob_append_char(db.pDmlLog, '\n');
}
/*
** Set the Blob to which DML statement text should be appended. Set it
** to zero to stop appending DML statement text.
*/
void db_append_dml_to_blob(Blob *pBlob){
db.pDmlLog = pBlob;
}
/*
** Pause or unpause the DML log
*/
void db_pause_dml_log(void){ db.pauseDmlLog++; }
void db_unpause_dml_log(void){ db.pauseDmlLog--; }
/*
** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
** If the input string contains multiple SQL statements, only the first
** one is processed. All statements beyond the first are silently ignored.
*/
int db_vprepare(Stmt *pStmt, int flags, const char *zFormat, va_list ap){
int rc;
int prepFlags = 0;
char *zSql;
const char *zExtra = 0;
blob_zero(&pStmt->sql);
blob_vappendf(&pStmt->sql, zFormat, ap);
va_end(ap);
zSql = blob_str(&pStmt->sql);
db.nPrepare++;
db_append_dml(zSql);
if( flags & DB_PREPARE_PERSISTENT ){
prepFlags = SQLITE_PREPARE_PERSISTENT;
}
rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
db_err("%s\n%s", sqlite3_errmsg(g.db), zSql);
}else if( zExtra && !fossil_all_whitespace(zExtra) ){
|
| ︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 |
while( rc==SQLITE_OK && z[0] ){
pStmt = 0;
rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
if( rc ){
db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
}else if( pStmt ){
db.nPrepare++;
while( sqlite3_step(pStmt)==SQLITE_ROW ){}
rc = sqlite3_finalize(pStmt);
if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
}
z = zEnd;
}
return rc;
| > | 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 |
while( rc==SQLITE_OK && z[0] ){
pStmt = 0;
rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
if( rc ){
db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
}else if( pStmt ){
db.nPrepare++;
db_append_dml(sqlite3_sql(pStmt));
while( sqlite3_step(pStmt)==SQLITE_ROW ){}
rc = sqlite3_finalize(pStmt);
if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
}
z = zEnd;
}
return rc;
|
| ︙ | ︙ |
Changes to src/descendants.c.
| ︙ | ︙ | |||
200 201 202 203 204 205 206 |
double rLimitMtime = 0.0;
if( ridBackTo ){
rLimitMtime = db_double(0.0,
"SELECT mtime FROM event WHERE objid=%d",
ridBackTo);
}
db_multi_exec(
| | | | | | | | | | | | | | | | | | | < | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
double rLimitMtime = 0.0;
if( ridBackTo ){
rLimitMtime = db_double(0.0,
"SELECT mtime FROM event WHERE objid=%d",
ridBackTo);
}
db_multi_exec(
"WITH RECURSIVE\n"
" parent(pid,cid,isCP) AS (\n"
" SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink\n"
" UNION ALL\n"
" SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude\n"
" ),\n"
" ancestor(rid, mtime, isCP) AS (\n"
" SELECT %d, mtime, 0 FROM event WHERE objid=%d\n"
" UNION\n"
" SELECT parent.pid, event.mtime, parent.isCP\n"
" FROM ancestor, parent, event\n"
" WHERE parent.cid=ancestor.rid\n"
" AND event.objid=parent.pid\n"
" AND NOT ancestor.isCP\n"
" AND (event.mtime>=%.17g OR parent.pid=%d)\n"
" ORDER BY mtime DESC LIMIT %d\n"
" )\n"
"INSERT OR IGNORE INTO ok SELECT rid FROM ancestor;",
rid, rid, rLimitMtime, ridBackTo, N
);
if( ridBackTo && db_changes()>1 ){
db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
}
}
}
|
| ︙ | ︙ | |||
320 321 322 323 324 325 326 |
void compute_descendants(int rid, int N){
if( !N ){
N = -1;
}else if( N<0 ){
N = -N;
}
db_multi_exec(
| | | | | | | | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
void compute_descendants(int rid, int N){
if( !N ){
N = -1;
}else if( N<0 ){
N = -N;
}
db_multi_exec(
"WITH RECURSIVE\n"
" dx(rid,mtime) AS (\n"
" SELECT %d, 0\n"
" UNION\n"
" SELECT plink.cid, plink.mtime FROM dx, plink\n"
" WHERE plink.pid=dx.rid\n"
" ORDER BY 2\n"
" )\n"
"INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
rid, N
);
}
/*
** COMMAND: descendants*
|
| ︙ | ︙ | |||
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 |
#if INTERFACE
/* Flag parameters to compute_uses_file() */
#define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
#endif
/*
** Add to table zTab the record ID (rid) of every check-in that contains
** the file fid.
*/
void compute_uses_file(const char *zTab, int fid, int usesFlags){
Bag seen;
Bag pending;
| > > > > > > > > > > > > > > > | > | | < < | < < | < < > | | 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 |
#if INTERFACE
/* Flag parameters to compute_uses_file() */
#define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
#endif
/*
** Append a new VALUES term.
*/
static void uses_file_append_term(Blob *pSql, int *pnCnt, int rid){
if( *pnCnt==0 ){
blob_append_sql(pSql, "(%d)", rid);
*pnCnt = 4;
}else if( (*pnCnt)%10==9 ){
blob_append_sql(pSql, ",\n (%d)", rid);
}else{
blob_append_sql(pSql, ",(%d)", rid);
}
++*pnCnt;
}
/*
** Add to table zTab the record ID (rid) of every check-in that contains
** the file fid.
*/
void compute_uses_file(const char *zTab, int fid, int usesFlags){
Bag seen;
Bag pending;
Blob ins = BLOB_INITIALIZER;
int nIns = 0;
Stmt q;
int rid;
bag_init(&seen);
bag_init(&pending);
blob_append_sql(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES", zTab);
db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
while( db_step(&q)==SQLITE_ROW ){
int mid = db_column_int(&q, 0);
bag_insert(&pending, mid);
bag_insert(&seen, mid);
uses_file_append_term(&ins, &nIns, mid);
}
db_finalize(&q);
db_prepare(&q, "SELECT mid FROM mlink WHERE pid=%d", fid);
while( db_step(&q)==SQLITE_ROW ){
int mid = db_column_int(&q, 0);
bag_insert(&seen, mid);
if( usesFlags & USESFILE_DELETE ){
uses_file_append_term(&ins, &nIns, mid);
}
}
db_finalize(&q);
db_prepare(&q, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
while( (rid = bag_first(&pending))!=0 ){
bag_remove(&pending, rid);
db_bind_int(&q, ":rid", rid);
while( db_step(&q)==SQLITE_ROW ){
int mid = db_column_int(&q, 0);
if( bag_find(&seen, mid) ) continue;
bag_insert(&seen, mid);
bag_insert(&pending, mid);
uses_file_append_term(&ins, &nIns, mid);
}
db_reset(&q);
}
db_finalize(&q);
db_exec_sql(blob_str(&ins));
blob_reset(&ins);
bag_clear(&seen);
bag_clear(&pending);
}
|
Changes to src/timeline.c.
| ︙ | ︙ | |||
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 |
int ans = 0;
tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
if( tagId==0 ){
endId = symbolic_name_to_rid(zEnd, "ci");
if( endId==0 ) return 0;
}
if( bForward ){
if( tagId ){
db_prepare(&q,
"WITH RECURSIVE dx(id,mtime) AS ("
" SELECT %d, event.mtime FROM event WHERE objid=%d"
" UNION"
" SELECT plink.cid, plink.mtime"
| > | 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 |
int ans = 0;
tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
if( tagId==0 ){
endId = symbolic_name_to_rid(zEnd, "ci");
if( endId==0 ) return 0;
}
db_pause_dml_log();
if( bForward ){
if( tagId ){
db_prepare(&q,
"WITH RECURSIVE dx(id,mtime) AS ("
" SELECT %d, event.mtime FROM event WHERE objid=%d"
" UNION"
" SELECT plink.cid, plink.mtime"
|
| ︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 |
);
}
}
if( db_step(&q)==SQLITE_ROW ){
ans = db_column_int(&q, 0);
}
db_finalize(&q);
return ans;
}
/*
** COMMAND: test-endpoint
**
** Usage: fossil test-endpoint BASE TAG ?OPTIONS?
| > | 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 |
);
}
}
if( db_step(&q)==SQLITE_ROW ){
ans = db_column_int(&q, 0);
}
db_finalize(&q);
db_unpause_dml_log();
return ans;
}
/*
** COMMAND: test-endpoint
**
** Usage: fossil test-endpoint BASE TAG ?OPTIONS?
|
| ︙ | ︙ | |||
1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 |
int secondaryRid = 0; /* Show secondary highlight */
int disableY = 0; /* Disable type selector on submenu */
int advancedMenu = 0; /* Use the advanced menu design */
char *zPlural; /* Ending for plural forms */
int showCherrypicks = 1; /* True to show cherrypick merges */
int haveParameterN; /* True if n= query parameter present */
int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
login_check_credentials();
url_initialize(&url, "timeline");
cgi_query_parameters_to_url(&url);
(void)P_NoBot("ss")
/* "ss" is processed via the udc but at least one spider likes to
** try to SQL inject via this argument, so let's catch that. */;
/* Set number of rows to display */
z = P("n");
| > > > | 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 |
int secondaryRid = 0; /* Show secondary highlight */
int disableY = 0; /* Disable type selector on submenu */
int advancedMenu = 0; /* Use the advanced menu design */
char *zPlural; /* Ending for plural forms */
int showCherrypicks = 1; /* True to show cherrypick merges */
int haveParameterN; /* True if n= query parameter present */
int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
int showSql = PB("showsql"); /* True to show the SQL */
Blob allSql; /* Copy of all SQL text */
login_check_credentials();
url_initialize(&url, "timeline");
cgi_query_parameters_to_url(&url);
blob_init(&allSql, 0, 0);
(void)P_NoBot("ss")
/* "ss" is processed via the udc but at least one spider likes to
** try to SQL inject via this argument, so let's catch that. */;
/* Set number of rows to display */
z = P("n");
|
| ︙ | ︙ | |||
2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 |
if( PB("deltabg") ){
tmFlags |= TIMELINE_DELTA;
}
if( PB("nc") ){
tmFlags &= ~(TIMELINE_DELTA|TIMELINE_BRCOLOR|TIMELINE_UCOLOR);
tmFlags |= TIMELINE_NOCOLOR;
}
if( zUses!=0 ){
int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
if( ufid ){
zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
compute_uses_file("usesfile", ufid, 0);
zType = "ci";
disableY = 1;
if( !haveParameterN ) nEntry = 0;
}else{
zUses = 0;
}
}
if( renameOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO rnfile"
| > | | | | | | | | | | | | | | | | 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 |
if( PB("deltabg") ){
tmFlags |= TIMELINE_DELTA;
}
if( PB("nc") ){
tmFlags &= ~(TIMELINE_DELTA|TIMELINE_BRCOLOR|TIMELINE_UCOLOR);
tmFlags |= TIMELINE_NOCOLOR;
}
if( showSql ) db_append_dml_to_blob(&allSql);
if( zUses!=0 ){
int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
if( ufid ){
zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
compute_uses_file("usesfile", ufid, 0);
zType = "ci";
disableY = 1;
if( !haveParameterN ) nEntry = 0;
}else{
zUses = 0;
}
}
if( renameOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO rnfile"
" SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
);
disableY = 1;
}
if( forkOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfork(rid INTEGER PRIMARY KEY);\n"
"INSERT OR IGNORE INTO rnfork(rid)\n"
" SELECT pid FROM plink\n"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" GROUP BY pid\n"
" HAVING count(*)>1;\n"
"INSERT OR IGNORE INTO rnfork(rid)\n"
" SELECT cid FROM plink\n"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" GROUP BY cid\n"
" HAVING count(*)>1;\n",
TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
);
db_multi_exec(
"INSERT OR IGNORE INTO rnfork(rid)\n"
" SELECT cid FROM plink\n"
" WHERE pid IN rnfork\n"
" AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" UNION\n"
" SELECT pid FROM plink\n"
" WHERE cid IN rnfork\n"
" AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n",
TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
);
tmFlags |= TIMELINE_UNHIDE;
zType = "ci";
disableY = 1;
}
if( bisectLocal && cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){
|
| ︙ | ︙ | |||
2237 2238 2239 2240 2241 2242 2243 |
zTo = P("you");
earlierRid = me_rid;
laterRid = you_rid;
}
}
blob_init(&ins, 0, 0);
db_multi_exec(
| | > > > > > > | > | | | | | | 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 |
zTo = P("you");
earlierRid = me_rid;
laterRid = you_rid;
}
}
blob_init(&ins, 0, 0);
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS pathnode(x INTEGER PRIMARY KEY);"
);
if( p ){
int cnt = 4;
blob_init(&ins, 0, 0);
blob_append_sql(&ins, "INSERT INTO pathnode(x) VALUES(%d)", p->rid);
p = p->u.pTo;
while( p ){
if( cnt==8 ){
blob_append_sql(&ins, ",\n (%d)", p->rid);
cnt = 0;
}else{
cnt++;
blob_append_sql(&ins, ",(%d)", p->rid);
}
p = p->u.pTo;
}
}
path_reset();
db_multi_exec("%s", blob_str(&ins)/*safe-for-%s*/);
blob_reset(&ins);
if( related || P("mionly") ){
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS related(x INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO related(x)"
" SELECT pid FROM plink WHERE cid IN pathnode AND NOT isprim;"
);
if( P("mionly")==0 ){
db_multi_exec(
"INSERT OR IGNORE INTO related(x)"
" SELECT cid FROM plink WHERE pid IN pathnode;"
);
}
if( showCherrypicks ){
db_multi_exec(
"INSERT OR IGNORE INTO related(x)"
" SELECT parentid FROM cherrypick WHERE childid IN pathnode;"
);
if( P("mionly")==0 ){
db_multi_exec(
"INSERT OR IGNORE INTO related(x)"
" SELECT childid FROM cherrypick WHERE parentid IN pathnode;"
);
}
}
db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
if( earlierRid && laterRid && commonAncs==earlierRid ){
/* On a query with me=XXX, you=YYY, and rel, omit all nodes that
** are not ancestors of either XXX or YYY, as those nodes tend to
|
| ︙ | ︙ | |||
2361 2362 2363 2364 2365 2366 2367 |
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
p_rid ? p_rid : d_rid);
zCiName = zDPName;
if( zCiName==0 ) zCiName = zUuid;
blob_append_sql(&sql, " AND event.objid IN ok");
nd = 0;
if( d_rid ){
| < > > > | | < | | | | | | | | < < < < | 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 |
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
p_rid ? p_rid : d_rid);
zCiName = zDPName;
if( zCiName==0 ) zCiName = zUuid;
blob_append_sql(&sql, " AND event.objid IN ok");
nd = 0;
if( d_rid ){
double rStopTime = 9e99;
zFwdTo = P("ft");
if( zFwdTo ){
double rStartDate = db_double(0.0,
"SELECT mtime FROM event WHERE objid=%d", d_rid);
ridFwdTo = first_checkin_with_tag_after_date(zFwdTo, rStartDate);
if( ridFwdTo==0 ){
ridFwdTo = name_to_typed_rid(zBackTo,"ci");
}
if( ridFwdTo ){
if( !haveParameterN ) nEntry = 0;
rStopTime = db_double(9e99,
"SELECT mtime FROM event WHERE objid=%d", ridFwdTo);
}
}
if( rStopTime<9e99 ){
rStopTime += 5.8e-6; /* Round up by 1/2 second */
}
db_multi_exec(
"WITH RECURSIVE dx(rid,mtime) AS (\n"
" SELECT %d, 0\n"
" UNION\n"
" SELECT plink.cid, plink.mtime FROM dx, plink\n"
" WHERE plink.pid=dx.rid\n"
" AND plink.mtime<=%.*g\n"
" ORDER BY 2\n"
")\n"
"INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
d_rid, rStopTime<8e99 ? 17 : 2, rStopTime, nEntry<=0 ? -1 : nEntry+1
);
nd = db_int(0, "SELECT count(*)-1 FROM ok");
if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
if( nd>0 || p_rid==0 ){
blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
}
if( useDividers && !selectedRid ) selectedRid = d_rid;
db_multi_exec("DELETE FROM ok");
|
| ︙ | ︙ | |||
2506 2507 2508 2509 2510 2511 2512 |
blob_zero(&cond);
tmFlags |= TIMELINE_FILLGAPS;
if( zChng && *zChng ){
addFileGlobExclusion(zChng, &cond);
tmFlags |= TIMELINE_XMERGE;
}
if( zUses ){
| | | | | | | 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 |
blob_zero(&cond);
tmFlags |= TIMELINE_FILLGAPS;
if( zChng && *zChng ){
addFileGlobExclusion(zChng, &cond);
tmFlags |= TIMELINE_XMERGE;
}
if( zUses ){
blob_append_sql(&cond, " AND event.objid IN usesfile\n");
}
if( renameOnly ){
blob_append_sql(&cond, " AND event.objid IN rnfile\n");
}
if( forkOnly ){
blob_append_sql(&cond, " AND event.objid IN rnfork\n");
}
if( cpOnly && showCherrypicks ){
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS cpnodes(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO cpnodes SELECT childid FROM cherrypick;"
"INSERT OR IGNORE INTO cpnodes SELECT parentid FROM cherrypick;"
);
blob_append_sql(&cond, " AND event.objid IN cpnodes\n");
}
if( bisectLocal || zBisect!=0 ){
blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
}
if( zYearMonth ){
char *zNext;
zYearMonth = timeline_expand_datetime(zYearMonth);
if( strlen(zYearMonth)>7 ){
zYearMonth = mprintf("%.7s", zYearMonth);
}
|
| ︙ | ︙ | |||
2876 2877 2878 2879 2880 2881 2882 |
Blob sql2;
blob_init(&sql2, blob_sql_text(&sql), -1);
blob_append_sql(&sql2,
" AND event.mtime>=%f ORDER BY event.mtime ASC", rCirca);
if( nEntry>0 ){
blob_append_sql(&sql2," LIMIT %d", (nEntry+1)/2);
}
| < < < | 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 |
Blob sql2;
blob_init(&sql2, blob_sql_text(&sql), -1);
blob_append_sql(&sql2,
" AND event.mtime>=%f ORDER BY event.mtime ASC", rCirca);
if( nEntry>0 ){
blob_append_sql(&sql2," LIMIT %d", (nEntry+1)/2);
}
db_multi_exec("%s", blob_sql_text(&sql2));
if( nEntry>0 ){
nEntry -= db_int(0,"select count(*) from timeline");
if( nEntry<=0 ) nEntry = 1;
}
blob_reset(&sql2);
blob_append_sql(&sql,
|
| ︙ | ︙ | |||
3033 3034 3035 3036 3037 3038 3039 |
if( advancedMenu ){
style_submenu_entry("t", "Tag Filter:", -8, 0);
style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
}
}
blob_zero(&cond);
}
| | > | > | 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 |
if( advancedMenu ){
style_submenu_entry("t", "Tag Filter:", -8, 0);
style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
}
}
blob_zero(&cond);
}
if( showSql ){
db_append_dml_to_blob(0);
@ <pre>%h(blob_str(&allSql))</pre>
blob_reset(&allSql);
}
if( search_restrict(SRCH_CKIN)!=0 ){
style_submenu_element("Search", "%R/search?y=c");
}
if( advancedMenu ){
style_submenu_element("Basic", "%s",
url_render(&url, "advm", "0", "udc", "1"));
|
| ︙ | ︙ |