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 | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
8c598d7232c227e199612aa305e85d0f |
User & Date: | drh 2020-10-19 18:24:41 |
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: a0bca481 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: 8c598d72 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: 47bfea07 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" |
︙ | ︙ |