Implement the ".ar --create" command using a single
"REPLACE INTO sqlar SELECT ... FROM fsdir();" statement. Add the shell_putsnl() SQL function for providing --verbose output. FossilOrigin-Name: 28ab930436fea33c79073e84f39d9e381fa60b4702a5dcbfaaed72baeeae8431
This commit is contained in:
parent
6c237b1fa7
commit
634c70fa15
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sthe\s"filetype()"\sSQL\sfunction\sfor\sinterpreting\sfile\smodes\sto\sthe\nfileio.c\sextension.
|
||||
D 2018-01-10T15:53:06.284
|
||||
C Implement\sthe\s".ar\s--create"\scommand\susing\sa\ssingle\s\n"REPLACE\sINTO\ssqlar\sSELECT\s...\sFROM\sfsdir();"\sstatement.\s\sAdd\sthe\nshell_putsnl()\sSQL\sfunction\sfor\sproviding\s--verbose\soutput.
|
||||
D 2018-01-10T16:50:18.954
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 12b6daa4bdb03fa87da27cbc205ff88ace645475b5be79414a3038b68ade14cb
|
||||
@ -484,7 +484,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74
|
||||
F src/shell.c.in 7d49ed78c6d8298d38d4733c3cc24f3a4230cd2f151564b7c11ab2e280007f9c
|
||||
F src/shell.c.in f8ae3a792ba5ae09d6ad89845fc1cae75eb5b467f8534f654b8107b54e4aa81e
|
||||
F src/sqlite.h.in 1f1a2da222ec57465794e8984d77f32d0bd0da80cdc136beadda461a0be9d80c
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
|
||||
@ -1697,7 +1697,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 430d1a7daa823ae53606b7a158af4e7c16f62ff9b072b90606524e7c3f6131df
|
||||
R 54a0e19016ae7cc0ce7d6a9a20dca28f
|
||||
P 58c0c74c407d93f48930a4964b6cc48f008b522d193a62a559de0e6a319a8bd0
|
||||
R 6861922f8b8e02d4e242f42a1464e5df
|
||||
U drh
|
||||
Z d67640218b4e3095d4e0ccc9365f61ee
|
||||
Z dfee26c5de1e816e5523347d081a1560
|
||||
|
@ -1 +1 @@
|
||||
58c0c74c407d93f48930a4964b6cc48f008b522d193a62a559de0e6a319a8bd0
|
||||
28ab930436fea33c79073e84f39d9e381fa60b4702a5dcbfaaed72baeeae8431
|
104
src/shell.c.in
104
src/shell.c.in
@ -1135,6 +1135,22 @@ static void shellLog(void *pArg, int iErrCode, const char *zMsg){
|
||||
fflush(p->pLog);
|
||||
}
|
||||
|
||||
/*
|
||||
** SQL function: shell_putsnl(X)
|
||||
**
|
||||
** Write the text X to the screen (or whatever output is being directed)
|
||||
** adding a newline at the end, and then return X.
|
||||
*/
|
||||
static void shellPutsFunc(
|
||||
sqlite3_context *pCtx,
|
||||
int nVal,
|
||||
sqlite3_value **apVal
|
||||
){
|
||||
ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
|
||||
utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
|
||||
sqlite3_result_value(pCtx, apVal[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
** Output the given string as a hex-encoded blob (eg. X'1234' )
|
||||
*/
|
||||
@ -3307,6 +3323,8 @@ static void open_db(ShellState *p, int keepAlive){
|
||||
shellAddSchemaName, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
|
||||
shellModuleSchema, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
|
||||
shellPutsFunc, 0, 0);
|
||||
if( p->openMode==SHELL_OPEN_ZIPFILE ){
|
||||
char *zSql = sqlite3_mprintf(
|
||||
"CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
|
||||
@ -5008,7 +5026,6 @@ static int arCreateOrUpdateCommand(
|
||||
ArCommand *pAr, /* Command arguments and options */
|
||||
int bUpdate /* true for a --create. false for --update */
|
||||
){
|
||||
const char *zSql = "SELECT name, mode, mtime, data FROM fsdir($name, $dir)";
|
||||
const char *zCreate =
|
||||
"CREATE TABLE IF NOT EXISTS sqlar(\n"
|
||||
" name TEXT PRIMARY KEY, -- name of the file\n"
|
||||
@ -5018,86 +5035,41 @@ static int arCreateOrUpdateCommand(
|
||||
" data BLOB -- compressed content\n"
|
||||
")";
|
||||
const char *zDrop = "DROP TABLE IF EXISTS sqlar";
|
||||
const char *zInsert = "REPLACE INTO sqlar VALUES(?,?,?,?,sqlar_compress(?))";
|
||||
|
||||
sqlite3_stmt *pStmt = 0; /* Directory traverser */
|
||||
sqlite3_stmt *pInsert = 0; /* Compilation of zInsert */
|
||||
const char *zInsertFmt =
|
||||
"REPLACE INTO sqlar(name,mode,mtime,sz,data)\n"
|
||||
" SELECT\n"
|
||||
" %s,\n"
|
||||
" mode,\n"
|
||||
" mtime,\n"
|
||||
" CASE filetype(mode)\n"
|
||||
" WHEN 'file' THEN length(data)\n"
|
||||
" WHEN 'directory' THEN 0\n"
|
||||
" ELSE -1 END,\n"
|
||||
" CASE WHEN filetype(mode)<>'directory' THEN data ELSE NULL END\n"
|
||||
" FROM fsdir(%Q,%Q)\n"
|
||||
" WHERE filetype(mode)<>'unknown'";
|
||||
int i; /* For iterating through azFile[] */
|
||||
int j; /* Parameter index */
|
||||
int rc; /* Return code */
|
||||
|
||||
assert( pAr->bZip==0 );
|
||||
|
||||
rc = arExecSql(pAr, "SAVEPOINT ar;");
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
if( bUpdate==0 ){
|
||||
rc = arExecSql(pAr, zDrop);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
|
||||
rc = arExecSql(pAr, zCreate);
|
||||
if( !pAr->bDryRun ){
|
||||
shellPrepare(pAr->db, &rc, zInsert, &pInsert);
|
||||
}
|
||||
shellPrepare(pAr->db, &rc, zSql, &pStmt);
|
||||
j = sqlite3_bind_parameter_index(pStmt, "$dir");
|
||||
sqlite3_bind_text(pStmt, j, pAr->zDir, -1, SQLITE_STATIC);
|
||||
if( pAr->bDryRun ){
|
||||
utf8_printf(pAr->p->out, "%s;\n", sqlite3_sql(pStmt));
|
||||
}
|
||||
|
||||
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
|
||||
j = sqlite3_bind_parameter_index(pStmt, "$name");
|
||||
sqlite3_bind_text(pStmt, j, pAr->azArg[i], -1, SQLITE_STATIC);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
int sz;
|
||||
const char *zName = (const char*)sqlite3_column_text(pStmt, 0);
|
||||
int mode = sqlite3_column_int(pStmt, 1);
|
||||
unsigned int mtime = sqlite3_column_int(pStmt, 2);
|
||||
|
||||
if( pAr->bVerbose ){
|
||||
utf8_printf(pAr->p->out, "%s\n", zName);
|
||||
}
|
||||
if( pAr->bDryRun ){
|
||||
utf8_printf(pAr->p->out, "%s;\n", zInsert);
|
||||
continue;
|
||||
}
|
||||
|
||||
sqlite3_bind_text(pInsert, 1, zName, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_int(pInsert, 2, mode);
|
||||
sqlite3_bind_int64(pInsert, 3, (sqlite3_int64)mtime);
|
||||
|
||||
if( S_ISDIR(mode) ){
|
||||
sz = 0;
|
||||
sqlite3_bind_null(pInsert, 5);
|
||||
}else{
|
||||
sqlite3_bind_value(pInsert, 5, sqlite3_column_value(pStmt, 3));
|
||||
if( S_ISLNK(mode) ){
|
||||
sz = -1;
|
||||
}else{
|
||||
sz = sqlite3_column_bytes(pStmt, 3);
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_bind_int(pInsert, 4, sz);
|
||||
if( pAr->bDryRun ){
|
||||
utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pInsert));
|
||||
}else{
|
||||
sqlite3_step(pInsert);
|
||||
}
|
||||
rc = sqlite3_reset(pInsert);
|
||||
}
|
||||
shellReset(&rc, pStmt);
|
||||
char *zSql = sqlite3_mprintf(zInsertFmt,
|
||||
pAr->bVerbose ? "shell_putsnl(name)" : "name",
|
||||
pAr->azArg[i], pAr->zDir);
|
||||
rc = arExecSql(pAr, zSql);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;");
|
||||
}else{
|
||||
rc = arExecSql(pAr, "RELEASE ar;");
|
||||
}
|
||||
shellFinalize(&rc, pStmt);
|
||||
shellFinalize(&rc, pInsert);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -5161,7 +5133,9 @@ static int arDotCommand(
|
||||
#endif
|
||||
}
|
||||
if( cmd.zSrcTable==0 ){
|
||||
if( sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0) ){
|
||||
if( cmd.eCmd!=AR_CMD_CREATE
|
||||
&& sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
|
||||
){
|
||||
utf8_printf(stderr, "database does not contain an 'sqlar' table\n");
|
||||
rc = SQLITE_ERROR;
|
||||
goto end_ar_command;
|
||||
|
Loading…
x
Reference in New Issue
Block a user