Have the shell tool ".ar --list" and ".ar --extract" commands support zip
files. Currently the "-zip" switch is required. FossilOrigin-Name: a532a0f6fd59e81086d46f09151ba7fb26725198231d902c71d0f95cb01dbe91
This commit is contained in:
parent
9ebfaad25d
commit
5a78b81b1b
@ -680,6 +680,54 @@ static int zipfileRegister(sqlite3 *db){
|
|||||||
# define zipfileRegister(x) SQLITE_OK
|
# define zipfileRegister(x) SQLITE_OK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
** zipfile_uncompress(DATA, SZ, METHOD)
|
||||||
|
*/
|
||||||
|
static void zipfileUncompressFunc(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
int iMethod;
|
||||||
|
|
||||||
|
iMethod = sqlite3_value_int(argv[2]);
|
||||||
|
if( iMethod==0 ){
|
||||||
|
sqlite3_result_value(context, argv[0]);
|
||||||
|
}else if( iMethod==8 ){
|
||||||
|
Byte *res;
|
||||||
|
int sz = sqlite3_value_int(argv[1]);
|
||||||
|
z_stream str;
|
||||||
|
memset(&str, 0, sizeof(str));
|
||||||
|
str.next_in = (Byte*)sqlite3_value_blob(argv[0]);
|
||||||
|
str.avail_in = sqlite3_value_bytes(argv[0]);
|
||||||
|
res = str.next_out = (Byte*)sqlite3_malloc(sz);
|
||||||
|
if( res==0 ){
|
||||||
|
sqlite3_result_error_nomem(context);
|
||||||
|
}else{
|
||||||
|
int err;
|
||||||
|
str.avail_out = sz;
|
||||||
|
|
||||||
|
err = inflateInit2(&str, -15);
|
||||||
|
if( err!=Z_OK ){
|
||||||
|
zipfileCtxErrorMsg(context, "inflateInit2() failed (%d)", err);
|
||||||
|
}else{
|
||||||
|
err = inflate(&str, Z_NO_FLUSH);
|
||||||
|
if( err!=Z_STREAM_END ){
|
||||||
|
zipfileCtxErrorMsg(context, "inflate() failed (%d)", err);
|
||||||
|
}else{
|
||||||
|
sqlite3_result_blob(context, res, sz, SQLITE_TRANSIENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlite3_free(res);
|
||||||
|
inflateEnd(&str);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
zipfileCtxErrorMsg(context, "unrecognized compression method: %d", iMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
#endif
|
#endif
|
||||||
@ -691,6 +739,10 @@ int sqlite3_zipfile_init(
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
SQLITE_EXTENSION_INIT2(pApi);
|
SQLITE_EXTENSION_INIT2(pApi);
|
||||||
(void)pzErrMsg; /* Unused parameter */
|
(void)pzErrMsg; /* Unused parameter */
|
||||||
|
rc = sqlite3_create_function(db, "zipfile_uncompress", 3,
|
||||||
|
SQLITE_UTF8, 0, zipfileUncompressFunc, 0, 0
|
||||||
|
);
|
||||||
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
return zipfileRegister(db);
|
return zipfileRegister(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\snew\sfile\sext/misc/zipfile.c,\scontaining\sa\svirtual\stable\sfor\sread-only\naccess\sto\ssimple\szip\sarchives.
|
C Have\sthe\sshell\stool\s".ar\s--list"\sand\s".ar\s--extract"\scommands\ssupport\szip\nfiles.\sCurrently\sthe\s"-zip"\sswitch\sis\srequired.
|
||||||
D 2017-12-26T20:39:58.777
|
D 2017-12-27T18:54:11.166
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F Makefile.in ceb40bfcb30ebba8e1202b34c56ff7e13e112f9809e2381d99be32c2726058f5
|
F Makefile.in ceb40bfcb30ebba8e1202b34c56ff7e13e112f9809e2381d99be32c2726058f5
|
||||||
@ -302,7 +302,7 @@ F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178
|
|||||||
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
|
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
|
||||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||||
F ext/misc/zipfile.c 9736694a5eb029397e769f06517250be8b8e3836f4869246bfb60942a4047227
|
F ext/misc/zipfile.c 96148b78b56664fe82f774e50dcdf6c83d693a1449b88011eba00cd6c697fedf
|
||||||
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
|
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
|
||||||
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
||||||
F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
|
F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
|
||||||
@ -483,7 +483,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
|||||||
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
|
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
|
||||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||||
F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74
|
F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74
|
||||||
F src/shell.c.in 1c927f9407fa4e58ed114577971525209ea12a293d25fe689d1973d9fef17f74
|
F src/shell.c.in d1be3030ee7afbbfb67972e4614b6d08dcae2e76460114d6b200fd28d0f008fb
|
||||||
F src/sqlite.h.in 2126192945019d4cdce335cb236b440a05ec75c93e4cd94c9c6d6e7fcc654cc4
|
F src/sqlite.h.in 2126192945019d4cdce335cb236b440a05ec75c93e4cd94c9c6d6e7fcc654cc4
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
|
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
|
||||||
@ -1692,7 +1692,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 150f07fec1e6d1fc0601820d717d8712fc513fe0d4bed67c8679eb51bca30d53
|
P 8e366b99b13d765d8bf000a7ec5919e582702e51dc07c27a746b6002898a2302
|
||||||
R ab04bfd243997fb0b46867b0347c7799
|
R 0d0cb33644ad535bd9f83812fd2ec78d
|
||||||
U dan
|
U dan
|
||||||
Z 06eecfc1ea586319973b447240342e1d
|
Z 54715bdb695d1dc399a9b1cd512f6d24
|
||||||
|
@ -1 +1 @@
|
|||||||
8e366b99b13d765d8bf000a7ec5919e582702e51dc07c27a746b6002898a2302
|
a532a0f6fd59e81086d46f09151ba7fb26725198231d902c71d0f95cb01dbe91
|
@ -4238,7 +4238,13 @@ static void shellReset(
|
|||||||
sqlite3_stmt *pStmt
|
sqlite3_stmt *pStmt
|
||||||
){
|
){
|
||||||
int rc = sqlite3_reset(pStmt);
|
int rc = sqlite3_reset(pStmt);
|
||||||
if( *pRc==SQLITE_OK ) *pRc = rc;
|
if( *pRc==SQLITE_OK ){
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqlite3 *db = sqlite3_db_handle(pStmt);
|
||||||
|
raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
|
||||||
|
}
|
||||||
|
*pRc = rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4250,6 +4256,7 @@ struct ArCommand {
|
|||||||
const char *zFile; /* --file argument, or NULL */
|
const char *zFile; /* --file argument, or NULL */
|
||||||
const char *zDir; /* --directory argument, or NULL */
|
const char *zDir; /* --directory argument, or NULL */
|
||||||
int bVerbose; /* True if --verbose */
|
int bVerbose; /* True if --verbose */
|
||||||
|
int bZip; /* True if --zip */
|
||||||
int nArg; /* Number of command arguments */
|
int nArg; /* Number of command arguments */
|
||||||
char **azArg; /* Array of command arguments */
|
char **azArg; /* Array of command arguments */
|
||||||
};
|
};
|
||||||
@ -4315,6 +4322,7 @@ static int arErrorMsg(const char *zFmt, ...){
|
|||||||
#define AR_SWITCH_VERBOSE 6
|
#define AR_SWITCH_VERBOSE 6
|
||||||
#define AR_SWITCH_FILE 7
|
#define AR_SWITCH_FILE 7
|
||||||
#define AR_SWITCH_DIRECTORY 8
|
#define AR_SWITCH_DIRECTORY 8
|
||||||
|
#define AR_SWITCH_ZIP 9
|
||||||
|
|
||||||
static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
|
static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
|
||||||
switch( eSwitch ){
|
switch( eSwitch ){
|
||||||
@ -4332,6 +4340,9 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
|
|||||||
case AR_SWITCH_VERBOSE:
|
case AR_SWITCH_VERBOSE:
|
||||||
pAr->bVerbose = 1;
|
pAr->bVerbose = 1;
|
||||||
break;
|
break;
|
||||||
|
case AR_SWITCH_ZIP:
|
||||||
|
pAr->bZip = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case AR_SWITCH_FILE:
|
case AR_SWITCH_FILE:
|
||||||
pAr->zFile = zArg;
|
pAr->zFile = zArg;
|
||||||
@ -4368,7 +4379,8 @@ static int arParseCommand(
|
|||||||
{ 'h', "help", AR_CMD_HELP, 0 },
|
{ 'h', "help", AR_CMD_HELP, 0 },
|
||||||
{ 'v', "verbose", AR_SWITCH_VERBOSE, 0 },
|
{ 'v', "verbose", AR_SWITCH_VERBOSE, 0 },
|
||||||
{ 'f', "file", AR_SWITCH_FILE, 1 },
|
{ 'f', "file", AR_SWITCH_FILE, 1 },
|
||||||
{ 'C', "directory", AR_SWITCH_DIRECTORY, 1 }
|
{ 'C', "directory", AR_SWITCH_DIRECTORY, 1 },
|
||||||
|
{ 'z', "zip", AR_SWITCH_ZIP, 0 }
|
||||||
};
|
};
|
||||||
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
|
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
|
||||||
struct ArSwitch *pEnd = &aSwitch[nSwitch];
|
struct ArSwitch *pEnd = &aSwitch[nSwitch];
|
||||||
@ -4501,7 +4513,12 @@ static int arCheckEntries(sqlite3 *db, ArCommand *pAr){
|
|||||||
int i;
|
int i;
|
||||||
sqlite3_stmt *pTest = 0;
|
sqlite3_stmt *pTest = 0;
|
||||||
|
|
||||||
shellPrepare(db, &rc, "SELECT name FROM sqlar WHERE name=?", &pTest);
|
shellPreparePrintf(db, &rc, &pTest, "SELECT name FROM %s WHERE name=?1",
|
||||||
|
pAr->bZip ? "zipfile(?2)" : "sqlar"
|
||||||
|
);
|
||||||
|
if( rc==SQLITE_OK && pAr->bZip ){
|
||||||
|
sqlite3_bind_text(pTest, 2, pAr->zFile, -1, SQLITE_TRANSIENT);
|
||||||
|
}
|
||||||
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
|
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
|
||||||
char *z = pAr->azArg[i];
|
char *z = pAr->azArg[i];
|
||||||
int n = strlen(z);
|
int n = strlen(z);
|
||||||
@ -4564,7 +4581,9 @@ static void arWhereClause(
|
|||||||
** Implementation of .ar "lisT" command.
|
** Implementation of .ar "lisT" command.
|
||||||
*/
|
*/
|
||||||
static int arListCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
static int arListCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
||||||
const char *zSql = "SELECT name FROM sqlar WHERE %s";
|
const char *zSql = "SELECT name FROM %s WHERE %s";
|
||||||
|
const char *zTbl = (pAr->bZip ? "zipfile(?)" : "sqlar");
|
||||||
|
|
||||||
char *zWhere = 0;
|
char *zWhere = 0;
|
||||||
sqlite3_stmt *pSql = 0;
|
sqlite3_stmt *pSql = 0;
|
||||||
int rc;
|
int rc;
|
||||||
@ -4572,10 +4591,15 @@ static int arListCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
|||||||
rc = arCheckEntries(db, pAr);
|
rc = arCheckEntries(db, pAr);
|
||||||
arWhereClause(&rc, pAr, &zWhere);
|
arWhereClause(&rc, pAr, &zWhere);
|
||||||
|
|
||||||
shellPreparePrintf(db, &rc, &pSql, zSql, zWhere);
|
shellPreparePrintf(db, &rc, &pSql, zSql, zTbl, zWhere);
|
||||||
|
if( rc==SQLITE_OK && pAr->bZip ){
|
||||||
|
sqlite3_bind_text(pSql, 1, pAr->zFile, -1, SQLITE_TRANSIENT);
|
||||||
|
}
|
||||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
|
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
|
||||||
raw_printf(p->out, "%s\n", sqlite3_column_text(pSql, 0));
|
raw_printf(p->out, "%s\n", sqlite3_column_text(pSql, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shellFinalize(&rc, pSql);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4587,8 +4611,18 @@ static int arExtractCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
|||||||
const char *zSql1 =
|
const char *zSql1 =
|
||||||
"SELECT "
|
"SELECT "
|
||||||
" :1 || name, "
|
" :1 || name, "
|
||||||
" writefile(:1 || name, sqlar_uncompress(data, sz), mode, mtime) "
|
" writefile(?1 || name, %s, mode, mtime) "
|
||||||
"FROM sqlar WHERE (%s) AND (data IS NULL OR :2 = 0)";
|
"FROM %s WHERE (%s) AND (data IS NULL OR ?2 = 0)";
|
||||||
|
|
||||||
|
const char *azExtraArg[] = {
|
||||||
|
"sqlar_uncompress(data, sz)",
|
||||||
|
"zipfile_uncompress(data, sz, method)"
|
||||||
|
};
|
||||||
|
const char *azSource[] = {
|
||||||
|
"sqlar", "zipfile(?3)"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct timespec times[2];
|
struct timespec times[2];
|
||||||
sqlite3_stmt *pSql = 0;
|
sqlite3_stmt *pSql = 0;
|
||||||
@ -4615,9 +4649,15 @@ static int arExtractCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
|
|||||||
memset(times, 0, sizeof(times));
|
memset(times, 0, sizeof(times));
|
||||||
times[0].tv_sec = time(0);
|
times[0].tv_sec = time(0);
|
||||||
|
|
||||||
shellPreparePrintf(db, &rc, &pSql, zSql1, zWhere);
|
shellPreparePrintf(db, &rc, &pSql, zSql1,
|
||||||
|
azExtraArg[pAr->bZip], azSource[pAr->bZip], zWhere
|
||||||
|
);
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
|
sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
|
||||||
|
if( pAr->bZip ){
|
||||||
|
sqlite3_bind_text(pSql, 3, pAr->zFile, -1, SQLITE_STATIC);
|
||||||
|
}
|
||||||
|
|
||||||
/* Run the SELECT statement twice. The first time, writefile() is called
|
/* Run the SELECT statement twice. The first time, writefile() is called
|
||||||
** for all archive members that should be extracted. The second time,
|
** for all archive members that should be extracted. The second time,
|
||||||
@ -4676,6 +4716,8 @@ static int arCreateUpdate(
|
|||||||
int i; /* For iterating through azFile[] */
|
int i; /* For iterating through azFile[] */
|
||||||
int rc; /* Return code */
|
int rc; /* Return code */
|
||||||
|
|
||||||
|
assert( pAr->bZip==0 );
|
||||||
|
|
||||||
rc = sqlite3_exec(db, "SAVEPOINT ar;", 0, 0, 0);
|
rc = sqlite3_exec(db, "SAVEPOINT ar;", 0, 0, 0);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
@ -4772,7 +4814,17 @@ static int arDotCommand(
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
sqlite3 *db = 0; /* Database handle to use as archive */
|
sqlite3 *db = 0; /* Database handle to use as archive */
|
||||||
|
|
||||||
if( cmd.zFile ){
|
if( cmd.bZip ){
|
||||||
|
if( cmd.zFile==0 ){
|
||||||
|
raw_printf(stderr, "zip format requires a --file switch\n");
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}else
|
||||||
|
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
|
||||||
|
raw_printf(stderr, "zip archives are read-only\n");
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
db = pState->db;
|
||||||
|
}else if( cmd.zFile ){
|
||||||
int flags;
|
int flags;
|
||||||
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
|
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
|
||||||
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user