]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If the filename argument to the ".import" command in the command-line shell
authordrh <drh@noemail.net>
Thu, 27 Jun 2013 14:07:53 +0000 (14:07 +0000)
committerdrh <drh@noemail.net>
Thu, 27 Jun 2013 14:07:53 +0000 (14:07 +0000)
begins with '|' then treat it as an input pipe rather than a file.

FossilOrigin-Name: 4c02b344f5c6f6fb1c61b79d51063a1e0e2d75c0

manifest
manifest.uuid
src/shell.c
test/shell5.test

index 8dc95a782b04a8a8f035918f1b85f6680d72011c..9c67932ae5135e25626be48d5686b4287bc12cca 100644 (file)
--- 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
index b31b7d62c6780e5479c0072e7cb9a3f33c5cf8b7..f795e733651d4f9652205df0f0d92d6e95400bb2 100644 (file)
@@ -1 +1 @@
-656a1fe5dd670e6ce7173ed3ce3392c0151641a0
\ No newline at end of file
+4c02b344f5c6f6fb1c61b79d51063a1e0e2d75c0
\ No newline at end of file
index 86a361de2b2f0fdb92f65e10e7209870d084cf8d..352e31d5111553420a440481869af32fff902707 100644 (file)
@@ -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 = "<pipe>";
+      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);
index 343e4cfcd1666696ed3c18cd1569f4522503c9c0..6256b281bba206e42efa0e347c247054a4f55166 100644 (file)
@@ -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