Fossil SCM
Enhance the artifact description logic to try to determine the source of phantom artifacts.
Commit
7fd31f69571cae5ab1b497ac05676a340b443142541e70823c320a526046d19c
Parent
28b92ca631f4c1c…
1 file changed
+41
-8
+41
-8
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -964,12 +964,13 @@ | ||
| 964 | 964 | @ ctime DATETIME, -- Time of creation |
| 965 | 965 | @ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts |
| 966 | 966 | @ type TEXT, -- file, checkin, wiki, ticket, etc. |
| 967 | 967 | @ rcvid INT, -- When the artifact was received |
| 968 | 968 | @ summary TEXT, -- Summary comment for the object |
| 969 | -@ detail TEXT -- File name, check-in comment, etc | |
| 969 | +@ ref TEXT -- hash of an object to link against | |
| 970 | 970 | @ ); |
| 971 | +@ CREATE INDEX desctype ON description(summary) WHERE summary='unknown'; | |
| 971 | 972 | ; |
| 972 | 973 | |
| 973 | 974 | /* |
| 974 | 975 | ** Create the description table if it does not already exists. |
| 975 | 976 | ** Populate fields of this table with descriptions for all artifacts |
| @@ -1101,24 +1102,50 @@ | ||
| 1101 | 1102 | " AND rootblob.rid=forumpost.froot", |
| 1102 | 1103 | zWhere /*safe-for-%s*/ |
| 1103 | 1104 | ); |
| 1104 | 1105 | } |
| 1105 | 1106 | |
| 1106 | - /* Everything else */ | |
| 1107 | + /* Mark all other artifacts as "unknown" for now */ | |
| 1107 | 1108 | db_multi_exec( |
| 1108 | 1109 | "INSERT OR IGNORE INTO description(rid,uuid,rcvid,type,summary)\n" |
| 1109 | - "SELECT blob.rid, blob.uuid,blob.rcvid," | |
| 1110 | - " CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n" | |
| 1110 | + "SELECT blob.rid, blob.uuid,blob.rcvid,\n" | |
| 1111 | + " CASE WHEN EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)\n" | |
| 1112 | + " THEN 'phantom' ELSE '' END,\n" | |
| 1111 | 1113 | " 'unknown'\n" |
| 1112 | - " FROM blob WHERE (blob.rid %s);", | |
| 1114 | + " FROM blob\n" | |
| 1115 | + " WHERE (blob.rid %s)\n" | |
| 1116 | + " AND (blob.rid NOT IN (SELECT rid FROM description));", | |
| 1113 | 1117 | zWhere /*safe-for-%s*/ |
| 1114 | 1118 | ); |
| 1115 | 1119 | |
| 1116 | 1120 | /* Mark private elements */ |
| 1117 | 1121 | db_multi_exec( |
| 1118 | 1122 | "UPDATE description SET isPrivate=1 WHERE rid IN private" |
| 1119 | 1123 | ); |
| 1124 | + | |
| 1125 | + /* Try to figure out the origin of unknown artifacts */ | |
| 1126 | + db_multi_exec( | |
| 1127 | + "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 1128 | + " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 1129 | + " CASE WHEN plink.isprim THEN '' ELSE 'merge ' END ||\n" | |
| 1130 | + " 'parent of check-in', blob.uuid\n" | |
| 1131 | + " FROM description, plink, blob\n" | |
| 1132 | + " WHERE description.summary='unknown'\n" | |
| 1133 | + " AND plink.pid=description.rid\n" | |
| 1134 | + " AND blob.rid=plink.cid;" | |
| 1135 | + ); | |
| 1136 | + db_multi_exec( | |
| 1137 | + "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 1138 | + " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 1139 | + " 'check-in referenced by \"'||tag.tagname ||'\" tag',\n" | |
| 1140 | + " blob.uuid\n" | |
| 1141 | + " FROM description, tagxref, tag, blob\n" | |
| 1142 | + " WHERE description.summary='unknown'\n" | |
| 1143 | + " AND tagxref.origid=description.rid\n" | |
| 1144 | + " AND tag.tagid=tagxref.tagid\n" | |
| 1145 | + " AND blob.rid=tagxref.srcid;" | |
| 1146 | + ); | |
| 1120 | 1147 | } |
| 1121 | 1148 | |
| 1122 | 1149 | /* |
| 1123 | 1150 | ** Print the content of the description table on stdout. |
| 1124 | 1151 | ** |
| @@ -1241,11 +1268,11 @@ | ||
| 1241 | 1268 | zRange = mprintf("BETWEEN %d AND %d", s, s+n-1); |
| 1242 | 1269 | } |
| 1243 | 1270 | describe_artifacts(zRange); |
| 1244 | 1271 | fossil_free(zRange); |
| 1245 | 1272 | db_prepare(&q, |
| 1246 | - "SELECT rid, uuid, summary, isPrivate, type='phantom', rcvid" | |
| 1273 | + "SELECT rid, uuid, summary, isPrivate, type='phantom', rcvid, ref" | |
| 1247 | 1274 | " FROM description ORDER BY rid" |
| 1248 | 1275 | ); |
| 1249 | 1276 | if( skin_detail_boolean("white-foreground") ){ |
| 1250 | 1277 | zSha1Bg = "#714417"; |
| 1251 | 1278 | zSha3Bg = "#177117"; |
| @@ -1253,20 +1280,21 @@ | ||
| 1253 | 1280 | zSha1Bg = "#ebffb0"; |
| 1254 | 1281 | zSha3Bg = "#b0ffb0"; |
| 1255 | 1282 | } |
| 1256 | 1283 | @ <table cellpadding="2" cellspacing="0" border="1"> |
| 1257 | 1284 | if( g.perm.Admin ){ |
| 1258 | - @ <tr><th>RID<th>Hash<th>Rcvid<th>Description<th>Remarks | |
| 1285 | + @ <tr><th>RID<th>Hash<th>Rcvid<th>Description<th>Ref<th>Remarks | |
| 1259 | 1286 | }else{ |
| 1260 | - @ <tr><th>RID<th>Hash<th>Description<th>Remarks | |
| 1287 | + @ <tr><th>RID<th>Hash<th>Description<th>Ref<th>Remarks | |
| 1261 | 1288 | } |
| 1262 | 1289 | while( db_step(&q)==SQLITE_ROW ){ |
| 1263 | 1290 | int rid = db_column_int(&q,0); |
| 1264 | 1291 | const char *zUuid = db_column_text(&q, 1); |
| 1265 | 1292 | const char *zDesc = db_column_text(&q, 2); |
| 1266 | 1293 | int isPriv = db_column_int(&q,3); |
| 1267 | 1294 | int isPhantom = db_column_int(&q,4); |
| 1295 | + const char *zRef = db_column_text(&q,6); | |
| 1268 | 1296 | if( isPhantom && !g.perm.Admin ){ |
| 1269 | 1297 | /* Do not show phantom artifacts to non-admin users */ |
| 1270 | 1298 | continue; |
| 1271 | 1299 | } |
| 1272 | 1300 | if( isPriv && !g.perm.Private && !g.perm.Admin ){ |
| @@ -1287,10 +1315,15 @@ | ||
| 1287 | 1315 | }else{ |
| 1288 | 1316 | @ <td><a href='%R/rcvfrom?rcvid=%d(rcvid)'>%d(rcvid)</a> |
| 1289 | 1317 | } |
| 1290 | 1318 | } |
| 1291 | 1319 | @ <td align="left">%h(zDesc)</td> |
| 1320 | + if( zRef && zRef[0] ){ | |
| 1321 | + @ <td>%z(href("%R/info/%!S",zRef))%S(zRef)</a> | |
| 1322 | + }else{ | |
| 1323 | + @ <td> | |
| 1324 | + } | |
| 1292 | 1325 | if( isPriv || isPhantom ){ |
| 1293 | 1326 | if( isPriv==0 ){ |
| 1294 | 1327 | @ <td>phantom</td> |
| 1295 | 1328 | }else if( isPhantom==0 ){ |
| 1296 | 1329 | @ <td>private</td> |
| 1297 | 1330 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -964,12 +964,13 @@ | |
| 964 | @ ctime DATETIME, -- Time of creation |
| 965 | @ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts |
| 966 | @ type TEXT, -- file, checkin, wiki, ticket, etc. |
| 967 | @ rcvid INT, -- When the artifact was received |
| 968 | @ summary TEXT, -- Summary comment for the object |
| 969 | @ detail TEXT -- File name, check-in comment, etc |
| 970 | @ ); |
| 971 | ; |
| 972 | |
| 973 | /* |
| 974 | ** Create the description table if it does not already exists. |
| 975 | ** Populate fields of this table with descriptions for all artifacts |
| @@ -1101,24 +1102,50 @@ | |
| 1101 | " AND rootblob.rid=forumpost.froot", |
| 1102 | zWhere /*safe-for-%s*/ |
| 1103 | ); |
| 1104 | } |
| 1105 | |
| 1106 | /* Everything else */ |
| 1107 | db_multi_exec( |
| 1108 | "INSERT OR IGNORE INTO description(rid,uuid,rcvid,type,summary)\n" |
| 1109 | "SELECT blob.rid, blob.uuid,blob.rcvid," |
| 1110 | " CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n" |
| 1111 | " 'unknown'\n" |
| 1112 | " FROM blob WHERE (blob.rid %s);", |
| 1113 | zWhere /*safe-for-%s*/ |
| 1114 | ); |
| 1115 | |
| 1116 | /* Mark private elements */ |
| 1117 | db_multi_exec( |
| 1118 | "UPDATE description SET isPrivate=1 WHERE rid IN private" |
| 1119 | ); |
| 1120 | } |
| 1121 | |
| 1122 | /* |
| 1123 | ** Print the content of the description table on stdout. |
| 1124 | ** |
| @@ -1241,11 +1268,11 @@ | |
| 1241 | zRange = mprintf("BETWEEN %d AND %d", s, s+n-1); |
| 1242 | } |
| 1243 | describe_artifacts(zRange); |
| 1244 | fossil_free(zRange); |
| 1245 | db_prepare(&q, |
| 1246 | "SELECT rid, uuid, summary, isPrivate, type='phantom', rcvid" |
| 1247 | " FROM description ORDER BY rid" |
| 1248 | ); |
| 1249 | if( skin_detail_boolean("white-foreground") ){ |
| 1250 | zSha1Bg = "#714417"; |
| 1251 | zSha3Bg = "#177117"; |
| @@ -1253,20 +1280,21 @@ | |
| 1253 | zSha1Bg = "#ebffb0"; |
| 1254 | zSha3Bg = "#b0ffb0"; |
| 1255 | } |
| 1256 | @ <table cellpadding="2" cellspacing="0" border="1"> |
| 1257 | if( g.perm.Admin ){ |
| 1258 | @ <tr><th>RID<th>Hash<th>Rcvid<th>Description<th>Remarks |
| 1259 | }else{ |
| 1260 | @ <tr><th>RID<th>Hash<th>Description<th>Remarks |
| 1261 | } |
| 1262 | while( db_step(&q)==SQLITE_ROW ){ |
| 1263 | int rid = db_column_int(&q,0); |
| 1264 | const char *zUuid = db_column_text(&q, 1); |
| 1265 | const char *zDesc = db_column_text(&q, 2); |
| 1266 | int isPriv = db_column_int(&q,3); |
| 1267 | int isPhantom = db_column_int(&q,4); |
| 1268 | if( isPhantom && !g.perm.Admin ){ |
| 1269 | /* Do not show phantom artifacts to non-admin users */ |
| 1270 | continue; |
| 1271 | } |
| 1272 | if( isPriv && !g.perm.Private && !g.perm.Admin ){ |
| @@ -1287,10 +1315,15 @@ | |
| 1287 | }else{ |
| 1288 | @ <td><a href='%R/rcvfrom?rcvid=%d(rcvid)'>%d(rcvid)</a> |
| 1289 | } |
| 1290 | } |
| 1291 | @ <td align="left">%h(zDesc)</td> |
| 1292 | if( isPriv || isPhantom ){ |
| 1293 | if( isPriv==0 ){ |
| 1294 | @ <td>phantom</td> |
| 1295 | }else if( isPhantom==0 ){ |
| 1296 | @ <td>private</td> |
| 1297 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -964,12 +964,13 @@ | |
| 964 | @ ctime DATETIME, -- Time of creation |
| 965 | @ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts |
| 966 | @ type TEXT, -- file, checkin, wiki, ticket, etc. |
| 967 | @ rcvid INT, -- When the artifact was received |
| 968 | @ summary TEXT, -- Summary comment for the object |
| 969 | @ ref TEXT -- hash of an object to link against |
| 970 | @ ); |
| 971 | @ CREATE INDEX desctype ON description(summary) WHERE summary='unknown'; |
| 972 | ; |
| 973 | |
| 974 | /* |
| 975 | ** Create the description table if it does not already exists. |
| 976 | ** Populate fields of this table with descriptions for all artifacts |
| @@ -1101,24 +1102,50 @@ | |
| 1102 | " AND rootblob.rid=forumpost.froot", |
| 1103 | zWhere /*safe-for-%s*/ |
| 1104 | ); |
| 1105 | } |
| 1106 | |
| 1107 | /* Mark all other artifacts as "unknown" for now */ |
| 1108 | db_multi_exec( |
| 1109 | "INSERT OR IGNORE INTO description(rid,uuid,rcvid,type,summary)\n" |
| 1110 | "SELECT blob.rid, blob.uuid,blob.rcvid,\n" |
| 1111 | " CASE WHEN EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)\n" |
| 1112 | " THEN 'phantom' ELSE '' END,\n" |
| 1113 | " 'unknown'\n" |
| 1114 | " FROM blob\n" |
| 1115 | " WHERE (blob.rid %s)\n" |
| 1116 | " AND (blob.rid NOT IN (SELECT rid FROM description));", |
| 1117 | zWhere /*safe-for-%s*/ |
| 1118 | ); |
| 1119 | |
| 1120 | /* Mark private elements */ |
| 1121 | db_multi_exec( |
| 1122 | "UPDATE description SET isPrivate=1 WHERE rid IN private" |
| 1123 | ); |
| 1124 | |
| 1125 | /* Try to figure out the origin of unknown artifacts */ |
| 1126 | db_multi_exec( |
| 1127 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 1128 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 1129 | " CASE WHEN plink.isprim THEN '' ELSE 'merge ' END ||\n" |
| 1130 | " 'parent of check-in', blob.uuid\n" |
| 1131 | " FROM description, plink, blob\n" |
| 1132 | " WHERE description.summary='unknown'\n" |
| 1133 | " AND plink.pid=description.rid\n" |
| 1134 | " AND blob.rid=plink.cid;" |
| 1135 | ); |
| 1136 | db_multi_exec( |
| 1137 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 1138 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 1139 | " 'check-in referenced by \"'||tag.tagname ||'\" tag',\n" |
| 1140 | " blob.uuid\n" |
| 1141 | " FROM description, tagxref, tag, blob\n" |
| 1142 | " WHERE description.summary='unknown'\n" |
| 1143 | " AND tagxref.origid=description.rid\n" |
| 1144 | " AND tag.tagid=tagxref.tagid\n" |
| 1145 | " AND blob.rid=tagxref.srcid;" |
| 1146 | ); |
| 1147 | } |
| 1148 | |
| 1149 | /* |
| 1150 | ** Print the content of the description table on stdout. |
| 1151 | ** |
| @@ -1241,11 +1268,11 @@ | |
| 1268 | zRange = mprintf("BETWEEN %d AND %d", s, s+n-1); |
| 1269 | } |
| 1270 | describe_artifacts(zRange); |
| 1271 | fossil_free(zRange); |
| 1272 | db_prepare(&q, |
| 1273 | "SELECT rid, uuid, summary, isPrivate, type='phantom', rcvid, ref" |
| 1274 | " FROM description ORDER BY rid" |
| 1275 | ); |
| 1276 | if( skin_detail_boolean("white-foreground") ){ |
| 1277 | zSha1Bg = "#714417"; |
| 1278 | zSha3Bg = "#177117"; |
| @@ -1253,20 +1280,21 @@ | |
| 1280 | zSha1Bg = "#ebffb0"; |
| 1281 | zSha3Bg = "#b0ffb0"; |
| 1282 | } |
| 1283 | @ <table cellpadding="2" cellspacing="0" border="1"> |
| 1284 | if( g.perm.Admin ){ |
| 1285 | @ <tr><th>RID<th>Hash<th>Rcvid<th>Description<th>Ref<th>Remarks |
| 1286 | }else{ |
| 1287 | @ <tr><th>RID<th>Hash<th>Description<th>Ref<th>Remarks |
| 1288 | } |
| 1289 | while( db_step(&q)==SQLITE_ROW ){ |
| 1290 | int rid = db_column_int(&q,0); |
| 1291 | const char *zUuid = db_column_text(&q, 1); |
| 1292 | const char *zDesc = db_column_text(&q, 2); |
| 1293 | int isPriv = db_column_int(&q,3); |
| 1294 | int isPhantom = db_column_int(&q,4); |
| 1295 | const char *zRef = db_column_text(&q,6); |
| 1296 | if( isPhantom && !g.perm.Admin ){ |
| 1297 | /* Do not show phantom artifacts to non-admin users */ |
| 1298 | continue; |
| 1299 | } |
| 1300 | if( isPriv && !g.perm.Private && !g.perm.Admin ){ |
| @@ -1287,10 +1315,15 @@ | |
| 1315 | }else{ |
| 1316 | @ <td><a href='%R/rcvfrom?rcvid=%d(rcvid)'>%d(rcvid)</a> |
| 1317 | } |
| 1318 | } |
| 1319 | @ <td align="left">%h(zDesc)</td> |
| 1320 | if( zRef && zRef[0] ){ |
| 1321 | @ <td>%z(href("%R/info/%!S",zRef))%S(zRef)</a> |
| 1322 | }else{ |
| 1323 | @ <td> |
| 1324 | } |
| 1325 | if( isPriv || isPhantom ){ |
| 1326 | if( isPriv==0 ){ |
| 1327 | @ <td>phantom</td> |
| 1328 | }else if( isPhantom==0 ){ |
| 1329 | @ <td>private</td> |
| 1330 |