1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-06 15:49:35 +03:00

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
This commit is contained in:
drh
2004-08-30 01:54:05 +00:00
parent effd02bcbe
commit dd3d4598bf
3 changed files with 73 additions and 31 deletions

View File

@@ -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

View File

@@ -1 +1 @@
431f7436a680b7c520aa559b0bf8619d7faba8c1
d3f3acb77f4e9f597af5afac565916b9c5e1c5d6

View 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);
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);
}
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 = sqlite3_finalize(pSelect);
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 type!='meta' AND sql NOT NULL "
"ORDER BY substr(type,2,1), name",
dump_callback, p, &zErrMsg
"WHERE sql NOT NULL AND type=='table'", 0
);
run_schema_dump_query(p,
"SELECT name, type, sql FROM sqlite_master "
"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;
}
}