Fossil SCM

Add the /mlink page (accessible only by Admin users) that shows MLINK table content for a check-in for debugging purposes.

drh 2015-12-24 14:36 trunk
Commit 3fdc2c01279ae85539dee9bffb98b880e4778f73
2 files changed +97 +5 -2
+97
--- src/finfo.c
+++ src/finfo.c
@@ -556,5 +556,102 @@
556556
}
557557
@ </table>
558558
timeline_output_graph_javascript(pGraph, 0, 1);
559559
style_footer();
560560
}
561
+
562
+/*
563
+** WEBPAGE: mlink
564
+** URL: /mlink?name=FILENAME
565
+** URL: /mlink?ci=NAME
566
+**
567
+** Show all MLINK table entries for a particular file, or for
568
+** a particular check-in. This screen is intended for use by developers
569
+** in debugging Fossil.
570
+*/
571
+void mlink_page(void){
572
+ const char *zFName = P("name");
573
+ const char *zCI = P("ci");
574
+ Stmt q;
575
+
576
+ login_check_credentials();
577
+ if( !g.perm.Admin ){ login_needed(g.anon.Admin); return; }
578
+ style_header("MLINK Table");
579
+ if( zFName==0 && zCI==0 ){
580
+ @ <span class='generalError'>
581
+ @ Requires either a name= or ci= query parameter
582
+ @ </span>
583
+ }else if( zFName ){
584
+ @ <span class='generalError'>
585
+ @ name= query parameter is not yet implemented.
586
+ @ </span>
587
+ }else{
588
+ int mid = name_to_rid_www("ci");
589
+ db_prepare(&q,
590
+ "SELECT"
591
+ /* 0 */ " (SELECT name FROM filename WHERE fnid=mlink.fnid),"
592
+ /* 1 */ " fid,"
593
+ /* 2 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid),"
594
+ /* 3 */ " pid,"
595
+ /* 4 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
596
+ /* 5 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid),"
597
+ /* 6 */ " pmid,"
598
+ /* 7 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid),"
599
+ /* 8 */ " mperm,"
600
+ /* 9 */ " isaux"
601
+ " FROM mlink WHERE mid=%d ORDER BY 1",
602
+ mid
603
+ );
604
+ @ <h1>MLINK table for check-in %h(zCI)</h1>
605
+ showContext(mid);
606
+ @ <hr>
607
+ @ <div class='brlist'>
608
+ @ <table id='mlinktable'>
609
+ @ <thead><tr>
610
+ @ <th>File</th>
611
+ @ <th>From</th>
612
+ @ <th>New</th>
613
+ @ <th>Old</th>
614
+ @ <th>Exec</th>
615
+ @ <th>Renamed From</th>
616
+ @ </tr></thead>
617
+ @ <tbody>
618
+ while( db_step(&q)==SQLITE_ROW ){
619
+ const char *zName = db_column_text(&q,0);
620
+ const char *zFid = db_column_text(&q,2);
621
+ const char *zPid = db_column_text(&q,4);
622
+ const char *zParent = db_column_text(&q,7);
623
+ const char *zPrior = db_column_text(&q,5);
624
+ int isExec = db_column_int(&q,8);
625
+ @ <tr>
626
+ @ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td>
627
+ if( zParent ){
628
+ @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td>
629
+ }else{
630
+ @ <td><i>(New)</i></td>
631
+ }
632
+ if( zFid ){
633
+ @ <td><a href='%R/info/%!S(zFid)'>%S(zFid)</a></td>
634
+ }else{
635
+ @ <td><i>(Deleted)</i></td>
636
+ }
637
+ if( zPid ){
638
+ @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a>
639
+ }else{
640
+ @ <td><i>(New)</i></td>
641
+ }
642
+ @ <td>%s(isExec?"X":"")</td>
643
+ if( zPrior ){
644
+ @ <td><a href='%R/finfo?name=%t(zPrior)'>%h(zPrior)</a></td>
645
+ }else{
646
+ @ <td></td>
647
+ }
648
+ @ </tr>
649
+ }
650
+ db_finalize(&q);
651
+ @ </tbody>
652
+ @ </table>
653
+ @ </div>
654
+ output_table_sorting_javascript("mlinktable","tttttt",1);
655
+ }
656
+ style_footer();
657
+}
561658
--- src/finfo.c
+++ src/finfo.c
@@ -556,5 +556,102 @@
556 }
557 @ </table>
558 timeline_output_graph_javascript(pGraph, 0, 1);
559 style_footer();
560 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
--- src/finfo.c
+++ src/finfo.c
@@ -556,5 +556,102 @@
556 }
557 @ </table>
558 timeline_output_graph_javascript(pGraph, 0, 1);
559 style_footer();
560 }
561
562 /*
563 ** WEBPAGE: mlink
564 ** URL: /mlink?name=FILENAME
565 ** URL: /mlink?ci=NAME
566 **
567 ** Show all MLINK table entries for a particular file, or for
568 ** a particular check-in. This screen is intended for use by developers
569 ** in debugging Fossil.
570 */
571 void mlink_page(void){
572 const char *zFName = P("name");
573 const char *zCI = P("ci");
574 Stmt q;
575
576 login_check_credentials();
577 if( !g.perm.Admin ){ login_needed(g.anon.Admin); return; }
578 style_header("MLINK Table");
579 if( zFName==0 && zCI==0 ){
580 @ <span class='generalError'>
581 @ Requires either a name= or ci= query parameter
582 @ </span>
583 }else if( zFName ){
584 @ <span class='generalError'>
585 @ name= query parameter is not yet implemented.
586 @ </span>
587 }else{
588 int mid = name_to_rid_www("ci");
589 db_prepare(&q,
590 "SELECT"
591 /* 0 */ " (SELECT name FROM filename WHERE fnid=mlink.fnid),"
592 /* 1 */ " fid,"
593 /* 2 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid),"
594 /* 3 */ " pid,"
595 /* 4 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
596 /* 5 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid),"
597 /* 6 */ " pmid,"
598 /* 7 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid),"
599 /* 8 */ " mperm,"
600 /* 9 */ " isaux"
601 " FROM mlink WHERE mid=%d ORDER BY 1",
602 mid
603 );
604 @ <h1>MLINK table for check-in %h(zCI)</h1>
605 showContext(mid);
606 @ <hr>
607 @ <div class='brlist'>
608 @ <table id='mlinktable'>
609 @ <thead><tr>
610 @ <th>File</th>
611 @ <th>From</th>
612 @ <th>New</th>
613 @ <th>Old</th>
614 @ <th>Exec</th>
615 @ <th>Renamed From</th>
616 @ </tr></thead>
617 @ <tbody>
618 while( db_step(&q)==SQLITE_ROW ){
619 const char *zName = db_column_text(&q,0);
620 const char *zFid = db_column_text(&q,2);
621 const char *zPid = db_column_text(&q,4);
622 const char *zParent = db_column_text(&q,7);
623 const char *zPrior = db_column_text(&q,5);
624 int isExec = db_column_int(&q,8);
625 @ <tr>
626 @ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td>
627 if( zParent ){
628 @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td>
629 }else{
630 @ <td><i>(New)</i></td>
631 }
632 if( zFid ){
633 @ <td><a href='%R/info/%!S(zFid)'>%S(zFid)</a></td>
634 }else{
635 @ <td><i>(Deleted)</i></td>
636 }
637 if( zPid ){
638 @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a>
639 }else{
640 @ <td><i>(New)</i></td>
641 }
642 @ <td>%s(isExec?"X":"")</td>
643 if( zPrior ){
644 @ <td><a href='%R/finfo?name=%t(zPrior)'>%h(zPrior)</a></td>
645 }else{
646 @ <td></td>
647 }
648 @ </tr>
649 }
650 db_finalize(&q);
651 @ </tbody>
652 @ </table>
653 @ </div>
654 output_table_sorting_javascript("mlinktable","tttttt",1);
655 }
656 style_footer();
657 }
658
+5 -2
--- src/info.c
+++ src/info.c
@@ -295,14 +295,13 @@
295295
296296
/*
297297
** Show the context graph (immediate parents and children) for
298298
** check-in rid.
299299
*/
300
-static void showContext(int rid){
300
+void showContext(int rid){
301301
Blob sql;
302302
Stmt q;
303
- @ <div class="section">Context</div>
304303
blob_zero(&sql);
305304
blob_append(&sql, timeline_query_for_www(), -1);
306305
db_multi_exec(
307306
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
308307
"INSERT INTO ok VALUES(%d);"
@@ -690,10 +689,11 @@
690689
style_header("Check-in Information");
691690
login_anonymous_available();
692691
}
693692
db_finalize(&q1);
694693
showTags(rid);
694
+ @ <div class="section">Context</div>
695695
showContext(rid);
696696
@ <div class="section">Changes</div>
697697
@ <div class="sectionmenu">
698698
verboseFlag = g.zPath[0]!='c';
699699
if( db_get_boolean("show-version-diffs", 0)==0 ){
@@ -728,10 +728,13 @@
728728
}
729729
if( zParent ){
730730
@ %z(xhref("class='button'","%R/vpatch?from=%!S&to=%!S",zParent,zUuid))
731731
@ Patch</a>
732732
}
733
+ if( g.perm.Admin ){
734
+ @ %z(xhref("class='button'","%R/mlink?ci=%!S",zUuid))MLink Table</a>
735
+ }
733736
@</div>
734737
if( pRe ){
735738
@ <p><b>Only differences that match regular expression "%h(zRe)"
736739
@ are shown.</b></p>
737740
}
738741
--- src/info.c
+++ src/info.c
@@ -295,14 +295,13 @@
295
296 /*
297 ** Show the context graph (immediate parents and children) for
298 ** check-in rid.
299 */
300 static void showContext(int rid){
301 Blob sql;
302 Stmt q;
303 @ <div class="section">Context</div>
304 blob_zero(&sql);
305 blob_append(&sql, timeline_query_for_www(), -1);
306 db_multi_exec(
307 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
308 "INSERT INTO ok VALUES(%d);"
@@ -690,10 +689,11 @@
690 style_header("Check-in Information");
691 login_anonymous_available();
692 }
693 db_finalize(&q1);
694 showTags(rid);
 
695 showContext(rid);
696 @ <div class="section">Changes</div>
697 @ <div class="sectionmenu">
698 verboseFlag = g.zPath[0]!='c';
699 if( db_get_boolean("show-version-diffs", 0)==0 ){
@@ -728,10 +728,13 @@
728 }
729 if( zParent ){
730 @ %z(xhref("class='button'","%R/vpatch?from=%!S&to=%!S",zParent,zUuid))
731 @ Patch</a>
732 }
 
 
 
733 @</div>
734 if( pRe ){
735 @ <p><b>Only differences that match regular expression "%h(zRe)"
736 @ are shown.</b></p>
737 }
738
--- src/info.c
+++ src/info.c
@@ -295,14 +295,13 @@
295
296 /*
297 ** Show the context graph (immediate parents and children) for
298 ** check-in rid.
299 */
300 void showContext(int rid){
301 Blob sql;
302 Stmt q;
 
303 blob_zero(&sql);
304 blob_append(&sql, timeline_query_for_www(), -1);
305 db_multi_exec(
306 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
307 "INSERT INTO ok VALUES(%d);"
@@ -690,10 +689,11 @@
689 style_header("Check-in Information");
690 login_anonymous_available();
691 }
692 db_finalize(&q1);
693 showTags(rid);
694 @ <div class="section">Context</div>
695 showContext(rid);
696 @ <div class="section">Changes</div>
697 @ <div class="sectionmenu">
698 verboseFlag = g.zPath[0]!='c';
699 if( db_get_boolean("show-version-diffs", 0)==0 ){
@@ -728,10 +728,13 @@
728 }
729 if( zParent ){
730 @ %z(xhref("class='button'","%R/vpatch?from=%!S&to=%!S",zParent,zUuid))
731 @ Patch</a>
732 }
733 if( g.perm.Admin ){
734 @ %z(xhref("class='button'","%R/mlink?ci=%!S",zUuid))MLink Table</a>
735 }
736 @</div>
737 if( pRe ){
738 @ <p><b>Only differences that match regular expression "%h(zRe)"
739 @ are shown.</b></p>
740 }
741

Keyboard Shortcuts

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