Fossil SCM
Add the describe_artifacts() utility procedure and the test-describe-artifacts command for testing it.
Commit
47115adec54bbfb3dcd971ac9a341f115e21e49e
Parent
85f239f1f7af939…
1 file changed
+162
+162
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -779,5 +779,167 @@ | ||
| 779 | 779 | while( db_step(&q)==SQLITE_ROW ){ |
| 780 | 780 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 781 | 781 | } |
| 782 | 782 | db_finalize(&q); |
| 783 | 783 | } |
| 784 | + | |
| 785 | +/* | |
| 786 | +** Schema for the description table | |
| 787 | +*/ | |
| 788 | +static const char zDescTab[] = | |
| 789 | +@ CREATE TEMP TABLE IF NOT EXISTS description( | |
| 790 | +@ rid INTEGER PRIMARY KEY, | |
| 791 | +@ uuid TEXT, -- SHA1 hash of the object | |
| 792 | +@ ctime DATETIME, -- Time of creation | |
| 793 | +@ type TEXT, -- file, checkin, wiki, ticket-change, etc. | |
| 794 | +@ detail TEXT -- filename, checkin comment, etc | |
| 795 | +@ ); | |
| 796 | +; | |
| 797 | + | |
| 798 | +/* | |
| 799 | +** Create the description table if it does not already exists. | |
| 800 | +** Populate fields of this table with descriptions for all artifacts | |
| 801 | +** whose RID matches the SQL expression in zWhere. | |
| 802 | +*/ | |
| 803 | +void describe_artifacts(const char *zWhere){ | |
| 804 | + Stmt q; | |
| 805 | + Stmt ins; | |
| 806 | + | |
| 807 | + db_multi_exec("%s", zDescTab/*safe-for-%s*/); | |
| 808 | + | |
| 809 | + /* Describe checkins */ | |
| 810 | + db_multi_exec( | |
| 811 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type)\n" | |
| 812 | + "SELECT blob.rid, blob.uuid, event.mtime, 'checkin'\n" | |
| 813 | + " FROM event, blob\n" | |
| 814 | + " WHERE event.objid %s AND event.type='ci'\n" | |
| 815 | + " AND event.objid=blob.rid;", | |
| 816 | + zWhere /*safe-for-%s*/ | |
| 817 | + ); | |
| 818 | + | |
| 819 | + /* Describe files */ | |
| 820 | + db_multi_exec( | |
| 821 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" | |
| 822 | + "SELECT blob.rid, blob.uuid, event.mtime, 'file', filename.name\n" | |
| 823 | + " FROM mlink, blob, event, filename\n" | |
| 824 | + " WHERE mlink.fid %s\n" | |
| 825 | + " AND mlink.mid=event.objid\n" | |
| 826 | + " AND filename.fnid=mlink.fnid\n" | |
| 827 | + " AND mlink.fid=blob.rid;", | |
| 828 | + zWhere /*safe-for-%s*/ | |
| 829 | + ); | |
| 830 | + | |
| 831 | + /* Describe tags */ | |
| 832 | + db_multi_exec( | |
| 833 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" | |
| 834 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n" | |
| 835 | + " substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n" | |
| 836 | + " FROM tagxref, blob\n" | |
| 837 | + " WHERE tagxref.srcid %s AND tagxref.srcid!=tagxref.rid\n" | |
| 838 | + " AND tagxref.srcid=blob.rid;", | |
| 839 | + zWhere /*safe-for-%s*/ | |
| 840 | + ); | |
| 841 | + | |
| 842 | + /* Cluster artifacts */ | |
| 843 | + db_multi_exec( | |
| 844 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type)\n" | |
| 845 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster'\n" | |
| 846 | + " FROM tagxref, blob\n" | |
| 847 | + " WHERE tagxref.rid %s\n" | |
| 848 | + " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n" | |
| 849 | + " AND blob.rid=tagxref.rid;", | |
| 850 | + zWhere /*safe-for-%s*/ | |
| 851 | + ); | |
| 852 | + | |
| 853 | + /* Ticket change artifacts */ | |
| 854 | + db_multi_exec( | |
| 855 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" | |
| 856 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n" | |
| 857 | + " substr(tag.tagname,5)\n" | |
| 858 | + " FROM tagxref, tag, blob\n" | |
| 859 | + " WHERE tagxref.rid %s\n" | |
| 860 | + " AND tag.tagid=tagxref.tagid\n" | |
| 861 | + " AND tag.tagname GLOB 'tkt-*'" | |
| 862 | + " AND blob.rid=tagxref.rid;", | |
| 863 | + zWhere /*safe-for-%s*/ | |
| 864 | + ); | |
| 865 | + | |
| 866 | + /* Wiki edit artifacts */ | |
| 867 | + db_multi_exec( | |
| 868 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" | |
| 869 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n" | |
| 870 | + " printf('\"%%s\"',substr(tag.tagname,6))\n" | |
| 871 | + " FROM tagxref, tag, blob\n" | |
| 872 | + " WHERE tagxref.rid %s\n" | |
| 873 | + " AND tag.tagid=tagxref.tagid\n" | |
| 874 | + " AND tag.tagname GLOB 'wiki-*'" | |
| 875 | + " AND blob.rid=tagxref.rid;", | |
| 876 | + zWhere /*safe-for-%s*/ | |
| 877 | + ); | |
| 878 | + | |
| 879 | + /* Event edit artifacts */ | |
| 880 | + db_multi_exec( | |
| 881 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" | |
| 882 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n" | |
| 883 | + " substr(tag.tagname,7)\n" | |
| 884 | + " FROM tagxref, tag, blob\n" | |
| 885 | + " WHERE tagxref.rid %s\n" | |
| 886 | + " AND tag.tagid=tagxref.tagid\n" | |
| 887 | + " AND tag.tagname GLOB 'event-*'" | |
| 888 | + " AND blob.rid=tagxref.rid;", | |
| 889 | + zWhere /*safe-for-%s*/ | |
| 890 | + ); | |
| 891 | + | |
| 892 | + /* Attachments */ | |
| 893 | + db_multi_exec( | |
| 894 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" | |
| 895 | + "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n" | |
| 896 | + " attachment.filename\n" | |
| 897 | + " FROM attachment, blob\n" | |
| 898 | + " WHERE attachment.src %s\n" | |
| 899 | + " AND blob.rid=attachment.src;", | |
| 900 | + zWhere /*safe-for-%s*/ | |
| 901 | + ); | |
| 902 | + | |
| 903 | + /* Everything else */ | |
| 904 | + db_multi_exec( | |
| 905 | + "INSERT OR IGNORE INTO description(rid,uuid,type)\n" | |
| 906 | + "SELECT blob.rid, blob.uuid, 'unknown'\n" | |
| 907 | + " FROM blob WHERE blob.rid %s;", | |
| 908 | + zWhere /*safe-for-%s*/ | |
| 909 | + ); | |
| 910 | +} | |
| 911 | + | |
| 912 | +/* | |
| 913 | +** COMMAND: test-describe-artifacts | |
| 914 | +** | |
| 915 | +** Usage: %fossil test-describe-artifacts | |
| 916 | +** | |
| 917 | +** Display a one-line description of every artifact. | |
| 918 | +*/ | |
| 919 | +void test_describe_artifacts_cmd(void){ | |
| 920 | + Stmt q; | |
| 921 | + db_find_and_open_repository(0,0); | |
| 922 | + describe_artifacts("IN (SELECT rid FROM blob)"); | |
| 923 | + db_prepare(&q, | |
| 924 | + "SELECT rid, uuid, datetime(ctime,'localtime'), type, detail\n" | |
| 925 | + " FROM description\n" | |
| 926 | + " ORDER BY rid;" | |
| 927 | + ); | |
| 928 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 929 | + const char *zType = db_column_text(&q,3); | |
| 930 | + fossil_print("%6d %.16s %s", db_column_int(&q,0), | |
| 931 | + db_column_text(&q,1), db_column_text(&q,3)); | |
| 932 | + if( db_column_bytes(&q,4)>0 ){ | |
| 933 | + fossil_print(" %s", db_column_text(&q,4)); | |
| 934 | + } | |
| 935 | + if( db_column_bytes(&q,2)>0 | |
| 936 | + && fossil_strcmp(zType,"file")!=0 | |
| 937 | + && fossil_strcmp(zType,"ticket")!=0 | |
| 938 | + && fossil_strcmp(zType,"event")!=0 | |
| 939 | + ){ | |
| 940 | + fossil_print(" %s", db_column_text(&q,2)); | |
| 941 | + } | |
| 942 | + fossil_print("\n"); | |
| 943 | + } | |
| 944 | + db_finalize(&q); | |
| 945 | +} | |
| 784 | 946 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -779,5 +779,167 @@ | |
| 779 | while( db_step(&q)==SQLITE_ROW ){ |
| 780 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 781 | } |
| 782 | db_finalize(&q); |
| 783 | } |
| 784 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -779,5 +779,167 @@ | |
| 779 | while( db_step(&q)==SQLITE_ROW ){ |
| 780 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 781 | } |
| 782 | db_finalize(&q); |
| 783 | } |
| 784 | |
| 785 | /* |
| 786 | ** Schema for the description table |
| 787 | */ |
| 788 | static const char zDescTab[] = |
| 789 | @ CREATE TEMP TABLE IF NOT EXISTS description( |
| 790 | @ rid INTEGER PRIMARY KEY, |
| 791 | @ uuid TEXT, -- SHA1 hash of the object |
| 792 | @ ctime DATETIME, -- Time of creation |
| 793 | @ type TEXT, -- file, checkin, wiki, ticket-change, etc. |
| 794 | @ detail TEXT -- filename, checkin comment, etc |
| 795 | @ ); |
| 796 | ; |
| 797 | |
| 798 | /* |
| 799 | ** Create the description table if it does not already exists. |
| 800 | ** Populate fields of this table with descriptions for all artifacts |
| 801 | ** whose RID matches the SQL expression in zWhere. |
| 802 | */ |
| 803 | void describe_artifacts(const char *zWhere){ |
| 804 | Stmt q; |
| 805 | Stmt ins; |
| 806 | |
| 807 | db_multi_exec("%s", zDescTab/*safe-for-%s*/); |
| 808 | |
| 809 | /* Describe checkins */ |
| 810 | db_multi_exec( |
| 811 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type)\n" |
| 812 | "SELECT blob.rid, blob.uuid, event.mtime, 'checkin'\n" |
| 813 | " FROM event, blob\n" |
| 814 | " WHERE event.objid %s AND event.type='ci'\n" |
| 815 | " AND event.objid=blob.rid;", |
| 816 | zWhere /*safe-for-%s*/ |
| 817 | ); |
| 818 | |
| 819 | /* Describe files */ |
| 820 | db_multi_exec( |
| 821 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" |
| 822 | "SELECT blob.rid, blob.uuid, event.mtime, 'file', filename.name\n" |
| 823 | " FROM mlink, blob, event, filename\n" |
| 824 | " WHERE mlink.fid %s\n" |
| 825 | " AND mlink.mid=event.objid\n" |
| 826 | " AND filename.fnid=mlink.fnid\n" |
| 827 | " AND mlink.fid=blob.rid;", |
| 828 | zWhere /*safe-for-%s*/ |
| 829 | ); |
| 830 | |
| 831 | /* Describe tags */ |
| 832 | db_multi_exec( |
| 833 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" |
| 834 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n" |
| 835 | " substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n" |
| 836 | " FROM tagxref, blob\n" |
| 837 | " WHERE tagxref.srcid %s AND tagxref.srcid!=tagxref.rid\n" |
| 838 | " AND tagxref.srcid=blob.rid;", |
| 839 | zWhere /*safe-for-%s*/ |
| 840 | ); |
| 841 | |
| 842 | /* Cluster artifacts */ |
| 843 | db_multi_exec( |
| 844 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type)\n" |
| 845 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster'\n" |
| 846 | " FROM tagxref, blob\n" |
| 847 | " WHERE tagxref.rid %s\n" |
| 848 | " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n" |
| 849 | " AND blob.rid=tagxref.rid;", |
| 850 | zWhere /*safe-for-%s*/ |
| 851 | ); |
| 852 | |
| 853 | /* Ticket change artifacts */ |
| 854 | db_multi_exec( |
| 855 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" |
| 856 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n" |
| 857 | " substr(tag.tagname,5)\n" |
| 858 | " FROM tagxref, tag, blob\n" |
| 859 | " WHERE tagxref.rid %s\n" |
| 860 | " AND tag.tagid=tagxref.tagid\n" |
| 861 | " AND tag.tagname GLOB 'tkt-*'" |
| 862 | " AND blob.rid=tagxref.rid;", |
| 863 | zWhere /*safe-for-%s*/ |
| 864 | ); |
| 865 | |
| 866 | /* Wiki edit artifacts */ |
| 867 | db_multi_exec( |
| 868 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" |
| 869 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n" |
| 870 | " printf('\"%%s\"',substr(tag.tagname,6))\n" |
| 871 | " FROM tagxref, tag, blob\n" |
| 872 | " WHERE tagxref.rid %s\n" |
| 873 | " AND tag.tagid=tagxref.tagid\n" |
| 874 | " AND tag.tagname GLOB 'wiki-*'" |
| 875 | " AND blob.rid=tagxref.rid;", |
| 876 | zWhere /*safe-for-%s*/ |
| 877 | ); |
| 878 | |
| 879 | /* Event edit artifacts */ |
| 880 | db_multi_exec( |
| 881 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" |
| 882 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n" |
| 883 | " substr(tag.tagname,7)\n" |
| 884 | " FROM tagxref, tag, blob\n" |
| 885 | " WHERE tagxref.rid %s\n" |
| 886 | " AND tag.tagid=tagxref.tagid\n" |
| 887 | " AND tag.tagname GLOB 'event-*'" |
| 888 | " AND blob.rid=tagxref.rid;", |
| 889 | zWhere /*safe-for-%s*/ |
| 890 | ); |
| 891 | |
| 892 | /* Attachments */ |
| 893 | db_multi_exec( |
| 894 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" |
| 895 | "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n" |
| 896 | " attachment.filename\n" |
| 897 | " FROM attachment, blob\n" |
| 898 | " WHERE attachment.src %s\n" |
| 899 | " AND blob.rid=attachment.src;", |
| 900 | zWhere /*safe-for-%s*/ |
| 901 | ); |
| 902 | |
| 903 | /* Everything else */ |
| 904 | db_multi_exec( |
| 905 | "INSERT OR IGNORE INTO description(rid,uuid,type)\n" |
| 906 | "SELECT blob.rid, blob.uuid, 'unknown'\n" |
| 907 | " FROM blob WHERE blob.rid %s;", |
| 908 | zWhere /*safe-for-%s*/ |
| 909 | ); |
| 910 | } |
| 911 | |
| 912 | /* |
| 913 | ** COMMAND: test-describe-artifacts |
| 914 | ** |
| 915 | ** Usage: %fossil test-describe-artifacts |
| 916 | ** |
| 917 | ** Display a one-line description of every artifact. |
| 918 | */ |
| 919 | void test_describe_artifacts_cmd(void){ |
| 920 | Stmt q; |
| 921 | db_find_and_open_repository(0,0); |
| 922 | describe_artifacts("IN (SELECT rid FROM blob)"); |
| 923 | db_prepare(&q, |
| 924 | "SELECT rid, uuid, datetime(ctime,'localtime'), type, detail\n" |
| 925 | " FROM description\n" |
| 926 | " ORDER BY rid;" |
| 927 | ); |
| 928 | while( db_step(&q)==SQLITE_ROW ){ |
| 929 | const char *zType = db_column_text(&q,3); |
| 930 | fossil_print("%6d %.16s %s", db_column_int(&q,0), |
| 931 | db_column_text(&q,1), db_column_text(&q,3)); |
| 932 | if( db_column_bytes(&q,4)>0 ){ |
| 933 | fossil_print(" %s", db_column_text(&q,4)); |
| 934 | } |
| 935 | if( db_column_bytes(&q,2)>0 |
| 936 | && fossil_strcmp(zType,"file")!=0 |
| 937 | && fossil_strcmp(zType,"ticket")!=0 |
| 938 | && fossil_strcmp(zType,"event")!=0 |
| 939 | ){ |
| 940 | fossil_print(" %s", db_column_text(&q,2)); |
| 941 | } |
| 942 | fossil_print("\n"); |
| 943 | } |
| 944 | db_finalize(&q); |
| 945 | } |
| 946 |