]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
For the ".archive --update" command in the CLI, only update files if their
authordrh <drh@noemail.net>
Mon, 25 Mar 2019 14:24:19 +0000 (14:24 +0000)
committerdrh <drh@noemail.net>
Mon, 25 Mar 2019 14:24:19 +0000 (14:24 +0000)
mtime or mode has changed.  To force an update, use the new --insert instead.

FossilOrigin-Name: 191a023ae708490eca61b3a42a3df41bb6709079f3905881abb82ebd46182607

manifest
manifest.uuid
src/shell.c.in

index 96ae5513c274de13a2c55445938601a9bbe1f536..ea0eb78148b9381464a53bfba8625ee5cd31644f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C We\slearn\sthat\sreaddir_r()\sis\sdeprecated\sin\sfavor\sof\splain\sold\sreaddir(),\swhich\nis\snow\ssuppose\sto\sbe\sthreadsafe\susing\sthread-local\sstorage.\s\sSo\sremove\sthe\nuse\sof\sreaddir_r()\sfrom\sthe\stest\scode.\s\s(SQLite\sitself\snever\scalls\sreaddir()\nor\sreaddir_r()).
-D 2019-03-22T13:53:25.635
+C For\sthe\s".archive\s--update"\scommand\sin\sthe\sCLI,\sonly\supdate\sfiles\sif\stheir\nmtime\sor\smode\shas\schanged.\s\sTo\sforce\san\supdate,\suse\sthe\snew\s--insert\sinstead.
+D 2019-03-25T14:24:19.101
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -517,7 +517,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 09419ad5c432190b69be7c0c326e03abb548a97c2c50675b81b459e1b382d1d2
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49
-F src/shell.c.in 576ba793cf166ea7055b7a1a2bea058242ca532ba84753e789b9c88790019b70
+F src/shell.c.in 652ba411c798b64a0c71079e16b022b6cd530a4c1161e220e4cd8a0a127dba60
 F src/sqlite.h.in e33a4df7e32d742aac29623b38a1edd7e07a2b964a5d0257e2923c8a724faddc
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
@@ -1807,7 +1807,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 b99f8512c06b9d47e48b028781265512ce8b812ae4e6af0a7139a093cf9a8f74
-R 721d1f8fcb0f28693679b1b90e33dd94
+P 7a0a26ed380dd0bdda50b0204b30b53bbbbc70f278eba02f91541ac6c691aef2
+R e5d0aae7927eed4a86cf78b0bf846424
 U drh
-Z 1ebe3d96da2eb6b085008de1980229a2
+Z 1d4ed68130e2fc4467c4c956c87b0a62
index 2611c359a058dfe5f340b4b5e2e1ecaa60898a27..1994a593521981defd91c5c0969a890f5ceeef04 100644 (file)
@@ -1 +1 @@
-7a0a26ed380dd0bdda50b0204b30b53bbbbc70f278eba02f91541ac6c691aef2
\ No newline at end of file
+191a023ae708490eca61b3a42a3df41bb6709079f3905881abb82ebd46182607
\ No newline at end of file
index 007d9bb0bee243f293cb3a23293fc3603c04cc09..c8fd3ae889d799b91a49c836e7983096da2397a4 100644 (file)
@@ -3452,7 +3452,8 @@ static const char *(azHelp[]) = {
   ".archive ...             Manage SQL archives",
   "   Each command must have exactly one of the following options:",
   "     -c, --create               Create a new archive",
-  "     -u, --update               Update or add files to an existing archive",
+  "     -u, --update               Add files or update files with newer mtime",
+  "     -i, --insert               Like -u but always add even if mtime unchanged",
   "     -t, --list                 List contents of archive",
   "     -x, --extract              Extract files from archive",
   "   Optional arguments:",
@@ -5387,19 +5388,20 @@ static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
 ** Values for ArCommand.eCmd.
 */
 #define AR_CMD_CREATE       1
-#define AR_CMD_EXTRACT      2
-#define AR_CMD_LIST         3
-#define AR_CMD_UPDATE       4
-#define AR_CMD_HELP         5
+#define AR_CMD_UPDATE       2
+#define AR_CMD_INSERT       3
+#define AR_CMD_EXTRACT      4
+#define AR_CMD_LIST         5
+#define AR_CMD_HELP         6
 
 /*
 ** Other (non-command) switches.
 */
-#define AR_SWITCH_VERBOSE     6
-#define AR_SWITCH_FILE        7
-#define AR_SWITCH_DIRECTORY   8
-#define AR_SWITCH_APPEND      9
-#define AR_SWITCH_DRYRUN     10
+#define AR_SWITCH_VERBOSE     7
+#define AR_SWITCH_FILE        8
+#define AR_SWITCH_DIRECTORY   9
+#define AR_SWITCH_APPEND     10
+#define AR_SWITCH_DRYRUN     11
 
 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
   switch( eSwitch ){
@@ -5407,6 +5409,7 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
     case AR_CMD_EXTRACT:
     case AR_CMD_LIST:
     case AR_CMD_UPDATE:
+    case AR_CMD_INSERT:
     case AR_CMD_HELP:
       if( pAr->eCmd ){
         return arErrorMsg(pAr, "multiple command options");
@@ -5453,6 +5456,7 @@ static int arParseCommand(
   } aSwitch[] = {
     { "create",    'c', AR_CMD_CREATE,       0 },
     { "extract",   'x', AR_CMD_EXTRACT,      0 },
+    { "insert",    'i', AR_CMD_INSERT,       0 },
     { "list",      't', AR_CMD_LIST,         0 },
     { "update",    'u', AR_CMD_UPDATE,       0 },
     { "help",      'h', AR_CMD_HELP,         0 },
@@ -5788,7 +5792,12 @@ static int arExecSql(ArCommand *pAr, const char *zSql){
 
 
 /*
-** Implementation of .ar "create" and "update" commands.
+** Implementation of .ar "create", "insert", and "update" commands.
+**
+**     create    ->     Create a new SQL archive
+**     insert    ->     Insert or reinsert all files listed
+**     update    ->     Insert files that have changed or that were not
+**                      previously in the archive
 **
 ** Create the "sqlar" table in the database if it does not already exist.
 ** Then add each file in the azFile[] array to the archive. Directories
@@ -5796,11 +5805,14 @@ static int arExecSql(ArCommand *pAr, const char *zSql){
 ** printed on stdout for each file archived.
 **
 ** The create command is the same as update, except that it drops
-** any existing "sqlar" table before beginning.
+** any existing "sqlar" table before beginning.  The "insert" command
+** always overwrites every file named on the command-line, where as
+** "update" only overwrites if the size or mtime or mode has changed.
 */
 static int arCreateOrUpdateCommand(
   ArCommand *pAr,                 /* Command arguments and options */
-  int bUpdate                     /* true for a --create.  false for --update */
+  int bUpdate,                    /* true for a --create. */
+  int bOnlyIfChanged              /* Only update if file has changed */
 ){
   const char *zCreate = 
       "CREATE TABLE IF NOT EXISTS sqlar(\n"
@@ -5822,22 +5834,24 @@ static int arCreateOrUpdateCommand(
      "      WHEN 'd' THEN 0\n"
      "      ELSE -1 END,\n"
      "    sqlar_compress(data)\n"
-     "  FROM fsdir(%Q,%Q)\n"
-     "  WHERE lsmode(mode) NOT LIKE '?%%';",
+     "  FROM fsdir(%Q,%Q) AS disk\n"
+     "  WHERE lsmode(mode) NOT LIKE '?%%'%s;"
+     ,
      "REPLACE INTO %s(name,mode,mtime,data)\n"
      "  SELECT\n"
      "    %s,\n"
      "    mode,\n"
      "    mtime,\n"
      "    data\n"
-     "  FROM fsdir(%Q,%Q)\n"
-     "  WHERE lsmode(mode) NOT LIKE '?%%';"
+     "  FROM fsdir(%Q,%Q) AS disk\n"
+     "  WHERE lsmode(mode) NOT LIKE '?%%'%s;"
   };
   int i;                          /* For iterating through azFile[] */
   int rc;                         /* Return code */
   const char *zTab = 0;           /* SQL table into which to insert */
   char *zSql;
   char zTemp[50];
+  char *zExists = 0;
 
   arExecSql(pAr, "PRAGMA page_size=512");
   rc = arExecSql(pAr, "SAVEPOINT ar;");
@@ -5868,10 +5882,21 @@ static int arCreateOrUpdateCommand(
     }
     rc = arExecSql(pAr, zCreate);
   }
+  if( bOnlyIfChanged ){
+    zExists = sqlite3_mprintf(
+      " AND NOT EXISTS("
+          "SELECT 1 FROM %s AS mem"
+          " WHERE mem.name=disk.name"
+          " AND mem.mtime=disk.mtime"
+          " AND mem.mode=disk.mode)", zTab);
+  }else{
+    zExists = sqlite3_mprintf("");
+  }
+  if( zExists==0 ) rc = SQLITE_NOMEM;
   for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
     char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
         pAr->bVerbose ? "shell_putsnl(name)" : "name",
-        pAr->azArg[i], pAr->zDir);
+        pAr->azArg[i], pAr->zDir, zExists);
     rc = arExecSql(pAr, zSql2);
     sqlite3_free(zSql2);
   }
@@ -5886,6 +5911,7 @@ end_ar_transaction:
       sqlite3_free(zSql);
     }
   }
+  sqlite3_free(zExists);
   return rc;
 }
 
@@ -5924,7 +5950,8 @@ static int arDotCommand(
     }else if( cmd.zFile ){
       int flags;
       if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
-      if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
+      if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT 
+           || cmd.eCmd==AR_CMD_UPDATE ){
         flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
       }else{
         flags = SQLITE_OPEN_READONLY;
@@ -5961,7 +5988,7 @@ static int arDotCommand(
 
     switch( cmd.eCmd ){
       case AR_CMD_CREATE:
-        rc = arCreateOrUpdateCommand(&cmd, 0);
+        rc = arCreateOrUpdateCommand(&cmd, 0, 0);
         break;
 
       case AR_CMD_EXTRACT:
@@ -5976,9 +6003,13 @@ static int arDotCommand(
         arUsage(pState->out);
         break;
 
+      case AR_CMD_INSERT:
+        rc = arCreateOrUpdateCommand(&cmd, 1, 0);
+        break;
+
       default:
         assert( cmd.eCmd==AR_CMD_UPDATE );
-        rc = arCreateOrUpdateCommand(&cmd, 1);
+        rc = arCreateOrUpdateCommand(&cmd, 1, 1);
         break;
     }
   }