Fossil SCM

Enhance the "fileage" webpage so that it shows ages relative to current time rather than relative to the last checkin, so that it shows associated checkin comments, and so that it is styled using CSS.

drh 2014-12-16 14:46 trunk
Commit 31b5dffa768db70cefd4a5c736582d70dcc698ce
2 files changed +60 -37 +19
+60 -37
--- src/browse.c
+++ src/browse.c
@@ -838,15 +838,13 @@
838838
** (e.g. *.c or *.txt).
839839
*/
840840
void fileage_page(void){
841841
int rid;
842842
const char *zName;
843
- char *zBaseTime;
844843
const char *zGlob;
845
- Stmt q;
844
+ Stmt q1, q2;
846845
double baseTime;
847
- int lastMid = -1;
848846
login_check_credentials();
849847
if( !g.perm.Read ){ login_needed(); return; }
850848
zName = P("name");
851849
if( zName==0 ) zName = "tip";
852850
rid = symbolic_name_to_rid(zName, "ci");
@@ -855,44 +853,69 @@
855853
}
856854
style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
857855
style_header("File Ages");
858856
zGlob = P("glob");
859857
compute_fileage(rid,zGlob);
860
- baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
861
- zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
862
- @ <h2>File Ages For Check-in
863
- @ %z(href("%R/info?name=%T",zName))%h(zName)</a></h2>
864
- @
865
- @ <p>The times given are relative to
866
- @ %z(href("%R/timeline?c=%T",zBaseTime))%s(zBaseTime)</a>, which is the
867
- @ check-in time for
868
- @ %z(href("%R/info?name=%T",zName))%h(zName)</a></p>
869
- @
870
- @ <table border=0 cellspacing=0 cellpadding=0>
871
- db_prepare(&q,
872
- "SELECT mtime, (SELECT uuid FROM blob WHERE rid=fid), mid, pathname"
873
- " FROM fileage"
874
- " ORDER BY mtime DESC, mid, pathname"
875
- );
876
- while( db_step(&q)==SQLITE_ROW ){
877
- double age = baseTime - db_column_double(&q, 0);
878
- int mid = db_column_int(&q, 2);
879
- const char *zFUuid = db_column_text(&q, 1);
880
- char *zAge = 0;
881
- if( lastMid!=mid ){
882
- @ <tr><td colspan=3><hr></tr>
883
- lastMid = mid;
884
- zAge = human_readable_age(age);
885
- }
886
- @ <tr>
887
- @ <td>%s(zAge?zAge:"")
888
- @ <td width="25">
889
- @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a>
890
- @ </tr>
858
+ db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
859
+
860
+ baseTime = db_double(0.0, "SELECT julianday('now');");
861
+ @ <h2>Most recent change to files in checkin
862
+ @ %z(href("%R/info?name=%T",zName))%h(zName)</a>
863
+ if( zGlob && zGlob[0] ){
864
+ @ that match "%h(zGlob)"
865
+ }
866
+ @</h2>
867
+ @
868
+ @ <div class='fileage'><table>
869
+ @ <tr><th>Age</th><th>Files</th><th>Checkin</th></tr>
870
+ db_prepare(&q1,
871
+ "SELECT event.mtime, event.objid, blob.uuid,\n"
872
+ " coalesce(event.ecomment,event.comment),\n"
873
+ " coalesce(event.euser,event.user),\n"
874
+ " coalesce((SELECT value FROM tagxref\n"
875
+ " WHERE tagtype>0 AND tagid=%d\n"
876
+ " AND rid=event.objid),'trunk')\n"
877
+ " FROM event, blob\n"
878
+ " WHERE event.objid IN (SELECT mid FROM fileage)\n"
879
+ " AND blob.rid=event.objid\n"
880
+ " ORDER BY event.mtime DESC;",
881
+ TAG_BRANCH
882
+ );
883
+ db_prepare(&q2,
884
+ "SELECT blob.uuid, filename.name\n"
885
+ " FROM fileage, blob, filename\n"
886
+ " WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
887
+ " AND blob.rid=fileage.fid;"
888
+ );
889
+ while( db_step(&q1)==SQLITE_ROW ){
890
+ double age = baseTime - db_column_double(&q1, 0);
891
+ int mid = db_column_int(&q1, 1);
892
+ const char *zUuid = db_column_text(&q1, 2);
893
+ const char *zComment = db_column_text(&q1, 3);
894
+ const char *zUser = db_column_text(&q1, 4);
895
+ const char *zBranch = db_column_text(&q1, 5);
896
+ char *zAge = human_readable_age(age);
897
+ @ <tr><td>%s(zAge)</td>
898
+ @ <td>
899
+ db_bind_int(&q2, ":mid", mid);
900
+ while( db_step(&q2)==SQLITE_ROW ){
901
+ const char *zFUuid = db_column_text(&q2,0);
902
+ const char *zFile = db_column_text(&q2,1);
903
+ @ %z(href("%R/artifact/%s",zFUuid))%h(zFile)</a><br>
904
+ }
905
+ db_reset(&q2);
906
+ @ </td>
907
+ @ <td>
908
+ @ %z(href("%R/info/%s",zUuid))[%S(zUuid)]</a>
909
+ @ %W(zComment) (user:
910
+ @ %z(href("%R/timeline?u=%t&c=%t&nd&n=200",zUser,zUuid))%h(zUser)</a>,
911
+ @ branch:
912
+ @ %z(href("%R/timeline?r=%t&c=%t&nd&n=200",zBranch,zUuid))%h(zBranch)</a>)
913
+ @ </td></tr>
891914
@
892915
fossil_free(zAge);
893916
}
894
- @ <tr><td colspan=3><hr></tr>
895
- @ </table>
896
- db_finalize(&q);
917
+ @ </table></div>
918
+ db_finalize(&q1);
919
+ db_finalize(&q2);
897920
style_footer();
898921
}
899922
--- src/browse.c
+++ src/browse.c
@@ -838,15 +838,13 @@
838 ** (e.g. *.c or *.txt).
839 */
840 void fileage_page(void){
841 int rid;
842 const char *zName;
843 char *zBaseTime;
844 const char *zGlob;
845 Stmt q;
846 double baseTime;
847 int lastMid = -1;
848 login_check_credentials();
849 if( !g.perm.Read ){ login_needed(); return; }
850 zName = P("name");
851 if( zName==0 ) zName = "tip";
852 rid = symbolic_name_to_rid(zName, "ci");
@@ -855,44 +853,69 @@
855 }
856 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
857 style_header("File Ages");
858 zGlob = P("glob");
859 compute_fileage(rid,zGlob);
860 baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
861 zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
862 @ <h2>File Ages For Check-in
863 @ %z(href("%R/info?name=%T",zName))%h(zName)</a></h2>
864 @
865 @ <p>The times given are relative to
866 @ %z(href("%R/timeline?c=%T",zBaseTime))%s(zBaseTime)</a>, which is the
867 @ check-in time for
868 @ %z(href("%R/info?name=%T",zName))%h(zName)</a></p>
869 @
870 @ <table border=0 cellspacing=0 cellpadding=0>
871 db_prepare(&q,
872 "SELECT mtime, (SELECT uuid FROM blob WHERE rid=fid), mid, pathname"
873 " FROM fileage"
874 " ORDER BY mtime DESC, mid, pathname"
875 );
876 while( db_step(&q)==SQLITE_ROW ){
877 double age = baseTime - db_column_double(&q, 0);
878 int mid = db_column_int(&q, 2);
879 const char *zFUuid = db_column_text(&q, 1);
880 char *zAge = 0;
881 if( lastMid!=mid ){
882 @ <tr><td colspan=3><hr></tr>
883 lastMid = mid;
884 zAge = human_readable_age(age);
885 }
886 @ <tr>
887 @ <td>%s(zAge?zAge:"")
888 @ <td width="25">
889 @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a>
890 @ </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
891 @
892 fossil_free(zAge);
893 }
894 @ <tr><td colspan=3><hr></tr>
895 @ </table>
896 db_finalize(&q);
897 style_footer();
898 }
899
--- src/browse.c
+++ src/browse.c
@@ -838,15 +838,13 @@
838 ** (e.g. *.c or *.txt).
839 */
840 void fileage_page(void){
841 int rid;
842 const char *zName;
 
843 const char *zGlob;
844 Stmt q1, q2;
845 double baseTime;
 
846 login_check_credentials();
847 if( !g.perm.Read ){ login_needed(); return; }
848 zName = P("name");
849 if( zName==0 ) zName = "tip";
850 rid = symbolic_name_to_rid(zName, "ci");
@@ -855,44 +853,69 @@
853 }
854 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
855 style_header("File Ages");
856 zGlob = P("glob");
857 compute_fileage(rid,zGlob);
858 db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
859
860 baseTime = db_double(0.0, "SELECT julianday('now');");
861 @ <h2>Most recent change to files in checkin
862 @ %z(href("%R/info?name=%T",zName))%h(zName)</a>
863 if( zGlob && zGlob[0] ){
864 @ that match "%h(zGlob)"
865 }
866 @</h2>
867 @
868 @ <div class='fileage'><table>
869 @ <tr><th>Age</th><th>Files</th><th>Checkin</th></tr>
870 db_prepare(&q1,
871 "SELECT event.mtime, event.objid, blob.uuid,\n"
872 " coalesce(event.ecomment,event.comment),\n"
873 " coalesce(event.euser,event.user),\n"
874 " coalesce((SELECT value FROM tagxref\n"
875 " WHERE tagtype>0 AND tagid=%d\n"
876 " AND rid=event.objid),'trunk')\n"
877 " FROM event, blob\n"
878 " WHERE event.objid IN (SELECT mid FROM fileage)\n"
879 " AND blob.rid=event.objid\n"
880 " ORDER BY event.mtime DESC;",
881 TAG_BRANCH
882 );
883 db_prepare(&q2,
884 "SELECT blob.uuid, filename.name\n"
885 " FROM fileage, blob, filename\n"
886 " WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
887 " AND blob.rid=fileage.fid;"
888 );
889 while( db_step(&q1)==SQLITE_ROW ){
890 double age = baseTime - db_column_double(&q1, 0);
891 int mid = db_column_int(&q1, 1);
892 const char *zUuid = db_column_text(&q1, 2);
893 const char *zComment = db_column_text(&q1, 3);
894 const char *zUser = db_column_text(&q1, 4);
895 const char *zBranch = db_column_text(&q1, 5);
896 char *zAge = human_readable_age(age);
897 @ <tr><td>%s(zAge)</td>
898 @ <td>
899 db_bind_int(&q2, ":mid", mid);
900 while( db_step(&q2)==SQLITE_ROW ){
901 const char *zFUuid = db_column_text(&q2,0);
902 const char *zFile = db_column_text(&q2,1);
903 @ %z(href("%R/artifact/%s",zFUuid))%h(zFile)</a><br>
904 }
905 db_reset(&q2);
906 @ </td>
907 @ <td>
908 @ %z(href("%R/info/%s",zUuid))[%S(zUuid)]</a>
909 @ %W(zComment) (user:
910 @ %z(href("%R/timeline?u=%t&c=%t&nd&n=200",zUser,zUuid))%h(zUser)</a>,
911 @ branch:
912 @ %z(href("%R/timeline?r=%t&c=%t&nd&n=200",zBranch,zUuid))%h(zBranch)</a>)
913 @ </td></tr>
914 @
915 fossil_free(zAge);
916 }
917 @ </table></div>
918 db_finalize(&q1);
919 db_finalize(&q2);
920 style_footer();
921 }
922
+19
--- src/style.c
+++ src/style.c
@@ -1219,10 +1219,29 @@
12191219
"Class for the /admin_log table",
12201220
@ text-align: left;
12211221
@ vertical-align: top;
12221222
@ white-space: nowrap;
12231223
},
1224
+ { ".fileage table",
1225
+ "The fileage table",
1226
+ @ border-spacing: 0;
1227
+ },
1228
+ { ".fileage td",
1229
+ "fileage table cells",
1230
+ @ vertical-align: top;
1231
+ @ text-align: left;
1232
+ @ border-top: 1px solid black;
1233
+ },
1234
+ { ".fileage td:first-child",
1235
+ "fileage first column (the age)",
1236
+ @ white-space: nowrap;
1237
+ },
1238
+ { ".fileage td:first-child + td",
1239
+ "fileage second column (the filename)",
1240
+ @ padding-left: 1em;
1241
+ @ padding-right: 1em;
1242
+ },
12241243
{ 0,
12251244
0,
12261245
0
12271246
}
12281247
};
12291248
--- src/style.c
+++ src/style.c
@@ -1219,10 +1219,29 @@
1219 "Class for the /admin_log table",
1220 @ text-align: left;
1221 @ vertical-align: top;
1222 @ white-space: nowrap;
1223 },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1224 { 0,
1225 0,
1226 0
1227 }
1228 };
1229
--- src/style.c
+++ src/style.c
@@ -1219,10 +1219,29 @@
1219 "Class for the /admin_log table",
1220 @ text-align: left;
1221 @ vertical-align: top;
1222 @ white-space: nowrap;
1223 },
1224 { ".fileage table",
1225 "The fileage table",
1226 @ border-spacing: 0;
1227 },
1228 { ".fileage td",
1229 "fileage table cells",
1230 @ vertical-align: top;
1231 @ text-align: left;
1232 @ border-top: 1px solid black;
1233 },
1234 { ".fileage td:first-child",
1235 "fileage first column (the age)",
1236 @ white-space: nowrap;
1237 },
1238 { ".fileage td:first-child + td",
1239 "fileage second column (the filename)",
1240 @ padding-left: 1em;
1241 @ padding-right: 1em;
1242 },
1243 { 0,
1244 0,
1245 0
1246 }
1247 };
1248

Keyboard Shortcuts

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