Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Improvements to /finfo: Show all file rename events. The "rid" for each timeline entry must be a combination of the file-id "fid" and the filename-id "fnid" since either one of those two might change which should result in a new entry on the timeline. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
8c598d7232c227e199612aa305e85d0f |
| User & Date: | drh 2020-10-19 18:24:41.157 |
Context
|
2020-10-19
| ||
| 20:09 | Do a better job of showing when a file is added, deleted, or renamed in the /finfo page. check-in: a0bca48147 user: drh tags: trunk | |
| 18:24 | Improvements to /finfo: Show all file rename events. The "rid" for each timeline entry must be a combination of the file-id "fid" and the filename-id "fnid" since either one of those two might change which should result in a new entry on the timeline. check-in: 8c598d7232 user: drh tags: trunk | |
| 14:37 | Use the new multi-recursive-term capability of CTEs in SQLite to fix the /finfo clade calculation, and to make /finfo run about 5x faster. check-in: 47bfea074b user: drh tags: trunk | |
Changes
Changes to src/finfo.c.
| ︙ | ︙ | |||
331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
int fShowId = P("showid")!=0;
Stmt qparent;
int iTableId = timeline_tableid();
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
const char *zMark; /* Mark this version of the file */
int selRid = 0; /* RID of the marked file version */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
ridCi = zCI ? name_to_rid_www("ci") : 0;
if( fnid==0 ){
style_header("No such file");
| > | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
int fShowId = P("showid")!=0;
Stmt qparent;
int iTableId = timeline_tableid();
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
const char *zMark; /* Mark this version of the file */
int selRid = 0; /* RID of the marked file version */
int mxfnid; /* Maximum filename.fnid value */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
ridCi = zCI ? name_to_rid_www("ci") : 0;
if( fnid==0 ){
style_header("No such file");
|
| ︙ | ︙ | |||
390 391 392 393 394 395 396 |
blob_append_sql(&sql,
/* The clade(fid,fnid) table is the set of all (fid,fnid) pairs
** that should participate in the output. Clade is computed by
** walking the graph of mlink edges.
*/
"WITH RECURSIVE clade(fid,fnid) AS (\n"
" SELECT blob.rid, %d FROM blob\n" /* %d is fnid */
| | | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
blob_append_sql(&sql,
/* The clade(fid,fnid) table is the set of all (fid,fnid) pairs
** that should participate in the output. Clade is computed by
** walking the graph of mlink edges.
*/
"WITH RECURSIVE clade(fid,fnid) AS (\n"
" SELECT blob.rid, %d FROM blob\n" /* %d is fnid */
" WHERE blob.uuid=(SELECT uuid FROM files_of_checkin(%Q)"
" WHERE filename=%Q)\n" /* %Q is the filename */
" UNION\n"
" SELECT mlink.fid, mlink.fnid\n"
" FROM clade, mlink\n"
" WHERE clade.fid=mlink.pid\n"
" AND ((mlink.pfnid=0 AND mlink.fnid=clade.fnid)\n"
" OR mlink.pfnid=clade.fnid)\n"
|
| ︙ | ︙ | |||
475 476 477 478 479 480 481 |
** files are deleted (when they have mlink.fid==0). If the same file
** is deleted in multiple places, we want to show each deletion, so
** use a "fake fid" which is derived from the parent-fid for grouping.
** The same fake-fid must be used on the graph.
*/
blob_append_sql(&sql,
"GROUP BY"
| | > | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
** files are deleted (when they have mlink.fid==0). If the same file
** is deleted in multiple places, we want to show each deletion, so
** use a "fake fid" which is derived from the parent-fid for grouping.
** The same fake-fid must be used on the graph.
*/
blob_append_sql(&sql,
"GROUP BY"
" CASE WHEN mlink.fid>0 THEN mlink.fid ELSE mlink.pid+1000000000 END,"
" mlink.fnid\n"
);
}
blob_append_sql(&sql, "ORDER BY event.mtime DESC");
if( (n = atoi(PD("n","0")))>0 ){
blob_append_sql(&sql, " LIMIT %d", n);
url_add_parameter(&url, "n", P("n"));
}
|
| ︙ | ︙ | |||
536 537 538 539 540 541 542 543 544 |
if( uBg ){
blob_append(&title, " (color-coded by user)", -1);
}
@ <h2>%b(&title)</h2>
blob_reset(&title);
pGraph = graph_init();
@ <table id="timelineTable%d(iTableId)" class="timelineTable">
if( ridFrom ){
db_prepare(&qparent,
| > | > | | > | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
if( uBg ){
blob_append(&title, " (color-coded by user)", -1);
}
@ <h2>%b(&title)</h2>
blob_reset(&title);
pGraph = graph_init();
@ <table id="timelineTable%d(iTableId)" class="timelineTable">
mxfnid = db_int(0, "SELECT max(fnid) FROM filename");
if( ridFrom ){
db_prepare(&qparent,
"SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
" FROM mlink"
" WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
" AND pmid IN (SELECT rid FROM ancestor)"
" ORDER BY isaux /*sort*/", mxfnid+1
);
}else{
db_prepare(&qparent,
"SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
" FROM mlink"
" WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
" ORDER BY isaux /*sort*/", mxfnid+1
);
}
while( db_step(&q)==SQLITE_ROW ){
const char *zDate = db_column_text(&q, 0);
const char *zCom = db_column_text(&q, 1);
const char *zUser = db_column_text(&q, 2);
int fpid = db_column_int(&q, 3);
|
| ︙ | ︙ | |||
585 586 587 588 589 590 591 |
db_reset(&qparent);
if( zBr==0 ) zBr = "trunk";
if( uBg ){
zBgClr = hash_color(zUser);
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
}
| | > | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
db_reset(&qparent);
if( zBr==0 ) zBr = "trunk";
if( uBg ){
zBgClr = hash_color(zUser);
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
}
gidx = graph_add_row(pGraph,
frid>0 ? frid*(mxfnid+1)+fnid : fpid+1000000000,
nParent, 0, aParent, zBr, zBgClr,
zUuid, 0);
if( strncmp(zDate, zPrevDate, 10) ){
sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
@ <tr><td>
@ <div class="divider timelineDate">%s(zPrevDate)</div>
@ </td><td></td><td></td></tr>
|
| ︙ | ︙ | |||
637 638 639 640 641 642 643 644 645 646 647 648 649 650 |
@ <td class="timelineDetailCell">
}
}
if( tmFlags & TIMELINE_COMPACT ){
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
}
cgi_printf("<span class='timeline%sDetail'>", zStyle);
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
@ file: %z(href("%R/file?name=%T&ci=%!S",zFName,zCkin))\
@ [%S(zUuid)]</a>
if( fShowId ){
int srcId = delta_source_rid(frid);
if( srcId>0 ){
| > > > > > > | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
@ <td class="timelineDetailCell">
}
}
if( tmFlags & TIMELINE_COMPACT ){
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
}
cgi_printf("<span class='timeline%sDetail'>", zStyle);
if( pfnid ){
char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
pfnid);
@ <b>Renamed</b> %h(zPrevName) → %h(zFName).
fossil_free(zPrevName);
}
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
@ file: %z(href("%R/file?name=%T&ci=%!S",zFName,zCkin))\
@ [%S(zUuid)]</a>
if( fShowId ){
int srcId = delta_source_rid(frid);
if( srcId>0 ){
|
| ︙ | ︙ | |||
663 664 665 666 667 668 669 |
hyperlink_to_user(zUser, zDate, ",");
@ branch: %z(href("%R/timeline?t=%T",zBr))%h(zBr)</a>,
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ){
@ size: %d(szFile))
}else{
@ size: %d(szFile)
}
| | < | < < < < < < | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
hyperlink_to_user(zUser, zDate, ",");
@ branch: %z(href("%R/timeline?t=%T",zBr))%h(zBr)</a>,
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ){
@ size: %d(szFile))
}else{
@ size: %d(szFile)
}
if( zUuid && ridTo==0 && nParent==0 ){
@ <b>Added</b>
}
if( zUuid==0 ){
char *zNewName;
zNewName = db_text(0,
"SELECT name FROM filename WHERE fnid = "
" (SELECT fnid FROM mlink"
" WHERE mid=%d"
|
| ︙ | ︙ |