Fossil SCM
Correct the new attachment-target-to-rid code to return the tip version RID of forum posts. General cleanups in attachment-related code. Add some test code for resolving attachment targets.
Commit
830cad5676d99e3051e93c8f0da01bc1a9579b0a58d2b5600f16818d1dd5c415
Parent
33f6106490c97c9…
1 file changed
+66
-25
+66
-25
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -130,10 +130,13 @@ | ||
| 130 | 130 | "AND b.uuid %s '%q%s'", |
| 131 | 131 | bFull ? "=" : "GLOB"/*safe-for-%s*/, |
| 132 | 132 | zTarget, |
| 133 | 133 | bFull ? "" : "*"/*safe-for-%s*/ |
| 134 | 134 | ); |
| 135 | + if( rid>0 ){ | |
| 136 | + rid = forumpost_head_rid(rid); | |
| 137 | + } | |
| 135 | 138 | break; |
| 136 | 139 | case CFTYPE_WIKI: |
| 137 | 140 | rid = db_int( |
| 138 | 141 | 0, "SELECT b.rid FROM blob b, tag t, tagxref x\n" |
| 139 | 142 | "WHERE tagname='wiki-%q'\n" |
| @@ -1310,15 +1313,18 @@ | ||
| 1310 | 1313 | char szBuf[36] = {0}; /* scratchpad for attachment size value */ |
| 1311 | 1314 | const char *zLinkTgt = (ATTACHLIST_TARGET_BLANK & flags) |
| 1312 | 1315 | ? " target=\"_blank\"" : ""; |
| 1313 | 1316 | Stmt q; |
| 1314 | 1317 | db_prepare(&q, |
| 1315 | - "SELECT datetime(mtime,toLocal()), filename, user," | |
| 1316 | - " (SELECT uuid FROM blob WHERE rid=attachid), src, target, " | |
| 1317 | - " attachid " | |
| 1318 | - " FROM attachment" | |
| 1319 | - " WHERE isLatest AND src!='' AND target=%Q" | |
| 1318 | + "SELECT datetime(mtime,toLocal()), a.filename, a.user," | |
| 1319 | + " b1.uuid, a.src, a.target, a.attachid, b2.size\n" | |
| 1320 | + " FROM attachment a, blob b1, blob b2\n" | |
| 1321 | + " WHERE a.isLatest\n" | |
| 1322 | + " AND a.src IS NOT NULL\n" | |
| 1323 | + " AND a.target=%Q\n" | |
| 1324 | + " AND b1.rid=a.attachid\n" | |
| 1325 | + " AND b2.uuid=a.src\n" | |
| 1320 | 1326 | " ORDER BY mtime DESC", |
| 1321 | 1327 | zTarget |
| 1322 | 1328 | ); |
| 1323 | 1329 | while( db_step(&q)==SQLITE_ROW ){ |
| 1324 | 1330 | const char *zDate = db_column_text(&q, 0); |
| @@ -1328,11 +1334,11 @@ | ||
| 1328 | 1334 | const char *zSrc = db_column_text(&q, 4); |
| 1329 | 1335 | const char *zTarget = db_column_text(&q, 5); |
| 1330 | 1336 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 1331 | 1337 | const char *zTypeArg = 0; /* URL arg name for /attachdownload */ |
| 1332 | 1338 | const int aid = db_column_int(&q, 6); |
| 1333 | - const int iAType = attachment_target_type(zTarget, 1); | |
| 1339 | + const int sz = db_column_int(&q, 7); | |
| 1334 | 1340 | if( (flags & ATTACHLIST_HIDE_UNAPPROVED) |
| 1335 | 1341 | && moderation_pending(aid) |
| 1336 | 1342 | && !moderation_user_could(aid, 1, 0) ){ |
| 1337 | 1343 | continue; |
| 1338 | 1344 | } |
| @@ -1343,21 +1349,20 @@ | ||
| 1343 | 1349 | } |
| 1344 | 1350 | @ %s(zHeader) |
| 1345 | 1351 | @ <ul> |
| 1346 | 1352 | } |
| 1347 | 1353 | cnt++; |
| 1348 | - switch( iAType ){ | |
| 1354 | + switch( attachment_target_type(zTarget, 1) ){ | |
| 1349 | 1355 | case CFTYPE_TICKET: zTypeArg = "tkt"; break; |
| 1350 | 1356 | case CFTYPE_FORUM: zTypeArg = "forumpost"; break; |
| 1351 | 1357 | case CFTYPE_EVENT: zTypeArg = "technote"; break; |
| 1352 | 1358 | case CFTYPE_WIKI: |
| 1353 | 1359 | default: zTypeArg = "page"; break; |
| 1354 | 1360 | } |
| 1355 | 1361 | @ <li> |
| 1356 | 1362 | @ <a href="%R/artifact/%!S(zSrc)"%s(zLinkTgt)>%h(zFile)</a> |
| 1357 | 1363 | if( flags & ATTACHLIST_SIZE ){ |
| 1358 | - const int sz = db_int(0,"SELECT size FROM blob WHERE uuid=%Q", zSrc); | |
| 1359 | 1364 | sqlite3_snprintf(sizeof(szBuf), szBuf, " %d bytes", sz); |
| 1360 | 1365 | } |
| 1361 | 1366 | @ [<a href="%R/attachdownload/%t(zFile)?%s(zTypeArg)=%t(zTarget)\ |
| 1362 | 1367 | @&file=%t(zFile)%s(zLinkTgt)">download</a>%s(szBuf)] |
| 1363 | 1368 | @ added by %h(zDispUser) on |
| @@ -1583,13 +1588,13 @@ | ||
| 1583 | 1588 | db_prepare(&q, |
| 1584 | 1589 | "SELECT datetime(mtime), a.src, a.target, a.filename, a.isLatest,\n" |
| 1585 | 1590 | " b2.size, b1.uuid, a.user, a.comment\n" |
| 1586 | 1591 | " FROM attachment a, blob b1, blob b2\n" |
| 1587 | 1592 | " WHERE a.target=%Q\n" |
| 1593 | + " AND a.src IS NOT NULL\n" | |
| 1588 | 1594 | " AND b1.rid=a.attachid\n" |
| 1589 | 1595 | " AND b2.uuid=a.src\n" |
| 1590 | - " AND b2.size>0\n" | |
| 1591 | 1596 | " AND (a.isLatest OR %d)\n" |
| 1592 | 1597 | " ORDER BY a.target, a.isLatest DESC, a.mtime DESC\n", |
| 1593 | 1598 | zTgt, !bLatestOnly |
| 1594 | 1599 | ); |
| 1595 | 1600 | while(SQLITE_ROW == db_step(&q)){ |
| @@ -1635,10 +1640,41 @@ | ||
| 1635 | 1640 | }else{ |
| 1636 | 1641 | blob_append_char(pOut, ']'); |
| 1637 | 1642 | } |
| 1638 | 1643 | return i; |
| 1639 | 1644 | } |
| 1645 | + | |
| 1646 | +/* | |
| 1647 | +** COMMAND: test-attachment-target | |
| 1648 | +** | |
| 1649 | +** Usage: %fossil test-attachment-target TARGET_ID... | |
| 1650 | +*/ | |
| 1651 | +void test_attachment_target_type_cmd(void){ | |
| 1652 | + int i; | |
| 1653 | + verify_all_options(); | |
| 1654 | + db_find_and_open_repository(0, 0); | |
| 1655 | + if( g.argc<3 ){ | |
| 1656 | + usage("test-attachment-target TARGET_ID"); | |
| 1657 | + return; | |
| 1658 | + } | |
| 1659 | + for( i = 2; i < g.argc; ++i ){ | |
| 1660 | + const char *zTarget = g.argv[i]; | |
| 1661 | + const int rid = attachment_target_rid(zTarget, 0); | |
| 1662 | + const int type = attachment_target_type(zTarget, 0); | |
| 1663 | + const char *zType = "<invalid>"; | |
| 1664 | + switch(type){ | |
| 1665 | + case CFTYPE_EVENT: zType = "e"; break; | |
| 1666 | + case CFTYPE_FORUM: zType = "f"; break; | |
| 1667 | + case CFTYPE_TICKET: zType = "t"; break; | |
| 1668 | + case CFTYPE_WIKI: zType = "w"; break; | |
| 1669 | + } | |
| 1670 | + fossil_print("%-20s = %s %d %z\n", | |
| 1671 | + zTarget, zType, rid, | |
| 1672 | + rid>0 ? rid_to_uuid(rid) : 0); | |
| 1673 | + } | |
| 1674 | +} | |
| 1675 | + | |
| 1640 | 1676 | |
| 1641 | 1677 | /* |
| 1642 | 1678 | ** COMMAND: test-attachments-to-json |
| 1643 | 1679 | ** |
| 1644 | 1680 | ** Usage: %fossil test-attachments-to-json TARGET_ID |
| @@ -1657,29 +1693,34 @@ | ||
| 1657 | 1693 | void test_attachments_to_json_cmd(void){ |
| 1658 | 1694 | Manifest *pManifest; |
| 1659 | 1695 | Blob b = BLOB_INITIALIZER; |
| 1660 | 1696 | int bLatestOnly = find_option("old",0,0)==0; |
| 1661 | 1697 | int emptyPolicy = 1; |
| 1662 | - int rid; | |
| 1698 | + int rid, i; | |
| 1663 | 1699 | int bFullId = find_option("full",0,0)!=0; |
| 1664 | - const char *zTarget; | |
| 1665 | 1700 | verify_all_options(); |
| 1666 | 1701 | db_find_and_open_repository(0, 0); |
| 1667 | 1702 | if( g.argc<3 ){ |
| 1668 | 1703 | usage("test-attachments-to-json TARGET_ID"); |
| 1669 | 1704 | return; |
| 1670 | 1705 | } |
| 1671 | - zTarget = g.argv[2]; | |
| 1672 | - rid = attachment_target_rid(zTarget, bFullId); | |
| 1673 | - if( 0==rid ){ | |
| 1674 | - fossil_fatal("Cannot resolve ID."); | |
| 1675 | - } | |
| 1676 | - pManifest = manifest_get(rid, CFTYPE_ANY, NULL); | |
| 1677 | - attachments_to_json(pManifest, &b, bLatestOnly, emptyPolicy); | |
| 1678 | - if( b.nUsed ){ | |
| 1679 | - char *zPretty = db_text(0,"SELECT json_pretty(%B)", &b); | |
| 1680 | - fossil_print("%s\n", zPretty); | |
| 1681 | - fossil_free(zPretty); | |
| 1682 | - } | |
| 1683 | - blob_reset(&b); | |
| 1684 | - manifest_destroy(pManifest); | |
| 1706 | + for( i = 2; i < g.argc; ++i ){ | |
| 1707 | + const char *zTarget = g.argv[i]; | |
| 1708 | + rid = attachment_target_rid(zTarget, bFullId); | |
| 1709 | + if( 0==rid ){ | |
| 1710 | + fossil_print("** cannot resolve %s\n", zTarget); | |
| 1711 | + continue; | |
| 1712 | + } | |
| 1713 | + pManifest = manifest_get(rid, CFTYPE_ANY, NULL); | |
| 1714 | + attachments_to_json(pManifest, &b, bLatestOnly, emptyPolicy); | |
| 1715 | + fossil_print("Attachments for %s: ", zTarget); | |
| 1716 | + if( b.nUsed ){ | |
| 1717 | + char *zPretty = db_text(0,"SELECT json_pretty(%B)", &b); | |
| 1718 | + fossil_print("%s\n", zPretty); | |
| 1719 | + fossil_free(zPretty); | |
| 1720 | + }else{ | |
| 1721 | + fossil_print("none\n"); | |
| 1722 | + } | |
| 1723 | + blob_reset(&b); | |
| 1724 | + manifest_destroy(pManifest); | |
| 1725 | + } | |
| 1685 | 1726 | } |
| 1686 | 1727 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -130,10 +130,13 @@ | |
| 130 | "AND b.uuid %s '%q%s'", |
| 131 | bFull ? "=" : "GLOB"/*safe-for-%s*/, |
| 132 | zTarget, |
| 133 | bFull ? "" : "*"/*safe-for-%s*/ |
| 134 | ); |
| 135 | break; |
| 136 | case CFTYPE_WIKI: |
| 137 | rid = db_int( |
| 138 | 0, "SELECT b.rid FROM blob b, tag t, tagxref x\n" |
| 139 | "WHERE tagname='wiki-%q'\n" |
| @@ -1310,15 +1313,18 @@ | |
| 1310 | char szBuf[36] = {0}; /* scratchpad for attachment size value */ |
| 1311 | const char *zLinkTgt = (ATTACHLIST_TARGET_BLANK & flags) |
| 1312 | ? " target=\"_blank\"" : ""; |
| 1313 | Stmt q; |
| 1314 | db_prepare(&q, |
| 1315 | "SELECT datetime(mtime,toLocal()), filename, user," |
| 1316 | " (SELECT uuid FROM blob WHERE rid=attachid), src, target, " |
| 1317 | " attachid " |
| 1318 | " FROM attachment" |
| 1319 | " WHERE isLatest AND src!='' AND target=%Q" |
| 1320 | " ORDER BY mtime DESC", |
| 1321 | zTarget |
| 1322 | ); |
| 1323 | while( db_step(&q)==SQLITE_ROW ){ |
| 1324 | const char *zDate = db_column_text(&q, 0); |
| @@ -1328,11 +1334,11 @@ | |
| 1328 | const char *zSrc = db_column_text(&q, 4); |
| 1329 | const char *zTarget = db_column_text(&q, 5); |
| 1330 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 1331 | const char *zTypeArg = 0; /* URL arg name for /attachdownload */ |
| 1332 | const int aid = db_column_int(&q, 6); |
| 1333 | const int iAType = attachment_target_type(zTarget, 1); |
| 1334 | if( (flags & ATTACHLIST_HIDE_UNAPPROVED) |
| 1335 | && moderation_pending(aid) |
| 1336 | && !moderation_user_could(aid, 1, 0) ){ |
| 1337 | continue; |
| 1338 | } |
| @@ -1343,21 +1349,20 @@ | |
| 1343 | } |
| 1344 | @ %s(zHeader) |
| 1345 | @ <ul> |
| 1346 | } |
| 1347 | cnt++; |
| 1348 | switch( iAType ){ |
| 1349 | case CFTYPE_TICKET: zTypeArg = "tkt"; break; |
| 1350 | case CFTYPE_FORUM: zTypeArg = "forumpost"; break; |
| 1351 | case CFTYPE_EVENT: zTypeArg = "technote"; break; |
| 1352 | case CFTYPE_WIKI: |
| 1353 | default: zTypeArg = "page"; break; |
| 1354 | } |
| 1355 | @ <li> |
| 1356 | @ <a href="%R/artifact/%!S(zSrc)"%s(zLinkTgt)>%h(zFile)</a> |
| 1357 | if( flags & ATTACHLIST_SIZE ){ |
| 1358 | const int sz = db_int(0,"SELECT size FROM blob WHERE uuid=%Q", zSrc); |
| 1359 | sqlite3_snprintf(sizeof(szBuf), szBuf, " %d bytes", sz); |
| 1360 | } |
| 1361 | @ [<a href="%R/attachdownload/%t(zFile)?%s(zTypeArg)=%t(zTarget)\ |
| 1362 | @&file=%t(zFile)%s(zLinkTgt)">download</a>%s(szBuf)] |
| 1363 | @ added by %h(zDispUser) on |
| @@ -1583,13 +1588,13 @@ | |
| 1583 | db_prepare(&q, |
| 1584 | "SELECT datetime(mtime), a.src, a.target, a.filename, a.isLatest,\n" |
| 1585 | " b2.size, b1.uuid, a.user, a.comment\n" |
| 1586 | " FROM attachment a, blob b1, blob b2\n" |
| 1587 | " WHERE a.target=%Q\n" |
| 1588 | " AND b1.rid=a.attachid\n" |
| 1589 | " AND b2.uuid=a.src\n" |
| 1590 | " AND b2.size>0\n" |
| 1591 | " AND (a.isLatest OR %d)\n" |
| 1592 | " ORDER BY a.target, a.isLatest DESC, a.mtime DESC\n", |
| 1593 | zTgt, !bLatestOnly |
| 1594 | ); |
| 1595 | while(SQLITE_ROW == db_step(&q)){ |
| @@ -1635,10 +1640,41 @@ | |
| 1635 | }else{ |
| 1636 | blob_append_char(pOut, ']'); |
| 1637 | } |
| 1638 | return i; |
| 1639 | } |
| 1640 | |
| 1641 | /* |
| 1642 | ** COMMAND: test-attachments-to-json |
| 1643 | ** |
| 1644 | ** Usage: %fossil test-attachments-to-json TARGET_ID |
| @@ -1657,29 +1693,34 @@ | |
| 1657 | void test_attachments_to_json_cmd(void){ |
| 1658 | Manifest *pManifest; |
| 1659 | Blob b = BLOB_INITIALIZER; |
| 1660 | int bLatestOnly = find_option("old",0,0)==0; |
| 1661 | int emptyPolicy = 1; |
| 1662 | int rid; |
| 1663 | int bFullId = find_option("full",0,0)!=0; |
| 1664 | const char *zTarget; |
| 1665 | verify_all_options(); |
| 1666 | db_find_and_open_repository(0, 0); |
| 1667 | if( g.argc<3 ){ |
| 1668 | usage("test-attachments-to-json TARGET_ID"); |
| 1669 | return; |
| 1670 | } |
| 1671 | zTarget = g.argv[2]; |
| 1672 | rid = attachment_target_rid(zTarget, bFullId); |
| 1673 | if( 0==rid ){ |
| 1674 | fossil_fatal("Cannot resolve ID."); |
| 1675 | } |
| 1676 | pManifest = manifest_get(rid, CFTYPE_ANY, NULL); |
| 1677 | attachments_to_json(pManifest, &b, bLatestOnly, emptyPolicy); |
| 1678 | if( b.nUsed ){ |
| 1679 | char *zPretty = db_text(0,"SELECT json_pretty(%B)", &b); |
| 1680 | fossil_print("%s\n", zPretty); |
| 1681 | fossil_free(zPretty); |
| 1682 | } |
| 1683 | blob_reset(&b); |
| 1684 | manifest_destroy(pManifest); |
| 1685 | } |
| 1686 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -130,10 +130,13 @@ | |
| 130 | "AND b.uuid %s '%q%s'", |
| 131 | bFull ? "=" : "GLOB"/*safe-for-%s*/, |
| 132 | zTarget, |
| 133 | bFull ? "" : "*"/*safe-for-%s*/ |
| 134 | ); |
| 135 | if( rid>0 ){ |
| 136 | rid = forumpost_head_rid(rid); |
| 137 | } |
| 138 | break; |
| 139 | case CFTYPE_WIKI: |
| 140 | rid = db_int( |
| 141 | 0, "SELECT b.rid FROM blob b, tag t, tagxref x\n" |
| 142 | "WHERE tagname='wiki-%q'\n" |
| @@ -1310,15 +1313,18 @@ | |
| 1313 | char szBuf[36] = {0}; /* scratchpad for attachment size value */ |
| 1314 | const char *zLinkTgt = (ATTACHLIST_TARGET_BLANK & flags) |
| 1315 | ? " target=\"_blank\"" : ""; |
| 1316 | Stmt q; |
| 1317 | db_prepare(&q, |
| 1318 | "SELECT datetime(mtime,toLocal()), a.filename, a.user," |
| 1319 | " b1.uuid, a.src, a.target, a.attachid, b2.size\n" |
| 1320 | " FROM attachment a, blob b1, blob b2\n" |
| 1321 | " WHERE a.isLatest\n" |
| 1322 | " AND a.src IS NOT NULL\n" |
| 1323 | " AND a.target=%Q\n" |
| 1324 | " AND b1.rid=a.attachid\n" |
| 1325 | " AND b2.uuid=a.src\n" |
| 1326 | " ORDER BY mtime DESC", |
| 1327 | zTarget |
| 1328 | ); |
| 1329 | while( db_step(&q)==SQLITE_ROW ){ |
| 1330 | const char *zDate = db_column_text(&q, 0); |
| @@ -1328,11 +1334,11 @@ | |
| 1334 | const char *zSrc = db_column_text(&q, 4); |
| 1335 | const char *zTarget = db_column_text(&q, 5); |
| 1336 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 1337 | const char *zTypeArg = 0; /* URL arg name for /attachdownload */ |
| 1338 | const int aid = db_column_int(&q, 6); |
| 1339 | const int sz = db_column_int(&q, 7); |
| 1340 | if( (flags & ATTACHLIST_HIDE_UNAPPROVED) |
| 1341 | && moderation_pending(aid) |
| 1342 | && !moderation_user_could(aid, 1, 0) ){ |
| 1343 | continue; |
| 1344 | } |
| @@ -1343,21 +1349,20 @@ | |
| 1349 | } |
| 1350 | @ %s(zHeader) |
| 1351 | @ <ul> |
| 1352 | } |
| 1353 | cnt++; |
| 1354 | switch( attachment_target_type(zTarget, 1) ){ |
| 1355 | case CFTYPE_TICKET: zTypeArg = "tkt"; break; |
| 1356 | case CFTYPE_FORUM: zTypeArg = "forumpost"; break; |
| 1357 | case CFTYPE_EVENT: zTypeArg = "technote"; break; |
| 1358 | case CFTYPE_WIKI: |
| 1359 | default: zTypeArg = "page"; break; |
| 1360 | } |
| 1361 | @ <li> |
| 1362 | @ <a href="%R/artifact/%!S(zSrc)"%s(zLinkTgt)>%h(zFile)</a> |
| 1363 | if( flags & ATTACHLIST_SIZE ){ |
| 1364 | sqlite3_snprintf(sizeof(szBuf), szBuf, " %d bytes", sz); |
| 1365 | } |
| 1366 | @ [<a href="%R/attachdownload/%t(zFile)?%s(zTypeArg)=%t(zTarget)\ |
| 1367 | @&file=%t(zFile)%s(zLinkTgt)">download</a>%s(szBuf)] |
| 1368 | @ added by %h(zDispUser) on |
| @@ -1583,13 +1588,13 @@ | |
| 1588 | db_prepare(&q, |
| 1589 | "SELECT datetime(mtime), a.src, a.target, a.filename, a.isLatest,\n" |
| 1590 | " b2.size, b1.uuid, a.user, a.comment\n" |
| 1591 | " FROM attachment a, blob b1, blob b2\n" |
| 1592 | " WHERE a.target=%Q\n" |
| 1593 | " AND a.src IS NOT NULL\n" |
| 1594 | " AND b1.rid=a.attachid\n" |
| 1595 | " AND b2.uuid=a.src\n" |
| 1596 | " AND (a.isLatest OR %d)\n" |
| 1597 | " ORDER BY a.target, a.isLatest DESC, a.mtime DESC\n", |
| 1598 | zTgt, !bLatestOnly |
| 1599 | ); |
| 1600 | while(SQLITE_ROW == db_step(&q)){ |
| @@ -1635,10 +1640,41 @@ | |
| 1640 | }else{ |
| 1641 | blob_append_char(pOut, ']'); |
| 1642 | } |
| 1643 | return i; |
| 1644 | } |
| 1645 | |
| 1646 | /* |
| 1647 | ** COMMAND: test-attachment-target |
| 1648 | ** |
| 1649 | ** Usage: %fossil test-attachment-target TARGET_ID... |
| 1650 | */ |
| 1651 | void test_attachment_target_type_cmd(void){ |
| 1652 | int i; |
| 1653 | verify_all_options(); |
| 1654 | db_find_and_open_repository(0, 0); |
| 1655 | if( g.argc<3 ){ |
| 1656 | usage("test-attachment-target TARGET_ID"); |
| 1657 | return; |
| 1658 | } |
| 1659 | for( i = 2; i < g.argc; ++i ){ |
| 1660 | const char *zTarget = g.argv[i]; |
| 1661 | const int rid = attachment_target_rid(zTarget, 0); |
| 1662 | const int type = attachment_target_type(zTarget, 0); |
| 1663 | const char *zType = "<invalid>"; |
| 1664 | switch(type){ |
| 1665 | case CFTYPE_EVENT: zType = "e"; break; |
| 1666 | case CFTYPE_FORUM: zType = "f"; break; |
| 1667 | case CFTYPE_TICKET: zType = "t"; break; |
| 1668 | case CFTYPE_WIKI: zType = "w"; break; |
| 1669 | } |
| 1670 | fossil_print("%-20s = %s %d %z\n", |
| 1671 | zTarget, zType, rid, |
| 1672 | rid>0 ? rid_to_uuid(rid) : 0); |
| 1673 | } |
| 1674 | } |
| 1675 | |
| 1676 | |
| 1677 | /* |
| 1678 | ** COMMAND: test-attachments-to-json |
| 1679 | ** |
| 1680 | ** Usage: %fossil test-attachments-to-json TARGET_ID |
| @@ -1657,29 +1693,34 @@ | |
| 1693 | void test_attachments_to_json_cmd(void){ |
| 1694 | Manifest *pManifest; |
| 1695 | Blob b = BLOB_INITIALIZER; |
| 1696 | int bLatestOnly = find_option("old",0,0)==0; |
| 1697 | int emptyPolicy = 1; |
| 1698 | int rid, i; |
| 1699 | int bFullId = find_option("full",0,0)!=0; |
| 1700 | verify_all_options(); |
| 1701 | db_find_and_open_repository(0, 0); |
| 1702 | if( g.argc<3 ){ |
| 1703 | usage("test-attachments-to-json TARGET_ID"); |
| 1704 | return; |
| 1705 | } |
| 1706 | for( i = 2; i < g.argc; ++i ){ |
| 1707 | const char *zTarget = g.argv[i]; |
| 1708 | rid = attachment_target_rid(zTarget, bFullId); |
| 1709 | if( 0==rid ){ |
| 1710 | fossil_print("** cannot resolve %s\n", zTarget); |
| 1711 | continue; |
| 1712 | } |
| 1713 | pManifest = manifest_get(rid, CFTYPE_ANY, NULL); |
| 1714 | attachments_to_json(pManifest, &b, bLatestOnly, emptyPolicy); |
| 1715 | fossil_print("Attachments for %s: ", zTarget); |
| 1716 | if( b.nUsed ){ |
| 1717 | char *zPretty = db_text(0,"SELECT json_pretty(%B)", &b); |
| 1718 | fossil_print("%s\n", zPretty); |
| 1719 | fossil_free(zPretty); |
| 1720 | }else{ |
| 1721 | fossil_print("none\n"); |
| 1722 | } |
| 1723 | blob_reset(&b); |
| 1724 | manifest_destroy(pManifest); |
| 1725 | } |
| 1726 | } |
| 1727 |