Add support for the "--list" command. And for arguments to the "--extract"
command. FossilOrigin-Name: 32c4fa2552bb0fa7d7d143108457efae7a756d6cb14b1d59312e56efac3b2656
This commit is contained in:
parent
ece4b0c172
commit
3f67ddf8f2
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Add\stests\sand\sfixes\sfor\sthe\sshell\s".ar"\scommand\s-f\soption.
|
||||
D 2017-12-12T20:28:36.588
|
||||
C Add\ssupport\sfor\sthe\s"--list"\scommand.\sAnd\sfor\sarguments\sto\sthe\s"--extract"\ncommand.
|
||||
D 2017-12-13T20:04:53.034
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 6a879cbf01e37f9eac131414955f71774b566502d9a57ded1b8585b507503cb8
|
||||
@ -474,7 +474,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 17e220191860a64a18c084141e1a8b7309e166a6f2d42c02021af27ea080d157
|
||||
F src/shell.c.in a09773c80a647f6ba4ef8dd9ce88840d52dbede5a9fa318333843deb8c8548b7
|
||||
F src/shell.c.in b53eddcb293a9d35c0673c1d3bf2cf120b55e6660b436f65d689776a56391562
|
||||
F src/sqlite.h.in 8fd97993d48b50b9bade38c52f12d175942c9497c960905610c7b03a3e4b5818
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
|
||||
@ -1682,7 +1682,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 38dbeb1e777aa7ec742aa27002ad4dcee28af520dc43de96e5c56c39f16574ff
|
||||
R e6fcdae437270c2329ef751955f65f0e
|
||||
P 1a9867973c9d6675fa5254fdd74f36004707a98a91593a188033cf5a49cc7a0b
|
||||
R c505f9c0d154ac54b6761fcc5d07e027
|
||||
U dan
|
||||
Z 1b5cf819c180e1535b22a7c0cf2ece4d
|
||||
Z dcb23b384070f4f2014f2150f41e157a
|
||||
|
@ -1 +1 @@
|
||||
1a9867973c9d6675fa5254fdd74f36004707a98a91593a188033cf5a49cc7a0b
|
||||
32c4fa2552bb0fa7d7d143108457efae7a756d6cb14b1d59312e56efac3b2656
|
138
src/shell.c.in
138
src/shell.c.in
@ -4092,6 +4092,26 @@ static void shellPrepare(
|
||||
}
|
||||
}
|
||||
|
||||
static void shellPrepare2(
|
||||
sqlite3 *db,
|
||||
int *pRc,
|
||||
const char *zSql,
|
||||
const char *zTail,
|
||||
sqlite3_stmt **ppStmt
|
||||
){
|
||||
if( *pRc==SQLITE_OK && zTail ){
|
||||
char *z = sqlite3_mprintf("%s %s", zSql, zTail);
|
||||
if( z==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
shellPrepare(db, pRc, z, ppStmt);
|
||||
sqlite3_free(z);
|
||||
}
|
||||
}else{
|
||||
shellPrepare(db, pRc, zSql, ppStmt);
|
||||
}
|
||||
}
|
||||
|
||||
static void shellFinalize(
|
||||
int *pRc,
|
||||
sqlite3_stmt *pStmt
|
||||
@ -4316,12 +4336,96 @@ static int arUpdateCmd(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function assumes that all arguments within the ArCommand.azArg[]
|
||||
** array refer to archive members, as for the --extract or --list 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.
|
||||
**
|
||||
** This function strips any trailing '/' characters from each argument.
|
||||
** This is consistent with the way the [tar] command seems to work on
|
||||
** Linux.
|
||||
*/
|
||||
static int arCheckEntries(sqlite3 *db, ArCommand *pAr){
|
||||
int rc = SQLITE_OK;
|
||||
if( pAr->nArg ){
|
||||
int i;
|
||||
sqlite3_stmt *pTest = 0;
|
||||
|
||||
shellPrepare(db, &rc, "SELECT name FROM sqlar WHERE name=?", &pTest);
|
||||
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
|
||||
char *z = pAr->azArg[i];
|
||||
int n = strlen(z);
|
||||
int bOk = 0;
|
||||
while( n>0 && z[n-1]=='/' ) n--;
|
||||
z[n] = '\0';
|
||||
sqlite3_bind_text(pTest, 1, z, -1, SQLITE_STATIC);
|
||||
if( SQLITE_ROW==sqlite3_step(pTest) ){
|
||||
bOk = 1;
|
||||
}
|
||||
shellReset(&rc, pTest);
|
||||
if( rc==SQLITE_OK && bOk==0 ){
|
||||
raw_printf(stderr, "not found in archive: %s\n", z);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
shellFinalize(&rc, pTest);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Format a WHERE clause that can be used against the "sqlar" table to
|
||||
** 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.
|
||||
*/
|
||||
static void arWhereClause(
|
||||
int *pRc,
|
||||
ArCommand *pAr,
|
||||
char **pzWhere /* OUT: New WHERE clause (or NULL) */
|
||||
){
|
||||
char *zWhere = 0;
|
||||
if( *pRc==SQLITE_OK ){
|
||||
int i;
|
||||
const char *zSep = "WHERE ";
|
||||
for(i=0; i<pAr->nArg; i++){
|
||||
const char *z = pAr->azArg[i];
|
||||
zWhere = sqlite3_mprintf(
|
||||
"%z%s name = '%q' OR name BETWEEN '%q/' AND '%q0'",
|
||||
zWhere, zSep, z, z, z
|
||||
);
|
||||
if( zWhere==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
break;
|
||||
}
|
||||
zSep = " OR ";
|
||||
}
|
||||
}
|
||||
*pzWhere = zWhere;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of .ar "lisT" command.
|
||||
*/
|
||||
static int arListCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||
raw_printf(stderr, "todo...\n");
|
||||
return SQLITE_OK;
|
||||
const char *zSql = "SELECT name FROM sqlar";
|
||||
char *zWhere = 0;
|
||||
sqlite3_stmt *pSql = 0;
|
||||
int rc;
|
||||
|
||||
rc = arCheckEntries(db, pAr);
|
||||
arWhereClause(&rc, pAr, &zWhere);
|
||||
|
||||
shellPrepare2(db, &rc, zSql, zWhere, &pSql);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
|
||||
raw_printf(p->out, "%s\n", sqlite3_column_text(pSql, 0));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -4331,8 +4435,11 @@ static int arListCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||
static int arExtractCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||
const char *zSql1 =
|
||||
"SELECT :1 || name, writefile(:1 || name, "
|
||||
"CASE WHEN (data AND sz>=0 AND sz!=length(data)) THEN uncompress(data) "
|
||||
" ELSE data END, "
|
||||
"CASE WHEN (data AND sz>=0 AND sz!=length(data)) THEN "
|
||||
" uncompress(data) "
|
||||
"ELSE"
|
||||
" data "
|
||||
"END, "
|
||||
"mode) FROM sqlar";
|
||||
const char *zSql2 = "SELECT :1 || name, mtime FROM sqlar";
|
||||
|
||||
@ -4340,17 +4447,27 @@ static int arExtractCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||
sqlite3_stmt *pSql = 0;
|
||||
int rc = SQLITE_OK;
|
||||
char *zDir = 0;
|
||||
char *zWhere = 0;
|
||||
|
||||
if( pAr->zDir ){
|
||||
zDir = sqlite3_mprintf("%s/", pAr->zDir);
|
||||
}else{
|
||||
zDir = sqlite3_mprintf("");
|
||||
/* If arguments are specified, check that they actually exist within
|
||||
** the archive before proceeding. And formulate a WHERE clause to
|
||||
** match them. */
|
||||
rc = arCheckEntries(db, pAr);
|
||||
arWhereClause(&rc, pAr, &zWhere);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( pAr->zDir ){
|
||||
zDir = sqlite3_mprintf("%s/", pAr->zDir);
|
||||
}else{
|
||||
zDir = sqlite3_mprintf("");
|
||||
}
|
||||
if( zDir==0 ) rc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
memset(times, 0, sizeof(times));
|
||||
times[0].tv_sec = time(0);
|
||||
|
||||
shellPrepare(db, &rc, zSql1, &pSql);
|
||||
shellPrepare2(db, &rc, zSql1, zWhere, &pSql);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
|
||||
}
|
||||
@ -4361,7 +4478,7 @@ static int arExtractCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||
}
|
||||
shellFinalize(&rc, pSql);
|
||||
|
||||
shellPrepare(db, &rc, zSql2, &pSql);
|
||||
shellPrepare2(db, &rc, zSql2, zWhere, &pSql);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
|
||||
}
|
||||
@ -4377,6 +4494,7 @@ static int arExtractCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||
shellFinalize(&rc, pSql);
|
||||
|
||||
sqlite3_free(zDir);
|
||||
sqlite3_free(zWhere);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user