From: drh Date: Mon, 30 Aug 2004 01:54:05 +0000 (+0000) Subject: Modify the sqlite shell program so that the ".dump" command does not give up X-Git-Tag: version-3.6.10~4227 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dd3d4598bf97f253f6d91996a9af2708e225c192;p=thirdparty%2Fsqlite.git Modify the sqlite shell program so that the ".dump" command does not give up 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 --- diff --git a/manifest b/manifest index 017c2bd0db..f1be02c556 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index d02cb3f821..e94e66fe0f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -431f7436a680b7c520aa559b0bf8619d7faba8c1 \ No newline at end of file +d3f3acb77f4e9f597af5afac565916b9c5e1c5d6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 8f444fba38..f1b4dac272 100644 --- a/src/shell.c +++ b/src/shell.c @@ -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 #include @@ -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; idb, + 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; } }