From: larrybr Date: Tue, 2 Nov 2021 00:18:11 +0000 (+0000) Subject: Add globbing option to shell's .archive command. X-Git-Tag: version-3.37.0~73^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8f09f4b264c68573cd5773b679fcf954b3142513;p=thirdparty%2Fsqlite.git Add globbing option to shell's .archive command. FossilOrigin-Name: 13fb74ac5e7578ab612af2ccc8147569d60dc35af84f496bcc5d648d223d6d6e --- diff --git a/manifest b/manifest index 8a34c1b356..3b473a0943 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index e1377c55ac..999bb1d766 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2a908e9c86efb11bb179ce7121f0d510f952284891abfa69517b773fd88324c \ No newline at end of file +13fb74ac5e7578ab612af2ccc8147569d60dc35af84f496bcc5d648d223d6d6e \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index ee601b846c..67c46981fa 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -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; inArg && 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; inArg; 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; diff --git a/test/shell8.test b/test/shell8.test index 8d9fa0f6b9..ddb4a47b82 100644 --- a/test/shell8.test +++ b/test/shell8.test @@ -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