]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
:-) (CVS 66)
authordrh <drh@noemail.net>
Wed, 7 Jun 2000 01:27:47 +0000 (01:27 +0000)
committerdrh <drh@noemail.net>
Wed, 7 Jun 2000 01:27:47 +0000 (01:27 +0000)
FossilOrigin-Name: 5d2e72e4bd5e218133190b8b1ebe52f48e2d7140

manifest
manifest.uuid
src/shell.c
src/vdbe.c
test/copy.test

index ba7cda2996dc96f4fec98cf4411023f125fcf6d0..9cd108aa630cd346c4ffb4ed3797b1efd208ac12 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C :-)\s(CVS\s65)
-D 2000-06-07T00:12:25
+C :-)\s(CVS\s66)
+D 2000-06-07T01:27:48
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
 F Makefile.in 17ba1ccf8d2d40c627796bba8f72952365d6d644
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
@@ -15,18 +15,18 @@ F src/insert.c 5e69dd70c3f91cf5ec5090f39fd6cd8e135af9bf
 F src/main.c 93a7ad14bb5a82ad13ad59da23ef674a94b0c3d6
 F src/parse.y 8b632f4c4ff2f4400f15592ca9d8fda27d97d0c4
 F src/select.c 74fa3af62bfa2e6e29f43153f883fd28c295b853
-F src/shell.c a2a2c5c6d9a8f640307edaf560a33c463ad6e3eb
+F src/shell.c 23d9700d0855f4767638c8cbb53e18aff08d5c31
 F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268
 F src/sqliteInt.h 3cca846df0a8b5f811cf4f8021303547cd8f21fd
 F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
 F src/tokenize.c 09373590cc3942aa4744eb431ac5b5ce31e7cfea
 F src/update.c 18746f920f989b3d19d96c08263c92584823cd35
 F src/util.c 33f9baa01e45394ef0cf85361a0e872987884315
-F src/vdbe.c 221e46a1e9f7b526d66939b536321113b1f7947a
+F src/vdbe.c d2ac31f6c0bb967b47409e715872992dd2fa62d3
 F src/vdbe.h 8f79f57c66ce1030f6371ff067b326d627a52c6d
 F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c
 F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
-F test/copy.test 73c3783535db538c8ebd8fffb931376864fc3226
+F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
 F test/delete.test 30451333f89479d2deb5410edd3f3cce67339944
 F test/expr.test 52be5592143a88479e0006dfd7e2023e43294636
 F test/in.test 17cd46a9ca0e5d4a804483e6fb496458494858e6
@@ -51,7 +51,7 @@ F www/c_interface.tcl 9ac800854272db5fe439e07b7435b243a5422293
 F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6
 F www/index.tcl 52e29a4eeda8d59e91af43c61fef177c5f2ffd53
 F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd
-P 3a2f4dcab299aceeba3afc223f424cd1d4d13c9d
-R 8071c3f31f98240ab06f25e12e1bf1fb
+P 80ee166ed1bb3694530a73c57544cb4d16964884
+R 021b42e9245a54b887b891304d2a0857
 U drh
-Z bb54d229ead7ce076e23b0376d456ad7
+Z e08c99a878ce95e40ba1229b1bd04197
index 7fe9ba4ed65cc38ca8e8b2afb0aacaf9815bfddd..c0f9ebbeeb719ef4b4695018ba8fae93f62bb22b 100644 (file)
@@ -1 +1 @@
-80ee166ed1bb3694530a73c57544cb4d16964884
\ No newline at end of file
+5d2e72e4bd5e218133190b8b1ebe52f48e2d7140
\ No newline at end of file
index c14f69bea0ab0d3b4128c00fad1e0928996164ea..7204f04df977b02763718633572674811a564248 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains code to implement the "sqlite" command line
 ** utility for accessing SQLite databases.
 **
-** $Id: shell.c,v 1.9 2000/06/07 00:12:25 drh Exp $
+** $Id: shell.c,v 1.10 2000/06/07 01:27:48 drh Exp $
 */
 #include <stdlib.h>
 #include <string.h>
@@ -122,10 +122,12 @@ static char *one_input_line(const char *zPrior, int isatty){
 ** state and mode information.
 */
 struct callback_data {
+  sqlite *db;        /* The database */
   int cnt;           /* Number of records displayed so far */
   FILE *out;         /* Write results here */
   int mode;          /* An output mode setting */
   int showHeader;    /* True to show column names in List or Column mode */
+  int escape;        /* Escape this character when in MODE_List */
   char separator[20];/* Separator character for MODE_List */
   int colWidth[30];  /* Width of each column when in column mode */
 };
@@ -200,8 +202,20 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
         }
       }
       for(i=0; i<nArg; i++){
-        fprintf(p->out,"%s%s",azArg[i] ? azArg[i] : "",
-             i==nArg-1 ? "\n" : p->separator);
+        char *z = azArg[i];
+        if( z==0 ) z = "";
+        while( *z ){
+          int j;
+          for(j=0; z[j] && z[j]!=p->escape && z[j]!='\\'; j++){}
+          if( j>0 ){
+            fprintf(p->out, "%.*s", j, z);
+          }
+          if( z[j] ){
+            fprintf(p->out, "\\%c", z[j]);
+            z = &z[j+1];
+          }
+        }
+        fprintf(p->out, "%s", i==nArg-1 ? "\n" : p->separator);
       }
       break;
     }
@@ -226,10 +240,36 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
   return 0;
 }
 
+/*
+** This is a different callback routine used for dumping the database.
+** Each row received by this callback consists of a table name,
+** the table type ("index" or "table") and SQL to create the table.
+** This routine should print text sufficient to recreate the table.
+*/
+static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
+  struct callback_data *pData = (struct callback_data *)pArg;
+  if( nArg!=3 ) return 1;
+  fprintf(pData->out, "%s;\n", azArg[2]);
+  if( strcmp(azArg[1],"table")==0 ){
+    struct callback_data d2;
+    char zSql[1000];
+    d2 = *pData;
+    d2.mode = MODE_List;
+    strcpy(d2.separator,"\t");
+    fprintf(pData->out, "COPY '%s' FROM STDIN;\n", azArg[0]);
+    sprintf(zSql, "SELECT * FROM '%s'", azArg[0]);
+    sqlite_exec(pData->db, zSql, callback, &d2, 0);
+    fprintf(pData->out, "\\.\n");
+  }
+  fprintf(pData->out, "VACUUM '%s';\n", azArg[2]);
+  return 0;
+}
+
 /*
 ** Text of a help message
 */
 static char zHelp[] = 
+  ".dump ?TABLE? ...      Dump the database in an text format\n"
   ".exit                  Exit this program\n"
   ".explain               Set output mode suitable for EXPLAIN\n"
   ".header ON|OFF         Turn display of headers on or off\n"
@@ -278,6 +318,29 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
   if( nArg==0 ) return;
   n = strlen(azArg[0]);
   c = azArg[0][0];
+  if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
+    char *zErrMsg = 0;
+    char zSql[1000];
+    if( nArg==1 ){
+      sprintf(zSql, "SELECT name, type, sql FROM sqlite_master "
+                    "ORDER BY tbl_name, type DESC, name");
+      sqlite_exec(db, zSql, dump_callback, p, &zErrMsg);
+    }else{
+      int i;
+      for(i=1; i<nArg && zErrMsg==0; i++){
+        sprintf(zSql, "SELECT name, type, sql FROM sqlite_master "
+                      "WHERE tbl_name LIKE '%.800s'"
+                      "ORDER BY type DESC, name", azArg[i]);
+        sqlite_exec(db, zSql, dump_callback, p, &zErrMsg);
+        
+      }
+    }
+    if( zErrMsg ){
+      fprintf(stderr,"Error: %s\n", zErrMsg);
+      free(zErrMsg);
+    }
+  }else
 
   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
     exit(0);
@@ -320,7 +383,7 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
     data.showHeader = 0;
     data.mode = MODE_List;
     sprintf(zSql, "SELECT name FROM sqlite_master "
-                  "WHERE type='index' AND tbl_name LIKE '%.00s' "
+                  "WHERE type='index' AND tbl_name LIKE '%.800s' "
                   "ORDER BY name", azArg[1]);
     sqlite_exec(db, zSql, callback, &data, &zErrMsg);
     if( zErrMsg ){
@@ -456,7 +519,7 @@ int main(int argc, char **argv){
     fprintf(stderr,"Usage: %s ?OPTIONS? FILENAME ?SQL?\n", argv0);
     exit(1);
   }
-  db = sqlite_open(argv[1], 0666, &zErrMsg);
+  data.db = db = sqlite_open(argv[1], 0666, &zErrMsg);
   if( db==0 ){
     if( zErrMsg ){
       fprintf(stderr,"Unable to open database \"%s\": %s\n", argv[1], zErrMsg);
index 9b8bfd15fff4dc235531b6f46b15305411eabce5..35fe30c5c9594356e110993ec6d8a7216d916c86 100644 (file)
@@ -41,7 +41,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.25 2000/06/07 00:12:25 drh Exp $
+** $Id: vdbe.c,v 1.26 2000/06/07 01:27:49 drh Exp $
 */
 #include "sqliteInt.h"
 #include <unistd.h>
@@ -2617,12 +2617,25 @@ int sqliteVdbeExec(
         c = zDelim[0];
         nDelim = strlen(zDelim);
         p->azField[0] = z;
-        for(i=1; *z!=0 && i<nField; i++){
-          while( *z && (*z!=c || strncmp(z,zDelim,nDelim)) ){ z++; }
-          if( *z ){
-            *z = 0;
-            z += nDelim;
-            p->azField[i] = z;
+        for(i=1; *z!=0 && i<=nField; i++){
+          int from, to;
+          from = to = 0;
+          while( z[from] ){
+            if( z[from]=='\\' && z[from+1]!=0 ){
+              z[to++] = z[from+1];
+              from += 2;
+              continue;
+            }
+            if( z[from]==c && strncmp(&z[from],zDelim,nDelim)==0 ) break;
+            z[to++] = z[from++];
+          }
+          if( z[from] ){
+            z[to] = 0;
+            z += from + nDelim;
+            if( i<nField ) p->azField[i] = z;
+          }else{
+            z[to] = 0;
+            z = "";
           }
         }
         while( i<nField ){
index 97b42e5173d65a3ad2aab2e8c2cbc5858f4d9306..e7e415707f9a31a0ef41705adb55c0cdf41385ff 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the COPY statement.
 #
-# $Id: copy.test,v 1.4 2000/06/05 18:54:47 drh Exp $
+# $Id: copy.test,v 1.5 2000/06/07 01:27:49 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -102,11 +102,11 @@ do_test copy-1.7 {
 
 # Try copying into a table that has one or more indices.
 #
-execsql {DELETE FROM test1}
-execsql {CREATE INDEX index1 ON test1(one)}
-execsql {CREATE INDEX index2 ON test1(two)}
-execsql {CREATE INDEX index3 ON test1(three)}
 do_test copy-1.8 {
+  execsql {DELETE FROM test1}
+  execsql {CREATE INDEX index1 ON test1(one)}
+  execsql {CREATE INDEX index2 ON test1(two)}
+  execsql {CREATE INDEX index3 ON test1(three)}
   execsql {COPY test1 from 'data1.txt'}
   execsql {SELECT * FROM test1 WHERE one=11}
 } {11 22 33}
@@ -136,6 +136,20 @@ do_test copy-2.1 {
   execsql {SELECT x from test2}
 } $x
 
+# Test the escape character mechanism
+#
+do_test copy-3.1 {
+  set fd [open data6.txt w]
+  puts $fd "hello\\\tworld\t1"
+  puts $fd "hello\tworld\\\t2"
+  close $fd
+  execsql {
+    CREATE TABLE t1(a text, b text);
+    COPY t1 FROM 'data6.txt';
+    SELECT * FROM t1 ORDER BY a;
+  }
+} {hello {world        2} {hello       world} 1}
+
 # Cleanup 
 #
 file delete -force data1.txt data2.txt data3.txt data4.txt data5.txt data21.txt