| | @@ -1143,10 +1143,40 @@ |
| 1143 | 1143 | case CFTYPE_CONTROL: zType = "Tag-change"; break; |
| 1144 | 1144 | default: break; |
| 1145 | 1145 | } |
| 1146 | 1146 | return zType; |
| 1147 | 1147 | } |
| 1148 | + |
| 1149 | +/* |
| 1150 | +** This is the output routine for whatis_rid(). If pOut is NULL |
| 1151 | +** then write zKey and zValue on fossil_print(). But if pOut is |
| 1152 | +** not NULL, append the key and value as a term of a JSON object. |
| 1153 | +*/ |
| 1154 | +static void whatis_line( |
| 1155 | + sqlite3_str *pOut, |
| 1156 | + const char *zKey, |
| 1157 | + const char *zValue, |
| 1158 | + ... |
| 1159 | +){ |
| 1160 | + char *zArg; |
| 1161 | + va_list ap; |
| 1162 | + va_start(ap, zValue); |
| 1163 | + zArg = sqlite3_vmprintf(zValue,ap); |
| 1164 | + va_end(ap); |
| 1165 | + if( pOut ){ |
| 1166 | + int n = sqlite3_str_length(pOut); |
| 1167 | + if( n>1 && sqlite3_str_value(pOut)[n-1]!='{' ){ |
| 1168 | + sqlite3_str_append(pOut, ",", 1); |
| 1169 | + } |
| 1170 | + sqlite3_str_appendf(pOut, "%J:%J", zKey, zArg); |
| 1171 | + }else{ |
| 1172 | + int n = 11 - (int)strlen(zKey); |
| 1173 | + if( n<=0 ) n = 0; |
| 1174 | + fossil_print("%s:%*s%s\n",zKey,n,"",zArg); |
| 1175 | + } |
| 1176 | + sqlite3_free(zArg); |
| 1177 | +} |
| 1148 | 1178 | |
| 1149 | 1179 | /* |
| 1150 | 1180 | ** Flag values for whatis_rid(). |
| 1151 | 1181 | */ |
| 1152 | 1182 | #if INTERFACE |
| | @@ -1153,18 +1183,25 @@ |
| 1153 | 1183 | #define WHATIS_VERBOSE 0x01 /* Extra output */ |
| 1154 | 1184 | #define WHATIS_BRIEF 0x02 /* Omit unnecessary output */ |
| 1155 | 1185 | #define WHATIS_REPO 0x04 /* Show repository name */ |
| 1156 | 1186 | #define WHATIS_OMIT_UNK 0x08 /* Do not show "unknown" lines */ |
| 1157 | 1187 | #define WHATIS_HASHONLY 0x10 /* Show only the hash */ |
| 1188 | +#define WHATIS_JSON 0x20 /* Render as JSON */ |
| 1158 | 1189 | #endif |
| 1159 | 1190 | |
| 1160 | 1191 | /* |
| 1161 | | -** Generate a description of artifact "rid" |
| 1192 | +** Generate a description of artifact "rid". |
| 1193 | +** |
| 1194 | +** Send results to stdout using fossil_print() if pOut==0 or if |
| 1195 | +** WHATIS_HASHONLY is set. But without WHATIS_HASHONLY and if |
| 1196 | +** pOut!=0, then write a JSON description of the object into pOut. |
| 1162 | 1197 | */ |
| 1163 | | -void whatis_rid(int rid, int flags){ |
| 1198 | +void whatis_rid(int rid, int flags, sqlite3_str *pOut){ |
| 1164 | 1199 | Stmt q; |
| 1165 | 1200 | int cnt; |
| 1201 | + |
| 1202 | + if( pOut ) sqlite3_str_append(pOut, "{", 1); |
| 1166 | 1203 | |
| 1167 | 1204 | /* Basic information about the object. */ |
| 1168 | 1205 | db_prepare(&q, |
| 1169 | 1206 | "SELECT uuid, size, datetime(mtime,toLocal()), ipaddr" |
| 1170 | 1207 | " FROM blob, rcvfrom" |
| | @@ -1173,18 +1210,18 @@ |
| 1173 | 1210 | rid); |
| 1174 | 1211 | if( db_step(&q)==SQLITE_ROW ){ |
| 1175 | 1212 | if( flags & WHATIS_HASHONLY ){ |
| 1176 | 1213 | fossil_print("%s\n", db_column_text(&q,0)); |
| 1177 | 1214 | }else if( flags & WHATIS_VERBOSE ){ |
| 1178 | | - fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); |
| 1179 | | - fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 1180 | | - fossil_print("received: %s from %s\n", |
| 1215 | + whatis_line(pOut, "artifact", "%s (%d)", db_column_text(&q,0), rid); |
| 1216 | + whatis_line(pOut, "size", "%d bytes", db_column_int(&q,1)); |
| 1217 | + whatis_line(pOut, "received", "%s from %s", |
| 1181 | 1218 | db_column_text(&q, 2), |
| 1182 | 1219 | db_column_text(&q, 3)); |
| 1183 | 1220 | }else{ |
| 1184 | | - fossil_print("artifact: %s\n", db_column_text(&q,0)); |
| 1185 | | - fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 1221 | + whatis_line(pOut, "artifact","%s", db_column_text(&q,0)); |
| 1222 | + whatis_line(pOut, "size", "%d bytes", db_column_int(&q,1)); |
| 1186 | 1223 | } |
| 1187 | 1224 | } |
| 1188 | 1225 | db_finalize(&q); |
| 1189 | 1226 | if( flags & WHATIS_HASHONLY ) return; |
| 1190 | 1227 | |
| | @@ -1198,14 +1235,27 @@ |
| 1198 | 1235 | " ORDER BY 1", |
| 1199 | 1236 | rid |
| 1200 | 1237 | ); |
| 1201 | 1238 | cnt = 0; |
| 1202 | 1239 | while( db_step(&q)==SQLITE_ROW ){ |
| 1203 | | - const char *zPrefix = cnt++ ? ", " : "tags: "; |
| 1204 | | - fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 1240 | + const char *zTag = (const char*)db_column_text(&q,0); |
| 1241 | + if( pOut ){ |
| 1242 | + const char *zSep = cnt==0 ? ",tags:[" : ","; |
| 1243 | + sqlite3_str_appendf(pOut, "%s%J", zSep, zTag); |
| 1244 | + }else{ |
| 1245 | + const char *zPrefix = cnt++ ? ", " : "tags: "; |
| 1246 | + fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 1247 | + } |
| 1248 | + cnt++; |
| 1205 | 1249 | } |
| 1206 | | - if( cnt ) fossil_print("\n"); |
| 1250 | + if( cnt ){ |
| 1251 | + if( pOut ){ |
| 1252 | + sqlite3_str_append(pOut, "]", 1); |
| 1253 | + }else{ |
| 1254 | + fossil_print("\n"); |
| 1255 | + } |
| 1256 | + } |
| 1207 | 1257 | db_finalize(&q); |
| 1208 | 1258 | |
| 1209 | 1259 | /* Report any HIDDEN, PRIVATE, CLUSTER, or CLOSED tags on this artifact */ |
| 1210 | 1260 | db_prepare(&q, |
| 1211 | 1261 | "SELECT tagname" |
| | @@ -1215,14 +1265,27 @@ |
| 1215 | 1265 | " ORDER BY 1", |
| 1216 | 1266 | rid |
| 1217 | 1267 | ); |
| 1218 | 1268 | cnt = 0; |
| 1219 | 1269 | while( db_step(&q)==SQLITE_ROW ){ |
| 1220 | | - const char *zPrefix = cnt++ ? ", " : "raw-tags: "; |
| 1221 | | - fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 1270 | + const char *zTag = (const char*)db_column_text(&q,0); |
| 1271 | + if( pOut ){ |
| 1272 | + const char *zSep = cnt==0 ? ",\"raw-tags\":[" : ","; |
| 1273 | + sqlite3_str_appendf(pOut, "%s%J", zSep, zTag); |
| 1274 | + }else{ |
| 1275 | + const char *zPrefix = cnt++ ? ", " : "raw-tags: "; |
| 1276 | + fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 1277 | + } |
| 1278 | + cnt++; |
| 1222 | 1279 | } |
| 1223 | | - if( cnt ) fossil_print("\n"); |
| 1280 | + if( cnt ){ |
| 1281 | + if( pOut ){ |
| 1282 | + sqlite3_str_append(pOut, "]", 1); |
| 1283 | + }else{ |
| 1284 | + fossil_print("\n"); |
| 1285 | + } |
| 1286 | + } |
| 1224 | 1287 | db_finalize(&q); |
| 1225 | 1288 | |
| 1226 | 1289 | /* Check for entries on the timeline that reference this object */ |
| 1227 | 1290 | db_prepare(&q, |
| 1228 | 1291 | "SELECT" |
| | @@ -1244,17 +1307,21 @@ |
| 1244 | 1307 | case 'f': zType = "Forum-post"; break; |
| 1245 | 1308 | case 't': zType = "Ticket-change"; break; |
| 1246 | 1309 | case 'g': zType = "Tag-change"; break; |
| 1247 | 1310 | default: zType = "Unknown"; break; |
| 1248 | 1311 | } |
| 1249 | | - fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), |
| 1312 | + whatis_line(pOut, "type", "%s by %s on %s", zType, db_column_text(&q,2), |
| 1250 | 1313 | db_column_text(&q, 1)); |
| 1251 | 1314 | if( eType=='t' && db_column_type(&q,4)==SQLITE_TEXT ){ |
| 1252 | | - fossil_print("ticket-id: %s\n", db_column_text(&q,4)); |
| 1315 | + whatis_line(pOut, "ticket-id", "%s", db_column_text(&q,4)); |
| 1253 | 1316 | } |
| 1254 | | - fossil_print("comment: "); |
| 1255 | | - comment_print(db_column_text(&q,3), 0, 12, -1, get_comment_format()); |
| 1317 | + if( pOut ){ |
| 1318 | + sqlite3_str_appendf(pOut, ",\"comment\":%J", db_column_text(&q,3)); |
| 1319 | + }else{ |
| 1320 | + fossil_print("comment: "); |
| 1321 | + comment_print(db_column_text(&q,3), 0, 12, -1, get_comment_format()); |
| 1322 | + } |
| 1256 | 1323 | cnt++; |
| 1257 | 1324 | } |
| 1258 | 1325 | db_finalize(&q); |
| 1259 | 1326 | |
| 1260 | 1327 | /* Check to see if this object is used as a file in a check-in */ |
| | @@ -1271,20 +1338,25 @@ |
| 1271 | 1338 | " ORDER BY event.mtime %s /*sort*/", |
| 1272 | 1339 | TAG_BRANCH, rid, |
| 1273 | 1340 | (flags & WHATIS_BRIEF) ? "LIMIT 1" : "DESC"); |
| 1274 | 1341 | while( db_step(&q)==SQLITE_ROW ){ |
| 1275 | 1342 | if( flags & WHATIS_BRIEF ){ |
| 1276 | | - fossil_print("mtime: %s\n", db_column_text(&q,2)); |
| 1277 | | - } |
| 1278 | | - fossil_print("file: %s\n", db_column_text(&q,0)); |
| 1279 | | - fossil_print(" part of [%S] on branch %s by %s on %s\n", |
| 1280 | | - db_column_text(&q, 1), |
| 1281 | | - db_column_text(&q, 5), |
| 1282 | | - db_column_text(&q, 3), |
| 1283 | | - db_column_text(&q, 2)); |
| 1284 | | - fossil_print(" "); |
| 1285 | | - comment_print(db_column_text(&q,4), 0, 12, -1, get_comment_format()); |
| 1343 | + whatis_line(pOut, "mtime","%s", db_column_text(&q,2)); |
| 1344 | + } |
| 1345 | + if( pOut ){ |
| 1346 | + whatis_line(pOut,"file","%s", db_column_text(&q,0)); |
| 1347 | + whatis_line(pOut,"part-of","%s", db_column_text(&q,1)); |
| 1348 | + }else{ |
| 1349 | + fossil_print("file: %s\n", db_column_text(&q,0)); |
| 1350 | + fossil_print(" part of [%S] on branch %s by %s on %s\n", |
| 1351 | + db_column_text(&q, 1), |
| 1352 | + db_column_text(&q, 5), |
| 1353 | + db_column_text(&q, 3), |
| 1354 | + db_column_text(&q, 2)); |
| 1355 | + fossil_print(" "); |
| 1356 | + comment_print(db_column_text(&q,4), 0, 12, -1, get_comment_format()); |
| 1357 | + } |
| 1286 | 1358 | cnt++; |
| 1287 | 1359 | } |
| 1288 | 1360 | db_finalize(&q); |
| 1289 | 1361 | |
| 1290 | 1362 | /* Check to see if this object is used as an attachment */ |
| | @@ -1303,30 +1375,36 @@ |
| 1303 | 1375 | " FROM attachment JOIN blob ON attachment.src=blob.uuid" |
| 1304 | 1376 | " WHERE blob.rid=%d", |
| 1305 | 1377 | rid |
| 1306 | 1378 | ); |
| 1307 | 1379 | while( db_step(&q)==SQLITE_ROW ){ |
| 1308 | | - fossil_print("attachment: %s\n", db_column_text(&q,0)); |
| 1309 | | - fossil_print(" attached to %s %s\n", |
| 1310 | | - db_column_text(&q,5), db_column_text(&q,4)); |
| 1311 | | - if( flags & WHATIS_VERBOSE ){ |
| 1312 | | - fossil_print(" via %s (%d)\n", |
| 1313 | | - db_column_text(&q,7), db_column_int(&q,6)); |
| 1380 | + if( pOut ){ |
| 1381 | + whatis_line(pOut, "attachment", "%s", db_column_text(&q,0)); |
| 1382 | + whatis_line(pOut, "attached-to", "%s %s", |
| 1383 | + db_column_text(&q,5), db_column_text(&q,4)); |
| 1314 | 1384 | }else{ |
| 1315 | | - fossil_print(" via %s\n", |
| 1316 | | - db_column_text(&q,7)); |
| 1385 | + fossil_print("attachment: %s\n", db_column_text(&q,0)); |
| 1386 | + fossil_print(" attached to %s %s\n", |
| 1387 | + db_column_text(&q,5), db_column_text(&q,4)); |
| 1388 | + if( flags & WHATIS_VERBOSE ){ |
| 1389 | + fossil_print(" via %s (%d)\n", |
| 1390 | + db_column_text(&q,7), db_column_int(&q,6)); |
| 1391 | + }else{ |
| 1392 | + fossil_print(" via %s\n", |
| 1393 | + db_column_text(&q,7)); |
| 1394 | + } |
| 1395 | + fossil_print(" by user %s on %s\n", |
| 1396 | + db_column_text(&q,2), db_column_text(&q,3)); |
| 1397 | + fossil_print(" "); |
| 1398 | + comment_print(db_column_text(&q,1), 0, 12, -1, get_comment_format()); |
| 1317 | 1399 | } |
| 1318 | | - fossil_print(" by user %s on %s\n", |
| 1319 | | - db_column_text(&q,2), db_column_text(&q,3)); |
| 1320 | | - fossil_print(" "); |
| 1321 | | - comment_print(db_column_text(&q,1), 0, 12, -1, get_comment_format()); |
| 1322 | 1400 | cnt++; |
| 1323 | 1401 | } |
| 1324 | 1402 | db_finalize(&q); |
| 1325 | 1403 | |
| 1326 | 1404 | /* If other information available, try to describe the object */ |
| 1327 | | - if( cnt==0 ){ |
| 1405 | + if( cnt==0 && pOut==0 ){ |
| 1328 | 1406 | char *zWhere = mprintf("=%d", rid); |
| 1329 | 1407 | char *zDesc; |
| 1330 | 1408 | describe_artifacts(zWhere); |
| 1331 | 1409 | free(zWhere); |
| 1332 | 1410 | zDesc = db_text(0, |
| | @@ -1339,19 +1417,25 @@ |
| 1339 | 1417 | |
| 1340 | 1418 | /* |
| 1341 | 1419 | ** Generate a description of artifact from it symbolic name. |
| 1342 | 1420 | */ |
| 1343 | 1421 | void whatis_artifact( |
| 1344 | | - const char *zName, /* Symbolic name or full hash */ |
| 1345 | | - const char *zFileName,/* Optional: original filename (in file mode) */ |
| 1346 | | - const char *zType, /* Artifact type filter */ |
| 1347 | | - int mFlags /* WHATIS_* flags */ |
| 1422 | + const char *zName, /* Symbolic name or full hash */ |
| 1423 | + const char *zFileName,/* Optional: original filename (in file mode) */ |
| 1424 | + const char *zType, /* Artifact type filter */ |
| 1425 | + int mFlags, /* WHATIS_* flags */ |
| 1426 | + sqlite3_str *pOut /* Write JSON here, if not NULL */ |
| 1348 | 1427 | ){ |
| 1349 | 1428 | int rid = symbolic_name_to_rid(zName, zType); |
| 1350 | 1429 | size_t nName; |
| 1351 | 1430 | char *zC = 0; |
| 1352 | 1431 | int nTkt = 0; |
| 1432 | + |
| 1433 | + if( pOut ){ |
| 1434 | + mFlags &= ~(WHATIS_HASHONLY|WHATIS_REPO); |
| 1435 | + zFileName = 0; |
| 1436 | + } |
| 1353 | 1437 | if( (nName = strlen(zName))>=4 && validate16(zName,nName) ){ |
| 1354 | 1438 | zC = fossil_strdup(zName); |
| 1355 | 1439 | canonical16(zC, nName); |
| 1356 | 1440 | nTkt = db_int(0,"SELECT count(*) FROM tag WHERE tagname GLOB 'tkt-%q*'",zC); |
| 1357 | 1441 | if( nTkt>0 ){ |
| | @@ -1376,18 +1460,28 @@ |
| 1376 | 1460 | fossil_print("\nrepository: %s\n", g.zRepositoryName); |
| 1377 | 1461 | } |
| 1378 | 1462 | if( zFileName ){ |
| 1379 | 1463 | fossil_print("%-12s%s\n", "name:", zFileName); |
| 1380 | 1464 | } |
| 1381 | | - fossil_print("%-12s%s (ambiguous)\n", "hash:", zName); |
| 1465 | + if( pOut ){ |
| 1466 | + sqlite3_str_appendall(pOut, "{\"ambiguous\":["); |
| 1467 | + }else{ |
| 1468 | + fossil_print("%-12s%s (ambiguous)\n", "hash:", zName); |
| 1469 | + } |
| 1382 | 1470 | db_prepare(&q, |
| 1383 | 1471 | "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", |
| 1384 | 1472 | zName, zName |
| 1385 | 1473 | ); |
| 1386 | 1474 | while( db_step(&q)==SQLITE_ROW ){ |
| 1387 | | - if( cnt++ ) fossil_print("%12s---- meaning #%d ----\n", " ", cnt); |
| 1388 | | - whatis_rid(db_column_int(&q, 0), mFlags); |
| 1475 | + if( cnt++ ){ |
| 1476 | + if( pOut ){ |
| 1477 | + sqlite3_str_append(pOut, ",", 1); |
| 1478 | + }else{ |
| 1479 | + fossil_print("%12s---- meaning #%d ----\n", " ", cnt); |
| 1480 | + } |
| 1481 | + } |
| 1482 | + whatis_rid(db_column_int(&q, 0), mFlags, pOut); |
| 1389 | 1483 | } |
| 1390 | 1484 | db_finalize(&q); |
| 1391 | 1485 | if( nTkt>0 ){ |
| 1392 | 1486 | db_prepare(&q, |
| 1393 | 1487 | "SELECT (SELECT srcid FROM tagxref" |
| | @@ -1396,34 +1490,41 @@ |
| 1396 | 1490 | " ORDER BY mtime LIMIT 1)" |
| 1397 | 1491 | " FROM tag WHERE tagname GLOB 'tkt-%q*'", |
| 1398 | 1492 | zC |
| 1399 | 1493 | ); |
| 1400 | 1494 | while( db_step(&q)==SQLITE_ROW ){ |
| 1401 | | - if( cnt++ ) fossil_print("%12s---- meaning #%d ----\n", " ", cnt); |
| 1402 | | - whatis_rid(db_column_int(&q, 0), mFlags); |
| 1495 | + if( pOut ){ |
| 1496 | + sqlite3_str_append(pOut, ",", 1); |
| 1497 | + }else{ |
| 1498 | + fossil_print("%12s---- meaning #%d ----\n", " ", cnt); |
| 1499 | + } |
| 1500 | + whatis_rid(db_column_int(&q, 0), mFlags, pOut); |
| 1403 | 1501 | } |
| 1404 | 1502 | db_finalize(&q); |
| 1405 | 1503 | } |
| 1504 | + if( pOut ) sqlite3_str_append(pOut, "]", 1); |
| 1406 | 1505 | }else if( rid==0 ){ |
| 1407 | 1506 | if( (mFlags & (WHATIS_OMIT_UNK|WHATIS_HASHONLY))==0 ){ |
| 1408 | 1507 | /* 0123456789 12 */ |
| 1409 | 1508 | if( zFileName ){ |
| 1410 | 1509 | fossil_print("%-12s%s\n", "name:", zFileName); |
| 1411 | 1510 | } |
| 1412 | | - fossil_print("unknown: %s\n", zName); |
| 1511 | + if( pOut ) sqlite3_str_append(pOut, "{", 1); |
| 1512 | + whatis_line(pOut, "unknown", "%s", zName); |
| 1513 | + if( pOut ) sqlite3_str_append(pOut, "}", 1); |
| 1413 | 1514 | } |
| 1414 | 1515 | }else{ |
| 1415 | 1516 | if( mFlags & WHATIS_REPO ){ |
| 1416 | 1517 | fossil_print("\nrepository: %s\n", g.zRepositoryName); |
| 1417 | 1518 | } |
| 1418 | 1519 | if( zFileName ){ |
| 1419 | 1520 | zName = zFileName; |
| 1420 | 1521 | } |
| 1421 | | - if( (mFlags & WHATIS_HASHONLY)==0 ){ |
| 1422 | | - fossil_print("%-12s%s\n", "name:", zName); |
| 1522 | + if( (mFlags & WHATIS_HASHONLY)==0 && pOut==0 ){ |
| 1523 | + whatis_line(pOut, "name", "%s", zName); |
| 1423 | 1524 | } |
| 1424 | | - whatis_rid(rid, mFlags); |
| 1525 | + whatis_rid(rid, mFlags, pOut); |
| 1425 | 1526 | } |
| 1426 | 1527 | fossil_free(zC); |
| 1427 | 1528 | } |
| 1428 | 1529 | |
| 1429 | 1530 | /* |
| | @@ -1449,10 +1550,11 @@ |
| 1449 | 1550 | void whatis_cmd(void){ |
| 1450 | 1551 | int mFlags = 0; |
| 1451 | 1552 | int fileFlag; |
| 1452 | 1553 | int i; |
| 1453 | 1554 | const char *zType = 0; |
| 1555 | + sqlite3_str *pOut = 0; |
| 1454 | 1556 | db_find_and_open_repository(0,0); |
| 1455 | 1557 | if( find_option("verbose","v",0)!=0 ){ |
| 1456 | 1558 | mFlags |= WHATIS_VERBOSE; |
| 1457 | 1559 | } |
| 1458 | 1560 | if( find_option("hash","h",0)!=0 ){ |
| | @@ -1461,10 +1563,14 @@ |
| 1461 | 1563 | if( g.fQuiet ){ |
| 1462 | 1564 | mFlags |= WHATIS_OMIT_UNK | WHATIS_REPO; |
| 1463 | 1565 | } |
| 1464 | 1566 | fileFlag = find_option("file","f",0)!=0; |
| 1465 | 1567 | zType = find_option("type",0,1); |
| 1568 | + |
| 1569 | + if( find_option("json",0,0)!=0 ){ /* undocumented test option */ |
| 1570 | + pOut = sqlite3_str_new(0); |
| 1571 | + } |
| 1466 | 1572 | |
| 1467 | 1573 | /* We should be done with options.. */ |
| 1468 | 1574 | verify_all_options(); |
| 1469 | 1575 | |
| 1470 | 1576 | if( g.argc<3 ) usage("NAME ..."); |
| | @@ -1487,17 +1593,52 @@ |
| 1487 | 1593 | ** the primary hash name. */ |
| 1488 | 1594 | blob_reset(&hash); |
| 1489 | 1595 | hname_hash(&in, 0, &hash); |
| 1490 | 1596 | zHash = (const char*)blob_str(&hash); |
| 1491 | 1597 | } |
| 1492 | | - whatis_artifact(zHash, zName, zType, mFlags); |
| 1598 | + whatis_artifact(zHash, zName, zType, mFlags, pOut); |
| 1493 | 1599 | blob_reset(&hash); |
| 1494 | 1600 | }else{ |
| 1495 | | - whatis_artifact(zName, 0, zType, mFlags); |
| 1601 | + whatis_artifact(zName, 0, zType, mFlags, pOut); |
| 1602 | + } |
| 1603 | + if( pOut ){ |
| 1604 | + fossil_print("%s\n", sqlite3_str_value(pOut)); |
| 1605 | + sqlite3_str_truncate(pOut, 0); |
| 1496 | 1606 | } |
| 1497 | 1607 | } |
| 1608 | + if( pOut ) sqlite3_str_free(pOut); |
| 1609 | +} |
| 1610 | + |
| 1611 | +/* |
| 1612 | +** This is an SQL function that does the rough equivalent of the |
| 1613 | +** "whatis" command. The argument can be a text identifier, or a |
| 1614 | +** integer RID. |
| 1615 | +*/ |
| 1616 | +void whatis_sql_function( |
| 1617 | + sqlite3_context *context, |
| 1618 | + int argc, |
| 1619 | + sqlite3_value **argv |
| 1620 | +){ |
| 1621 | + sqlite3_str *pOut = sqlite3_str_new(0); |
| 1622 | + int n; |
| 1623 | + assert( argc==1 ); |
| 1624 | + if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){ |
| 1625 | + int rid = sqlite3_value_int(argv[0]); |
| 1626 | + whatis_rid(rid, 0, pOut); |
| 1627 | + }else if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){ |
| 1628 | + const char *zName = (const char*)sqlite3_value_text(argv[0]); |
| 1629 | + whatis_artifact(zName, 0, 0, 0, pOut); |
| 1630 | + }else{ |
| 1631 | + sqlite3_str_free(pOut); |
| 1632 | + return; |
| 1633 | + } |
| 1634 | + n = sqlite3_str_length(pOut); |
| 1635 | + sqlite3_result_text64(context, sqlite3_str_finish(pOut), n, |
| 1636 | + sqlite3_free, SQLITE_UTF8); |
| 1637 | + sqlite3_result_subtype(context, 'J'); |
| 1498 | 1638 | } |
| 1639 | + |
| 1499 | 1640 | |
| 1500 | 1641 | /* |
| 1501 | 1642 | ** COMMAND: test-whatis-all |
| 1502 | 1643 | ** |
| 1503 | 1644 | ** Usage: %fossil test-whatis-all |
| | @@ -1509,11 +1650,11 @@ |
| 1509 | 1650 | int cnt = 0; |
| 1510 | 1651 | db_find_and_open_repository(0,0); |
| 1511 | 1652 | db_prepare(&q, "SELECT rid FROM blob ORDER BY rid"); |
| 1512 | 1653 | while( db_step(&q)==SQLITE_ROW ){ |
| 1513 | 1654 | if( cnt++ ) fossil_print("%.79c\n", '-'); |
| 1514 | | - whatis_rid(db_column_int(&q,0), 1); |
| 1655 | + whatis_rid(db_column_int(&q,0), 1, 0); |
| 1515 | 1656 | } |
| 1516 | 1657 | db_finalize(&q); |
| 1517 | 1658 | } |
| 1518 | 1659 | |
| 1519 | 1660 | |
| 1520 | 1661 | |