Fossil SCM

Add the uf= query parameter to timeline. The timeline shows only those checkins that contain the file identified.

drh 2012-11-15 15:14 trunk
Commit eb3cc76d509d680cad5e69e0cbbb7ebf8640050b
--- src/descendants.c
+++ src/descendants.c
@@ -441,5 +441,71 @@
441441
@ function xout(id){
442442
@ }
443443
@ </script>
444444
style_footer();
445445
}
446
+
447
+#if INTERFACE
448
+/* Flag parameters to compute_uses_file() */
449
+#define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
450
+
451
+#endif
452
+
453
+
454
+/*
455
+** Add to table zTab the record ID (rid) of every check-in that contains
456
+** the file fid.
457
+*/
458
+void compute_uses_file(const char *zTab, int fid, int usesFlags){
459
+ Bag seen;
460
+ Bag pending;
461
+ Stmt ins;
462
+ Stmt q;
463
+ int rid;
464
+
465
+ bag_init(&seen);
466
+ bag_init(&pending);
467
+ db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab);
468
+ db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
469
+ while( db_step(&q)==SQLITE_ROW ){
470
+ int mid = db_column_int(&q, 0);
471
+ bag_insert(&pending, mid);
472
+ bag_insert(&seen, mid);
473
+ db_bind_int(&ins, ":rid", mid);
474
+ db_step(&ins);
475
+ db_reset(&ins);
476
+ }
477
+ db_finalize(&q);
478
+
479
+ db_prepare(&q, "SELECT mid FROM mlink WHERE pid=%d", fid);
480
+ while( db_step(&q)==SQLITE_ROW ){
481
+ int mid = db_column_int(&q, 0);
482
+ bag_insert(&seen, mid);
483
+ if( usesFlags & USESFILE_DELETE ){
484
+ db_bind_int(&ins, ":rid", mid);
485
+ db_step(&ins);
486
+ db_reset(&ins);
487
+ }
488
+ }
489
+ db_finalize(&q);
490
+ db_prepare(&q, "SELECT cid FROM plink WHERE pid=:rid");
491
+
492
+ while( (rid = bag_first(&pending))!=0 ){
493
+ bag_remove(&pending, rid);
494
+ db_bind_int(&q, ":rid", rid);
495
+ while( db_step(&q)==SQLITE_ROW ){
496
+ int mid = db_column_int(&q, 0);
497
+ if( bag_find(&seen, mid) ) continue;
498
+ bag_insert(&seen, mid);
499
+ bag_insert(&pending, mid);
500
+ db_bind_int(&ins, ":rid", mid);
501
+ db_step(&ins);
502
+ db_reset(&ins);
503
+ }
504
+ db_reset(&q);
505
+ }
506
+ db_finalize(&q);
507
+ db_finalize(&ins);
508
+ bag_clear(&seen);
509
+ bag_clear(&pending);
510
+}
511
+
446512
--- src/descendants.c
+++ src/descendants.c
@@ -441,5 +441,71 @@
441 @ function xout(id){
442 @ }
443 @ </script>
444 style_footer();
445 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
--- src/descendants.c
+++ src/descendants.c
@@ -441,5 +441,71 @@
441 @ function xout(id){
442 @ }
443 @ </script>
444 style_footer();
445 }
446
447 #if INTERFACE
448 /* Flag parameters to compute_uses_file() */
449 #define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
450
451 #endif
452
453
454 /*
455 ** Add to table zTab the record ID (rid) of every check-in that contains
456 ** the file fid.
457 */
458 void compute_uses_file(const char *zTab, int fid, int usesFlags){
459 Bag seen;
460 Bag pending;
461 Stmt ins;
462 Stmt q;
463 int rid;
464
465 bag_init(&seen);
466 bag_init(&pending);
467 db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab);
468 db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
469 while( db_step(&q)==SQLITE_ROW ){
470 int mid = db_column_int(&q, 0);
471 bag_insert(&pending, mid);
472 bag_insert(&seen, mid);
473 db_bind_int(&ins, ":rid", mid);
474 db_step(&ins);
475 db_reset(&ins);
476 }
477 db_finalize(&q);
478
479 db_prepare(&q, "SELECT mid FROM mlink WHERE pid=%d", fid);
480 while( db_step(&q)==SQLITE_ROW ){
481 int mid = db_column_int(&q, 0);
482 bag_insert(&seen, mid);
483 if( usesFlags & USESFILE_DELETE ){
484 db_bind_int(&ins, ":rid", mid);
485 db_step(&ins);
486 db_reset(&ins);
487 }
488 }
489 db_finalize(&q);
490 db_prepare(&q, "SELECT cid FROM plink WHERE pid=:rid");
491
492 while( (rid = bag_first(&pending))!=0 ){
493 bag_remove(&pending, rid);
494 db_bind_int(&q, ":rid", rid);
495 while( db_step(&q)==SQLITE_ROW ){
496 int mid = db_column_int(&q, 0);
497 if( bag_find(&seen, mid) ) continue;
498 bag_insert(&seen, mid);
499 bag_insert(&pending, mid);
500 db_bind_int(&ins, ":rid", mid);
501 db_step(&ins);
502 db_reset(&ins);
503 }
504 db_reset(&q);
505 }
506 db_finalize(&q);
507 db_finalize(&ins);
508 bag_clear(&seen);
509 bag_clear(&pending);
510 }
511
512
+5 -1
--- src/info.c
+++ src/info.c
@@ -1597,11 +1597,15 @@
15971597
@ <h2>Artifact %s(zUuid):</h2>
15981598
}
15991599
blob_zero(&downloadName);
16001600
objType = object_description(rid, 0, &downloadName);
16011601
style_submenu_element("Download", "Download",
1602
- "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid);
1602
+ "%R/raw/%T?name=%s", blob_str(&downloadName), zUuid);
1603
+ if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
1604
+ style_submenu_element("Checkins Using", "Checkins Using",
1605
+ "%R/timeline?uf=%s&n=200",zUuid);
1606
+ }
16031607
asText = P("txt")!=0;
16041608
zMime = mimetype_from_name(blob_str(&downloadName));
16051609
if( zMime ){
16061610
if( fossil_strcmp(zMime, "text/html")==0 ){
16071611
if( asText ){
16081612
--- src/info.c
+++ src/info.c
@@ -1597,11 +1597,15 @@
1597 @ <h2>Artifact %s(zUuid):</h2>
1598 }
1599 blob_zero(&downloadName);
1600 objType = object_description(rid, 0, &downloadName);
1601 style_submenu_element("Download", "Download",
1602 "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid);
 
 
 
 
1603 asText = P("txt")!=0;
1604 zMime = mimetype_from_name(blob_str(&downloadName));
1605 if( zMime ){
1606 if( fossil_strcmp(zMime, "text/html")==0 ){
1607 if( asText ){
1608
--- src/info.c
+++ src/info.c
@@ -1597,11 +1597,15 @@
1597 @ <h2>Artifact %s(zUuid):</h2>
1598 }
1599 blob_zero(&downloadName);
1600 objType = object_description(rid, 0, &downloadName);
1601 style_submenu_element("Download", "Download",
1602 "%R/raw/%T?name=%s", blob_str(&downloadName), zUuid);
1603 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
1604 style_submenu_element("Checkins Using", "Checkins Using",
1605 "%R/timeline?uf=%s&n=200",zUuid);
1606 }
1607 asText = P("txt")!=0;
1608 zMime = mimetype_from_name(blob_str(&downloadName));
1609 if( zMime ){
1610 if( fossil_strcmp(zMime, "text/html")==0 ){
1611 if( asText ){
1612
--- src/timeline.c
+++ src/timeline.c
@@ -930,10 +930,11 @@
930930
const char *zBefore = P("b"); /* Events before this time */
931931
const char *zCirca = P("c"); /* Events near this time */
932932
const char *zTagName = P("t"); /* Show events with this tag */
933933
const char *zBrName = P("r"); /* Show events related to this tag */
934934
const char *zSearch = P("s"); /* Search string */
935
+ const char *zUses = P("uf"); /* Only show checkins hold this file */
935936
int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
936937
int tagid; /* Tag ID */
937938
int tmFlags; /* Timeline flags */
938939
const char *zThisTag = 0; /* Suppress links to this tag */
939940
const char *zThisUser = 0; /* Suppress links to this user */
@@ -981,10 +982,22 @@
981982
url_add_parameter(&url, "brbg", 0);
982983
}
983984
if( P("ubg")!=0 ){
984985
tmFlags |= TIMELINE_UCOLOR;
985986
url_add_parameter(&url, "ubg", 0);
987
+ }
988
+ if( zUses!=0 ){
989
+ int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
990
+ if( ufid ){
991
+ zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
992
+ url_add_parameter(&url, "uf", zUses);
993
+ db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
994
+ compute_uses_file("usesfile", ufid, 0);
995
+ zType = "ci";
996
+ }else{
997
+ zUses = 0;
998
+ }
986999
}
9871000
9881001
style_header("Timeline");
9891002
login_anonymous_available();
9901003
timeline_temp_table();
@@ -1085,10 +1098,13 @@
10851098
int n;
10861099
const char *zEType = "timeline item";
10871100
char *zDate;
10881101
char *zNEntry = mprintf("%d", nEntry);
10891102
url_add_parameter(&url, "n", zNEntry);
1103
+ if( zUses ){
1104
+ blob_appendf(&sql, " AND event.objid IN usesfile ");
1105
+ }
10901106
if( tagid>0 ){
10911107
blob_appendf(&sql,
10921108
"AND (EXISTS(SELECT 1 FROM tagxref"
10931109
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
10941110
@@ -1220,10 +1236,15 @@
12201236
if( zAfter==0 && zBefore==0 && zCirca==0 ){
12211237
blob_appendf(&desc, "%d most recent %ss", n, zEType);
12221238
}else{
12231239
blob_appendf(&desc, "%d %ss", n, zEType);
12241240
}
1241
+ if( zUses ){
1242
+ blob_appendf(&desc, " using file %z%S</a>",
1243
+ href("%R/artifact/%S",zUses), zUses);
1244
+ tmFlags |= TIMELINE_DISJOINT;
1245
+ }
12251246
if( zUser ){
12261247
blob_appendf(&desc, " by user %h", zUser);
12271248
tmFlags |= TIMELINE_DISJOINT;
12281249
}
12291250
if( zTagName ){
12301251
--- src/timeline.c
+++ src/timeline.c
@@ -930,10 +930,11 @@
930 const char *zBefore = P("b"); /* Events before this time */
931 const char *zCirca = P("c"); /* Events near this time */
932 const char *zTagName = P("t"); /* Show events with this tag */
933 const char *zBrName = P("r"); /* Show events related to this tag */
934 const char *zSearch = P("s"); /* Search string */
 
935 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
936 int tagid; /* Tag ID */
937 int tmFlags; /* Timeline flags */
938 const char *zThisTag = 0; /* Suppress links to this tag */
939 const char *zThisUser = 0; /* Suppress links to this user */
@@ -981,10 +982,22 @@
981 url_add_parameter(&url, "brbg", 0);
982 }
983 if( P("ubg")!=0 ){
984 tmFlags |= TIMELINE_UCOLOR;
985 url_add_parameter(&url, "ubg", 0);
 
 
 
 
 
 
 
 
 
 
 
 
986 }
987
988 style_header("Timeline");
989 login_anonymous_available();
990 timeline_temp_table();
@@ -1085,10 +1098,13 @@
1085 int n;
1086 const char *zEType = "timeline item";
1087 char *zDate;
1088 char *zNEntry = mprintf("%d", nEntry);
1089 url_add_parameter(&url, "n", zNEntry);
 
 
 
1090 if( tagid>0 ){
1091 blob_appendf(&sql,
1092 "AND (EXISTS(SELECT 1 FROM tagxref"
1093 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1094
@@ -1220,10 +1236,15 @@
1220 if( zAfter==0 && zBefore==0 && zCirca==0 ){
1221 blob_appendf(&desc, "%d most recent %ss", n, zEType);
1222 }else{
1223 blob_appendf(&desc, "%d %ss", n, zEType);
1224 }
 
 
 
 
 
1225 if( zUser ){
1226 blob_appendf(&desc, " by user %h", zUser);
1227 tmFlags |= TIMELINE_DISJOINT;
1228 }
1229 if( zTagName ){
1230
--- src/timeline.c
+++ src/timeline.c
@@ -930,10 +930,11 @@
930 const char *zBefore = P("b"); /* Events before this time */
931 const char *zCirca = P("c"); /* Events near this time */
932 const char *zTagName = P("t"); /* Show events with this tag */
933 const char *zBrName = P("r"); /* Show events related to this tag */
934 const char *zSearch = P("s"); /* Search string */
935 const char *zUses = P("uf"); /* Only show checkins hold this file */
936 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
937 int tagid; /* Tag ID */
938 int tmFlags; /* Timeline flags */
939 const char *zThisTag = 0; /* Suppress links to this tag */
940 const char *zThisUser = 0; /* Suppress links to this user */
@@ -981,10 +982,22 @@
982 url_add_parameter(&url, "brbg", 0);
983 }
984 if( P("ubg")!=0 ){
985 tmFlags |= TIMELINE_UCOLOR;
986 url_add_parameter(&url, "ubg", 0);
987 }
988 if( zUses!=0 ){
989 int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
990 if( ufid ){
991 zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
992 url_add_parameter(&url, "uf", zUses);
993 db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
994 compute_uses_file("usesfile", ufid, 0);
995 zType = "ci";
996 }else{
997 zUses = 0;
998 }
999 }
1000
1001 style_header("Timeline");
1002 login_anonymous_available();
1003 timeline_temp_table();
@@ -1085,10 +1098,13 @@
1098 int n;
1099 const char *zEType = "timeline item";
1100 char *zDate;
1101 char *zNEntry = mprintf("%d", nEntry);
1102 url_add_parameter(&url, "n", zNEntry);
1103 if( zUses ){
1104 blob_appendf(&sql, " AND event.objid IN usesfile ");
1105 }
1106 if( tagid>0 ){
1107 blob_appendf(&sql,
1108 "AND (EXISTS(SELECT 1 FROM tagxref"
1109 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1110
@@ -1220,10 +1236,15 @@
1236 if( zAfter==0 && zBefore==0 && zCirca==0 ){
1237 blob_appendf(&desc, "%d most recent %ss", n, zEType);
1238 }else{
1239 blob_appendf(&desc, "%d %ss", n, zEType);
1240 }
1241 if( zUses ){
1242 blob_appendf(&desc, " using file %z%S</a>",
1243 href("%R/artifact/%S",zUses), zUses);
1244 tmFlags |= TIMELINE_DISJOINT;
1245 }
1246 if( zUser ){
1247 blob_appendf(&desc, " by user %h", zUser);
1248 tmFlags |= TIMELINE_DISJOINT;
1249 }
1250 if( zTagName ){
1251

Keyboard Shortcuts

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