Fossil SCM
Change the bundle on-disk format slightly. Add the "bundle ls" command.
Commit
b2a56a76d55c99860a1ed4dba0440f939fd2b178
Parent
8a57413e825ee1b…
1 file changed
+35
-6
+35
-6
| --- src/bundle.c | ||
| +++ src/bundle.c | ||
| @@ -21,10 +21,16 @@ | ||
| 21 | 21 | #include "bundle.h" |
| 22 | 22 | #include <assert.h> |
| 23 | 23 | |
| 24 | 24 | /* |
| 25 | 25 | ** SQL code used to initialize the schema of a bundle. |
| 26 | +** | |
| 27 | +** The bblob.delta field can be an integer, a text string, or NULL. | |
| 28 | +** If an integer, then the corresponding blobid is the delta basis. | |
| 29 | +** If a text string, then that string is a SHA1 hash for the delta | |
| 30 | +** basis, which is presumably in the master repository. If NULL, then | |
| 31 | +** data contains contain without delta compression. | |
| 26 | 32 | */ |
| 27 | 33 | static const char zBundleInit[] = |
| 28 | 34 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig( |
| 29 | 35 | @ bcname TEXT, |
| 30 | 36 | @ bcvalue ANY |
| @@ -31,11 +37,11 @@ | ||
| 31 | 37 | @ ); |
| 32 | 38 | @ CREATE TABLE IF NOT EXISTS "%w".bblob( |
| 33 | 39 | @ blobid INTEGER PRIMARY KEY, -- Blob ID |
| 34 | 40 | @ uuid TEXT NOT NULL, -- SHA1 hash of expanded blob |
| 35 | 41 | @ sz INT NOT NULL, -- Size of blob after expansion |
| 36 | -@ delta INT REFERENCES bblob, -- Delta compression basis, or NULL | |
| 42 | +@ delta ANY, -- Delta compression basis, or NULL | |
| 37 | 43 | @ data BLOB -- compressed content |
| 38 | 44 | @ ); |
| 39 | 45 | ; |
| 40 | 46 | |
| 41 | 47 | /* |
| @@ -50,26 +56,51 @@ | ||
| 50 | 56 | db_multi_exec("ATTACH %Q AS %Q;", zFile, zBName); |
| 51 | 57 | db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); |
| 52 | 58 | } |
| 53 | 59 | |
| 54 | 60 | /* |
| 55 | -** List the content of a bundle | |
| 61 | +** fossil bundle ls BUNDLE ?OPTIONS? | |
| 62 | +** | |
| 63 | +** Display the content of a bundle in human-readable form. | |
| 56 | 64 | */ |
| 57 | 65 | static void bundle_ls(void){ |
| 58 | - | |
| 66 | + Stmt q; | |
| 67 | + sqlite3_int64 sumSz = 0; | |
| 68 | + sqlite3_int64 sumLen = 0; | |
| 69 | + bundle_attach_file(g.argv[3], "b1", 0); | |
| 70 | + db_prepare(&q, | |
| 71 | + "SELECT blobid, substr(uuid,1,16), coalesce(substr(delta,1,16),'')," | |
| 72 | + " sz, length(data)" | |
| 73 | + " FROM bblob" | |
| 74 | + ); | |
| 75 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 76 | + fossil_print("%4d %16s %16s %10d %10d\n", | |
| 77 | + db_column_int(&q,0), | |
| 78 | + db_column_text(&q,1), | |
| 79 | + db_column_text(&q,2), | |
| 80 | + db_column_int(&q,3), | |
| 81 | + db_column_int(&q,4)); | |
| 82 | + sumSz += db_column_int(&q,3); | |
| 83 | + sumLen += db_column_int(&q,4); | |
| 84 | + } | |
| 85 | + db_finalize(&q); | |
| 86 | + fossil_print("%38s %10lld %10lld\n", "Total:", sumSz, sumLen); | |
| 59 | 87 | } |
| 60 | 88 | |
| 61 | 89 | /* |
| 62 | -** Implement the "fossil bundle append BUNDLE FILE..." command. | |
| 90 | +** Implement the "fossil bundle append BUNDLE FILE..." command. Add | |
| 91 | +** the named files into the BUNDLE. Create the BUNDLE if it does not | |
| 92 | +** alraedy exist. | |
| 63 | 93 | */ |
| 64 | 94 | static void bundle_append(void){ |
| 65 | 95 | char *zFilename; |
| 66 | 96 | Blob content, hash; |
| 67 | 97 | int i; |
| 68 | 98 | Stmt q; |
| 69 | 99 | |
| 70 | 100 | verify_all_options(); |
| 101 | + bundle_attach_file(g.argv[3], "b1", 1); | |
| 71 | 102 | db_prepare(&q, |
| 72 | 103 | "INSERT INTO bblob(blobid, uuid, sz, delta, data) " |
| 73 | 104 | "VALUES(NULL, $uuid, $sz, NULL, $data)"); |
| 74 | 105 | db_begin_transaction(); |
| 75 | 106 | for(i=4; i<g.argc; i++){ |
| @@ -254,12 +285,10 @@ | ||
| 254 | 285 | const char *zBundleFile; |
| 255 | 286 | int n; |
| 256 | 287 | if( g.argc<4 ) usage("SUBCOMMAND BUNDLE ?ARGUMENTS?"); |
| 257 | 288 | zSubcmd = g.argv[2]; |
| 258 | 289 | db_find_and_open_repository(0,0); |
| 259 | - zBundleFile = g.argv[3]; | |
| 260 | - bundle_attach_file(zBundleFile, "b1", 1); | |
| 261 | 290 | n = (int)strlen(zSubcmd); |
| 262 | 291 | if( strncmp(zSubcmd, "export", n)==0 ){ |
| 263 | 292 | fossil_print("Not yet implemented...\n"); |
| 264 | 293 | }else if( strncmp(zSubcmd, "import", n)==0 ){ |
| 265 | 294 | fossil_print("Not yet implemented...\n"); |
| 266 | 295 |
| --- src/bundle.c | |
| +++ src/bundle.c | |
| @@ -21,10 +21,16 @@ | |
| 21 | #include "bundle.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** SQL code used to initialize the schema of a bundle. |
| 26 | */ |
| 27 | static const char zBundleInit[] = |
| 28 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig( |
| 29 | @ bcname TEXT, |
| 30 | @ bcvalue ANY |
| @@ -31,11 +37,11 @@ | |
| 31 | @ ); |
| 32 | @ CREATE TABLE IF NOT EXISTS "%w".bblob( |
| 33 | @ blobid INTEGER PRIMARY KEY, -- Blob ID |
| 34 | @ uuid TEXT NOT NULL, -- SHA1 hash of expanded blob |
| 35 | @ sz INT NOT NULL, -- Size of blob after expansion |
| 36 | @ delta INT REFERENCES bblob, -- Delta compression basis, or NULL |
| 37 | @ data BLOB -- compressed content |
| 38 | @ ); |
| 39 | ; |
| 40 | |
| 41 | /* |
| @@ -50,26 +56,51 @@ | |
| 50 | db_multi_exec("ATTACH %Q AS %Q;", zFile, zBName); |
| 51 | db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); |
| 52 | } |
| 53 | |
| 54 | /* |
| 55 | ** List the content of a bundle |
| 56 | */ |
| 57 | static void bundle_ls(void){ |
| 58 | |
| 59 | } |
| 60 | |
| 61 | /* |
| 62 | ** Implement the "fossil bundle append BUNDLE FILE..." command. |
| 63 | */ |
| 64 | static void bundle_append(void){ |
| 65 | char *zFilename; |
| 66 | Blob content, hash; |
| 67 | int i; |
| 68 | Stmt q; |
| 69 | |
| 70 | verify_all_options(); |
| 71 | db_prepare(&q, |
| 72 | "INSERT INTO bblob(blobid, uuid, sz, delta, data) " |
| 73 | "VALUES(NULL, $uuid, $sz, NULL, $data)"); |
| 74 | db_begin_transaction(); |
| 75 | for(i=4; i<g.argc; i++){ |
| @@ -254,12 +285,10 @@ | |
| 254 | const char *zBundleFile; |
| 255 | int n; |
| 256 | if( g.argc<4 ) usage("SUBCOMMAND BUNDLE ?ARGUMENTS?"); |
| 257 | zSubcmd = g.argv[2]; |
| 258 | db_find_and_open_repository(0,0); |
| 259 | zBundleFile = g.argv[3]; |
| 260 | bundle_attach_file(zBundleFile, "b1", 1); |
| 261 | n = (int)strlen(zSubcmd); |
| 262 | if( strncmp(zSubcmd, "export", n)==0 ){ |
| 263 | fossil_print("Not yet implemented...\n"); |
| 264 | }else if( strncmp(zSubcmd, "import", n)==0 ){ |
| 265 | fossil_print("Not yet implemented...\n"); |
| 266 |
| --- src/bundle.c | |
| +++ src/bundle.c | |
| @@ -21,10 +21,16 @@ | |
| 21 | #include "bundle.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** SQL code used to initialize the schema of a bundle. |
| 26 | ** |
| 27 | ** The bblob.delta field can be an integer, a text string, or NULL. |
| 28 | ** If an integer, then the corresponding blobid is the delta basis. |
| 29 | ** If a text string, then that string is a SHA1 hash for the delta |
| 30 | ** basis, which is presumably in the master repository. If NULL, then |
| 31 | ** data contains contain without delta compression. |
| 32 | */ |
| 33 | static const char zBundleInit[] = |
| 34 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig( |
| 35 | @ bcname TEXT, |
| 36 | @ bcvalue ANY |
| @@ -31,11 +37,11 @@ | |
| 37 | @ ); |
| 38 | @ CREATE TABLE IF NOT EXISTS "%w".bblob( |
| 39 | @ blobid INTEGER PRIMARY KEY, -- Blob ID |
| 40 | @ uuid TEXT NOT NULL, -- SHA1 hash of expanded blob |
| 41 | @ sz INT NOT NULL, -- Size of blob after expansion |
| 42 | @ delta ANY, -- Delta compression basis, or NULL |
| 43 | @ data BLOB -- compressed content |
| 44 | @ ); |
| 45 | ; |
| 46 | |
| 47 | /* |
| @@ -50,26 +56,51 @@ | |
| 56 | db_multi_exec("ATTACH %Q AS %Q;", zFile, zBName); |
| 57 | db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); |
| 58 | } |
| 59 | |
| 60 | /* |
| 61 | ** fossil bundle ls BUNDLE ?OPTIONS? |
| 62 | ** |
| 63 | ** Display the content of a bundle in human-readable form. |
| 64 | */ |
| 65 | static void bundle_ls(void){ |
| 66 | Stmt q; |
| 67 | sqlite3_int64 sumSz = 0; |
| 68 | sqlite3_int64 sumLen = 0; |
| 69 | bundle_attach_file(g.argv[3], "b1", 0); |
| 70 | db_prepare(&q, |
| 71 | "SELECT blobid, substr(uuid,1,16), coalesce(substr(delta,1,16),'')," |
| 72 | " sz, length(data)" |
| 73 | " FROM bblob" |
| 74 | ); |
| 75 | while( db_step(&q)==SQLITE_ROW ){ |
| 76 | fossil_print("%4d %16s %16s %10d %10d\n", |
| 77 | db_column_int(&q,0), |
| 78 | db_column_text(&q,1), |
| 79 | db_column_text(&q,2), |
| 80 | db_column_int(&q,3), |
| 81 | db_column_int(&q,4)); |
| 82 | sumSz += db_column_int(&q,3); |
| 83 | sumLen += db_column_int(&q,4); |
| 84 | } |
| 85 | db_finalize(&q); |
| 86 | fossil_print("%38s %10lld %10lld\n", "Total:", sumSz, sumLen); |
| 87 | } |
| 88 | |
| 89 | /* |
| 90 | ** Implement the "fossil bundle append BUNDLE FILE..." command. Add |
| 91 | ** the named files into the BUNDLE. Create the BUNDLE if it does not |
| 92 | ** alraedy exist. |
| 93 | */ |
| 94 | static void bundle_append(void){ |
| 95 | char *zFilename; |
| 96 | Blob content, hash; |
| 97 | int i; |
| 98 | Stmt q; |
| 99 | |
| 100 | verify_all_options(); |
| 101 | bundle_attach_file(g.argv[3], "b1", 1); |
| 102 | db_prepare(&q, |
| 103 | "INSERT INTO bblob(blobid, uuid, sz, delta, data) " |
| 104 | "VALUES(NULL, $uuid, $sz, NULL, $data)"); |
| 105 | db_begin_transaction(); |
| 106 | for(i=4; i<g.argc; i++){ |
| @@ -254,12 +285,10 @@ | |
| 285 | const char *zBundleFile; |
| 286 | int n; |
| 287 | if( g.argc<4 ) usage("SUBCOMMAND BUNDLE ?ARGUMENTS?"); |
| 288 | zSubcmd = g.argv[2]; |
| 289 | db_find_and_open_repository(0,0); |
| 290 | n = (int)strlen(zSubcmd); |
| 291 | if( strncmp(zSubcmd, "export", n)==0 ){ |
| 292 | fossil_print("Not yet implemented...\n"); |
| 293 | }else if( strncmp(zSubcmd, "import", n)==0 ){ |
| 294 | fossil_print("Not yet implemented...\n"); |
| 295 |