From: drh Date: Thu, 27 Jun 2013 14:07:53 +0000 (+0000) Subject: If the filename argument to the ".import" command in the command-line shell X-Git-Tag: version-3.8.0~125 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5bde816599b78e80c9157613744dd3fc50dcb90f;p=thirdparty%2Fsqlite.git If the filename argument to the ".import" command in the command-line shell begins with '|' then treat it as an input pipe rather than a file. FossilOrigin-Name: 4c02b344f5c6f6fb1c61b79d51063a1e0e2d75c0 --- diff --git a/manifest b/manifest index 8dc95a782b..9c67932ae5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\shandling\sof\sbackslash\sescapes\son\sdouble-quoted\sarguments\sto\ndot-commands\sin\sthe\scommand-line\sshell. -D 2013-06-27T13:26:55.828 +C If\sthe\sfilename\sargument\sto\sthe\s".import"\scommand\sin\sthe\scommand-line\sshell\nbegins\swith\s'|'\sthen\streat\sit\sas\san\sinput\spipe\srather\sthan\sa\sfile. +D 2013-06-27T14:07:53.488 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 -F src/shell.c 3b8fff51ad65fb932b0b29a2a33c1991a4c56a9b +F src/shell.c c0f38cee126d1ea82275195933359e91d90196a0 F src/sqlite.h.in 9e8d57aa4d2fdc181dc25e9aa295f5ecec7e184a F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h d936f797812c28b81b26ed18345baf8db28a21a5 @@ -777,7 +777,7 @@ F test/shell1.test 928547277d385038c696428e9d791cbbad098974 F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 -F test/shell5.test 0fed7823d57e80f79da2c5f350e50aa86011f24f +F test/shell5.test 946e620a41b64f90d45dcf91c36e8d408d435cfd F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 @@ -1098,7 +1098,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P e88fd5b22198edfc6f91390194bdde07ca06ba35 -R e0ea5c577e99c4c9e7b89055ec3f7b29 +P 656a1fe5dd670e6ce7173ed3ce3392c0151641a0 +R 97949a48417894542203b78a8164f7cc U drh -Z e3dc96e0e57dde00a2c7ad221cef5689 +Z 363202d577b3d015f15870ab9c3327f8 diff --git a/manifest.uuid b/manifest.uuid index b31b7d62c6..f795e73365 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -656a1fe5dd670e6ce7173ed3ce3392c0151641a0 \ No newline at end of file +4c02b344f5c6f6fb1c61b79d51063a1e0e2d75c0 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 86a361de2b..352e31d511 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1995,6 +1995,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){ char *zTable = azArg[2]; /* Insert data into this table */ + char *zFile = azArg[1]; /* Name of file to extra content from */ sqlite3_stmt *pStmt = NULL; /* A statement */ int nCol; /* Number of columns in the table */ int nByte; /* Number of bytes in an SQL string */ @@ -2002,11 +2003,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ int nSep; /* Number of bytes in p->separator[] */ char *zSql; /* An SQL statement */ CSVReader sCsv; /* Reader context */ + int (*xCloser)(FILE*); /* Procedure to close th3 connection */ seenInterrupt = 0; memset(&sCsv, 0, sizeof(sCsv)); - sCsv.zFile = azArg[1]; - sCsv.nLine = 1; open_db(p); nSep = strlen30(p->separator); if( nSep==0 ){ @@ -2018,16 +2018,25 @@ static int do_meta_command(char *zLine, struct callback_data *p){ " for import\n"); return 1; } - sCsv.in = fopen(sCsv.zFile, "rb"); + sCsv.zFile = zFile; + sCsv.nLine = 1; + if( sCsv.zFile[0]=='|' ){ + sCsv.in = popen(sCsv.zFile+1, "r"); + sCsv.zFile = ""; + xCloser = pclose; + }else{ + sCsv.in = fopen(sCsv.zFile, "rb"); + xCloser = fclose; + } if( sCsv.in==0 ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", sCsv.zFile); + fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); return 1; } sCsv.cSeparator = p->separator[0]; zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); if( zSql==0 ){ fprintf(stderr, "Error: out of memory\n"); - fclose(sCsv.in); + xCloser(sCsv.in); return 1; } nByte = strlen30(zSql); @@ -2040,6 +2049,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){ cSep = ','; if( sCsv.cTerm!=sCsv.cSeparator ) break; } + if( cSep=='(' ){ + sqlite3_free(zCreate); + sqlite3_free(sCsv.z); + xCloser(sCsv.in); + fprintf(stderr,"%s: empty file\n", sCsv.zFile); + return 1; + } zCreate = sqlite3_mprintf("%z\n)", zCreate); rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); sqlite3_free(zCreate); @@ -2047,7 +2063,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, sqlite3_errmsg(db)); sqlite3_free(sCsv.z); - fclose(sCsv.in); + xCloser(sCsv.in); return 1; } rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); @@ -2056,7 +2072,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( rc ){ if (pStmt) sqlite3_finalize(pStmt); fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); - fclose(sCsv.in); + xCloser(sCsv.in); return 1; } nCol = sqlite3_column_count(pStmt); @@ -2066,7 +2082,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); if( zSql==0 ){ fprintf(stderr, "Error: out of memory\n"); - fclose(sCsv.in); + xCloser(sCsv.in); return 1; } sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); @@ -2082,7 +2098,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( rc ){ fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); if (pStmt) sqlite3_finalize(pStmt); - fclose(sCsv.in); + xCloser(sCsv.in); return 1; } do{ @@ -2118,7 +2134,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }while( sCsv.cTerm!=EOF ); - fclose(sCsv.in); + xCloser(sCsv.in); sqlite3_free(sCsv.z); sqlite3_finalize(pStmt); sqlite3_exec(p->db, "COMMIT", 0, 0, 0); diff --git a/test/shell5.test b/test/shell5.test index 343e4cfcd1..6256b281bb 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -215,7 +215,7 @@ SELECT COUNT(*) FROM t2;}] } {0 1} # try importing a large number of rows -set rows 99999 +set rows 9999 do_test shell5-1.7.1 { set in [open shell5.csv w] puts $in a @@ -228,4 +228,18 @@ do_test shell5-1.7.1 { SELECT COUNT(*) FROM t3;}] } [list 0 $rows] +# Inport from a pipe. (Unix only, as it requires "awk") +if {$tcl_platform(platform)=="unix"} { + do_test shell5-1.8 { + file delete -force test.db + catchcmd test.db {.mode csv +.import "|awk 'END{print \"x,y\";for(i=1;i<=5;i++){print i \",this is \" i}}'" t1 +SELECT * FROM t1;} + } {0 {1,"this is 1" +2,"this is 2" +3,"this is 3" +4,"this is 4" +5,"this is 5"}} +} + finish_test