** 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
| 27569 | ** "update" only overwrites if the size or mtime or mode has changed. |
| 27570 | */ |
| 27571 | static int arCreateOrUpdateCommand( |
| 27572 | ArCommand *pAr, /* Command arguments and options */ |
| 27573 | int bUpdate, /* true for a --create. */ |
| 27574 | int bOnlyIfChanged /* Only update if file has changed */ |
| 27575 | ){ |
| 27576 | const char *zCreate = |
| 27577 | "CREATE TABLE IF NOT EXISTS sqlar(\n" |
| 27578 | " name TEXT PRIMARY KEY, -- name of the file\n" |
| 27579 | " mode INT, -- access permissions\n" |
| 27580 | " mtime INT, -- last modification time\n" |
| 27581 | " sz INT, -- original file size\n" |
| 27582 | " data BLOB -- compressed content\n" |
| 27583 | ")"; |
| 27584 | const char *zDrop = "DROP TABLE IF EXISTS sqlar"; |
| 27585 | const char *zInsertFmt[2] = { |
| 27586 | "REPLACE INTO %s(name,mode,mtime,sz,data)\n" |
| 27587 | " SELECT\n" |
| 27588 | " %s,\n" |
| 27589 | " mode,\n" |
| 27590 | " mtime,\n" |
| 27591 | " CASE substr(lsmode(mode),1,1)\n" |
| 27592 | " WHEN '-' THEN length(data)\n" |
| 27593 | " WHEN 'd' THEN 0\n" |
| 27594 | " ELSE -1 END,\n" |
| 27595 | " sqlar_compress(data)\n" |
| 27596 | " FROM fsdir(%Q,%Q) AS disk\n" |
| 27597 | " WHERE lsmode(mode) NOT LIKE '?%%'%s;" |
| 27598 | , |
| 27599 | "REPLACE INTO %s(name,mode,mtime,data)\n" |
| 27600 | " SELECT\n" |
| 27601 | " %s,\n" |
| 27602 | " mode,\n" |
| 27603 | " mtime,\n" |
| 27604 | " data\n" |
| 27605 | " FROM fsdir(%Q,%Q) AS disk\n" |
| 27606 | " WHERE lsmode(mode) NOT LIKE '?%%'%s;" |
| 27607 | }; |
| 27608 | int i; /* For iterating through azFile[] */ |
| 27609 | int rc; /* Return code */ |
| 27610 | const char *zTab = 0; /* SQL table into which to insert */ |
| 27611 | char *zSql; |
| 27612 | char zTemp[50]; |
| 27613 | char *zExists = 0; |
| 27614 | |
| 27615 | arExecSql(pAr, "PRAGMA page_size=512"); |
| 27616 | rc = arExecSql(pAr, "SAVEPOINT ar;"); |
| 27617 | if( rc!=SQLITE_OK ) return rc; |
| 27618 | zTemp[0] = 0; |
| 27619 | if( pAr->bZip ){ |
| 27620 | /* Initialize the zipfile virtual table, if necessary */ |
| 27621 | if( pAr->zFile ){ |
| 27622 | sqlite3_uint64 r; |
| 27623 | sqlite3_randomness(sizeof(r),&r); |
| 27624 | sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r); |
| 27625 | zTab = zTemp; |
| 27626 | zSql = sqlite3_mprintf( |
| 27627 | "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)", |
| 27628 | zTab, pAr->zFile |
no test coverage detected