]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify the sqlite shell program so that the ".dump" command does not give up
authordrh <drh@noemail.net>
Mon, 30 Aug 2004 01:54:05 +0000 (01:54 +0000)
committerdrh <drh@noemail.net>
Mon, 30 Aug 2004 01:54:05 +0000 (01:54 +0000)
if it encounters an SQLITE_CORRUPT error.  It tries to keep going in order
to extract as much information as it can from the corrupt database. (CVS 1919)

FossilOrigin-Name: d3f3acb77f4e9f597af5afac565916b9c5e1c5d6

manifest
manifest.uuid
src/shell.c

index 017c2bd0db5600bbb6cf8c1db429b3fb95518825..f1be02c556fd5d1af5158aee2d1fefc66d69b352 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sthe\sname\sof\sthe\sglobal\svariable\sto\ssqlite3_temp_directory\sto\navoid\sa\snaming\sconflict\swith\sversion\s2.8.\s(CVS\s1918)
-D 2004-08-29T23:42:14
+C Modify\sthe\ssqlite\sshell\sprogram\sso\sthat\sthe\s".dump"\scommand\sdoes\snot\sgive\sup\nif\sit\sencounters\san\sSQLITE_CORRUPT\serror.\s\sIt\stries\sto\skeep\sgoing\sin\sorder\nto\sextract\sas\smuch\sinformation\sas\sit\scan\sfrom\sthe\scorrupt\sdatabase.\s(CVS\s1919)
+D 2004-08-30T01:54:05
 F Makefile.in 65a7c43fcaf9a710d62f120b11b6e435eeb4a450
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -59,7 +59,7 @@ F src/pragma.c a7cea75286fcff6666a5412b04478fcf0ecef5c4
 F src/printf.c 17b28a1eedfe8129b05de981719306c18c3f1327
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 400b2dcc8e05c0101a65a370f7ebb33c9c85f0b3
-F src/shell.c 42f65424a948f197f389e13bc7aaa3cf24dafd0c
+F src/shell.c 64932b37d79baffd34544172c14c99b2e08a11bb
 F src/sqlite.h.in b89ced1acc705bc9c79a2a4e725ac0eb64bd0614
 F src/sqliteInt.h c7ed161ecc40f9fd0f080fbcc00e34bd7d6735ee
 F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
@@ -245,7 +245,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 32c2974af67abbbfa75c46afdab59ea6d5c15beb
-R 3347a7f98eb5a4e40a0194704c888c75
+P 431f7436a680b7c520aa559b0bf8619d7faba8c1
+R c2bf0d7faa9695ce4fed9fa1b1ba2f22
 U drh
-Z 011af6407c824924cbc813caa53fa330
+Z d01d7107b6d7cfa828846c09e3df38dc
index d02cb3f821b0f832759633067809b6223d280c0c..e94e66fe0fa0c46cb54640f178d9e94c52ebe034 100644 (file)
@@ -1 +1 @@
-431f7436a680b7c520aa559b0bf8619d7faba8c1
\ No newline at end of file
+d3f3acb77f4e9f597af5afac565916b9c5e1c5d6
\ No newline at end of file
index 8f444fba38ce1178cf898800f1a7f42428336e30..f1b4dac2725d9596afbd69d7d02e6ad05a7e0722 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains code to implement the "sqlite" command line
 ** utility for accessing SQLite databases.
 **
-** $Id: shell.c,v 1.111 2004/08/14 18:18:44 drh Exp $
+** $Id: shell.c,v 1.112 2004/08/30 01:54:05 drh Exp $
 */
 #include <stdlib.h>
 #include <string.h>
@@ -556,6 +556,27 @@ static char * appendText(char *zIn, char const *zAppend, char quote){
   return zIn;
 }
 
+
+/*
+** Execute a query statement that has a single result column.  Print
+** that result column on a line by itself with a semicolon terminator.
+*/
+static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
+  sqlite3_stmt *pSelect;
+  int rc;
+  rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
+  if( rc!=SQLITE_OK || !pSelect ){
+    return rc;
+  }
+  rc = sqlite3_step(pSelect);
+  while( rc==SQLITE_ROW ){
+    fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
+    rc = sqlite3_step(pSelect);
+  }
+  return sqlite3_finalize(pSelect);
+}
+
+
 /*
 ** This is a different callback routine used for dumping the database.
 ** Each row received by this callback consists of a table name,
@@ -578,7 +599,6 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
 
   if( strcmp(zType, "table")==0 ){
     sqlite3_stmt *pTableInfo = 0;
-    sqlite3_stmt *pSelect = 0;
     char *zSelect = 0;
     char *zTableInfo = 0;
     char *zTmp = 0;
@@ -618,26 +638,44 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
     zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
     zSelect = appendText(zSelect, zTable, '"');
 
-    rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
-    if( zSelect ) free(zSelect);
-    if( rc!=SQLITE_OK || !pSelect ){
-      return 1;
-    }
-
-    rc = sqlite3_step(pSelect);
-    while( rc==SQLITE_ROW ){
-      fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0));
-      rc = sqlite3_step(pSelect);
+    rc = run_table_dump_query(p->out, p->db, zSelect);
+    if( rc==SQLITE_CORRUPT ){
+      zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
+      rc = run_table_dump_query(p->out, p->db, zSelect);
     }
-    rc = sqlite3_finalize(pSelect);
+    if( zSelect ) free(zSelect);
     if( rc!=SQLITE_OK ){
       return 1;
     }
   }
-
   return 0;
 }
 
+/*
+** Run zQuery.  Update dump_callback() as the callback routine.
+** If we get a SQLITE_CORRUPT error, rerun the query after appending
+** "ORDER BY rowid DESC" to the end.
+*/
+static int run_schema_dump_query(
+  struct callback_data *p, 
+  const char *zQuery,
+  char **pzErrMsg
+){
+  int rc;
+  rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
+  if( rc==SQLITE_CORRUPT ){
+    char *zQ2;
+    int len = strlen(zQuery);
+    if( pzErrMsg ) sqlite3_free(*pzErrMsg);
+    zQ2 = malloc( len+100 );
+    if( zQ2==0 ) return rc;
+    sprintf(zQ2, "%s ORDER BY rowid DESC", zQuery);
+    rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
+    free(zQ2);
+  }
+  return rc;
+}
+
 /*
 ** Text of a help message
 */
@@ -799,22 +837,26 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     open_db(p);
     fprintf(p->out, "BEGIN TRANSACTION;\n");
     if( nArg==1 ){
-      sqlite3_exec(p->db,
+      run_schema_dump_query(p, 
+        "SELECT name, type, sql FROM sqlite_master "
+        "WHERE sql NOT NULL AND type=='table'", 0
+      );
+      run_schema_dump_query(p, 
         "SELECT name, type, sql FROM sqlite_master "
-        "WHERE type!='meta' AND sql NOT NULL "
-        "ORDER BY substr(type,2,1), name",
-        dump_callback, p, &zErrMsg
+        "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0
       );
     }else{
       int i;
-      for(i=1; i<nArg && zErrMsg==0; i++){
+      for(i=1; i<nArg; i++){
         zShellStatic = azArg[i];
-        sqlite3_exec(p->db,
+        run_schema_dump_query(p,
           "SELECT name, type, sql FROM sqlite_master "
-          "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOT NULL "
-          "ORDER BY substr(type,2,1), name",
-          dump_callback, p, &zErrMsg
-        );
+          "WHERE tbl_name LIKE shellstatic() AND type=='table'"
+          "  AND sql NOT NULL", 0);
+        run_schema_dump_query(p,
+          "SELECT name, type, sql FROM sqlite_master "
+          "WHERE tbl_name LIKE shellstatic() AND type!='table'"
+          "  AND type!='meta' AND sql NOT NULL", 0);
         zShellStatic = 0;
       }
     }