]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add globbing option to shell's .archive command.
authorlarrybr <larrybr@noemail.net>
Tue, 2 Nov 2021 00:18:11 +0000 (00:18 +0000)
committerlarrybr <larrybr@noemail.net>
Tue, 2 Nov 2021 00:18:11 +0000 (00:18 +0000)
FossilOrigin-Name: 13fb74ac5e7578ab612af2ccc8147569d60dc35af84f496bcc5d648d223d6d6e

manifest
manifest.uuid
src/shell.c.in
test/shell8.test

index 8a34c1b3566faf0e67566b28205482ce123e38be..3b473a0943ca9dc3b6436c8472fc48a8fc71e363 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C zap\strailing\swhitespace
-D 2021-11-01T22:33:20.802
+C Add\sglobbing\soption\sto\sshell's\s.archive\scommand.
+D 2021-11-02T00:18:11.885
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -550,7 +550,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
 F src/resolve.c ae65c88f5d0d4bc0052b203773d407efa2387c2bd6b202f87178006c7bb8632c
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c 32d25b5af6c708aa63373c78c2e59681910387a7a78c08ec3086cadc77d41627
-F src/shell.c.in 74dc1a088b1840b89615e99da33c3419f2808ce213f809006accce890c1ed99b
+F src/shell.c.in 9e3b9543d26a0c3eef9ad0408d4cd78bff5e2af57820d11617a5c1e8c8ab984d
 F src/sqlite.h.in 99786216caf1c57aa3d70f95a7f84566dff6a9eeb50174799ea3b387eafd2a22
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h d8f6f67ae9ad990a70dd03c093bcdc8883e159ff4bfd16a496f8fb80c6840b5a
@@ -1384,7 +1384,7 @@ F test/shell4.test 3ed6c4b42fd695efcbc25d69ef759dbb15855ca8e52ba6c5ee076f8b435f4
 F test/shell5.test 6e4aa0e531dcb8dcf74b7920a2a7442c6712d4dff8422bbc81f768f9dee8a0e3
 F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
-F test/shell8.test b109236471b68749b0dd23d075626373397e609562a3f4c49548a4c971ef105b
+F test/shell8.test 388471d16e4de767333107e30653983f186232c0e863f4490bb230419e830aae
 F test/shmlock.test 3dbf017d34ab0c60abe6a44e447d3552154bd0c87b41eaf5ceacd408dd13fda5
 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
@@ -1930,7 +1930,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 978d5ed4379b631a79cd46a75d9b5b403f3ec4ce7d9d52ed36a5678cdf04f7f2
-R aa5d515bd539d5a906c526319f66022b
+P f2a908e9c86efb11bb179ce7121f0d510f952284891abfa69517b773fd88324c
+R eecc379f0265e2d49eed240d5e55a92c
 U larrybr
-Z 19de7df3053f6a11c3c0364e259c1387
+Z d62c3b222b587fc248ac413fb1d62a07
index e1377c55acb8d385ef54a5d3e9294a52d6daefc0..999bb1d766d02a94d8dea98f1242c8fb06d9e17b 100644 (file)
@@ -1 +1 @@
-f2a908e9c86efb11bb179ce7121f0d510f952284891abfa69517b773fd88324c
\ No newline at end of file
+13fb74ac5e7578ab612af2ccc8147569d60dc35af84f496bcc5d648d223d6d6e
\ No newline at end of file
index ee601b846c3d09dcac13927312ecbdb1c70d16b6..67c46981fa02baced438e58fc62e87bfa7645635 100644 (file)
@@ -3973,6 +3973,7 @@ static const char *(azHelp[]) = {
   "     -f FILE, --file FILE       Use archive FILE (default is current db)",
   "     -a FILE, --append FILE     Open FILE using the apndvfs VFS",
   "     -C DIR, --directory DIR    Read/extract files from directory DIR",
+  "     -g, --glob                 Use glob matching for names in archive",
   "     -n, --dryrun               Show the SQL that would have occurred",
   "   Examples:",
   "     .ar -cf ARCHIVE foo bar  # Create ARCHIVE from files foo and bar",
@@ -6133,6 +6134,7 @@ struct ArCommand {
   u8 bZip;                        /* True if the archive is a ZIP */
   u8 bDryRun;                     /* True if --dry-run */
   u8 bAppend;                     /* True if --append */
+  u8 bGlob;                       /* True if --glob */
   u8 fromCmdLine;                 /* Run from -A instead of .archive */
   int nArg;                       /* Number of command arguments */
   char *zSrcTable;                /* "sqlar", "zipfile($file)" or "zip" */
@@ -6190,6 +6192,7 @@ static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
 #define AR_SWITCH_DIRECTORY  10
 #define AR_SWITCH_APPEND     11
 #define AR_SWITCH_DRYRUN     12
+#define AR_SWITCH_GLOB       13
 
 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
   switch( eSwitch ){
@@ -6209,6 +6212,9 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
     case AR_SWITCH_DRYRUN:
       pAr->bDryRun = 1;
       break;
+    case AR_SWITCH_GLOB:
+      pAr->bGlob = 1;
+      break;
     case AR_SWITCH_VERBOSE:
       pAr->bVerbose = 1;
       break;
@@ -6255,6 +6261,7 @@ static int arParseCommand(
     { "append",    'a', AR_SWITCH_APPEND,    1 },
     { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
     { "dryrun",    'n', AR_SWITCH_DRYRUN,    0 },
+    { "glob",      'g', AR_SWITCH_GLOB,      0 },
   };
   int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
   struct ArSwitch *pEnd = &aSwitch[nSwitch];
@@ -6372,10 +6379,12 @@ static int arParseCommand(
 /*
 ** This function assumes that all arguments within the ArCommand.azArg[]
 ** array refer to archive members, as for the --extract, --list or --remove
-** commands. It checks that each of them are present. If any specified file
-** is not present in the archive, an error is printed to stderr and an
+** commands. It checks that each of them are "present". If any specified
+** file is not present in the archive, an error is printed to stderr and an
 ** error code returned. Otherwise, if all specified arguments are present
-** in the archive, SQLITE_OK is returned.
+** in the archive, SQLITE_OK is returned. Here, "present" means either an
+** exact equality when pAr->bGlob is false or a "name GLOB pattern" match
+*  when pAr->bGlob is true.
 **
 ** This function strips any trailing '/' characters from each argument.
 ** This is consistent with the way the [tar] command seems to work on
@@ -6386,11 +6395,11 @@ static int arCheckEntries(ArCommand *pAr){
   if( pAr->nArg ){
     int i, j;
     sqlite3_stmt *pTest = 0;
+    const char *zSel = (pAr->bGlob)
+      ? "SELECT name FROM %s WHERE glob($name,name)"
+      : "SELECT name FROM %s WHERE name=$name";
 
-    shellPreparePrintf(pAr->db, &rc, &pTest,
-        "SELECT name FROM %s WHERE name=$name", 
-        pAr->zSrcTable
-    );
+    shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable);
     j = sqlite3_bind_parameter_index(pTest, "$name");
     for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
       char *z = pAr->azArg[i];
@@ -6418,14 +6427,16 @@ static int arCheckEntries(ArCommand *pAr){
 ** identify all archive members that match the command arguments held
 ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
 ** The caller is responsible for eventually calling sqlite3_free() on
-** any non-NULL (*pzWhere) value.
+** any non-NULL (*pzWhere) value. Here, "match" means strict equality
+** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
 */
 static void arWhereClause(
   int *pRc, 
-  ArCommand *pAr, 
+  ArCommand *pAr,
   char **pzWhere                  /* OUT: New WHERE clause */
 ){
   char *zWhere = 0;
+  const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
   if( *pRc==SQLITE_OK ){
     if( pAr->nArg==0 ){
       zWhere = sqlite3_mprintf("1");
@@ -6435,8 +6446,8 @@ static void arWhereClause(
       for(i=0; i<pAr->nArg; i++){
         const char *z = pAr->azArg[i];
         zWhere = sqlite3_mprintf(
-          "%z%s name = '%q' OR substr(name,1,%d) = '%q/'", 
-          zWhere, zSep, z, strlen30(z)+1, z
+          "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'", 
+          zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
         );
         if( zWhere==0 ){
           *pRc = SQLITE_NOMEM;
index 8d9fa0f6b97b9b4739b676b9af0e9e02cf9154bc..ddb4a47b82dcd40f4deafc00092f25039d23762f 100644 (file)
@@ -178,6 +178,8 @@ do_test 2.1.1 {
   populate_dir ar2 {
     file1 "abcd" 
     file2 "efgh"
+    junk1 "j1"
+    junk2 "j2"
     dir1/file3 "ijkl"
   }
   populate_dir ar4 {
@@ -186,8 +188,9 @@ do_test 2.1.1 {
   catchcmd shell8.db {.ar -c}
   catchcmd shell8.db {.ar -C ar2 -i .}
   catchcmd shell8.db {.ar -r ./file2 ./dir1}
+  catchcmd shell8.db {.ar -g -r ./ju*2}
   catchcmd shell8.db {.ar -C ar4 -x .}
   regsub -all {ar4} [dir_content ar4] ar2
-} {ar2/file1 ar2/file2}
+} {ar2/file1 ar2/file2 ar2/junk1}
 
 finish_test