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:
12
manifest
12
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)
|
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-29T23:42:14
|
D 2004-08-30T01:54:05
|
||||||
F Makefile.in 65a7c43fcaf9a710d62f120b11b6e435eeb4a450
|
F Makefile.in 65a7c43fcaf9a710d62f120b11b6e435eeb4a450
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@@ -59,7 +59,7 @@ F src/pragma.c a7cea75286fcff6666a5412b04478fcf0ecef5c4
|
|||||||
F src/printf.c 17b28a1eedfe8129b05de981719306c18c3f1327
|
F src/printf.c 17b28a1eedfe8129b05de981719306c18c3f1327
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||||
F src/select.c 400b2dcc8e05c0101a65a370f7ebb33c9c85f0b3
|
F src/select.c 400b2dcc8e05c0101a65a370f7ebb33c9c85f0b3
|
||||||
F src/shell.c 42f65424a948f197f389e13bc7aaa3cf24dafd0c
|
F src/shell.c 64932b37d79baffd34544172c14c99b2e08a11bb
|
||||||
F src/sqlite.h.in b89ced1acc705bc9c79a2a4e725ac0eb64bd0614
|
F src/sqlite.h.in b89ced1acc705bc9c79a2a4e725ac0eb64bd0614
|
||||||
F src/sqliteInt.h c7ed161ecc40f9fd0f080fbcc00e34bd7d6735ee
|
F src/sqliteInt.h c7ed161ecc40f9fd0f080fbcc00e34bd7d6735ee
|
||||||
F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
|
F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
|
||||||
@@ -245,7 +245,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
|||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 32c2974af67abbbfa75c46afdab59ea6d5c15beb
|
P 431f7436a680b7c520aa559b0bf8619d7faba8c1
|
||||||
R 3347a7f98eb5a4e40a0194704c888c75
|
R c2bf0d7faa9695ce4fed9fa1b1ba2f22
|
||||||
U drh
|
U drh
|
||||||
Z 011af6407c824924cbc813caa53fa330
|
Z d01d7107b6d7cfa828846c09e3df38dc
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
431f7436a680b7c520aa559b0bf8619d7faba8c1
|
d3f3acb77f4e9f597af5afac565916b9c5e1c5d6
|
||||||
90
src/shell.c
90
src/shell.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains code to implement the "sqlite" command line
|
** This file contains code to implement the "sqlite" command line
|
||||||
** utility for accessing SQLite databases.
|
** 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 <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -556,6 +556,27 @@ static char * appendText(char *zIn, char const *zAppend, char quote){
|
|||||||
return zIn;
|
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.
|
** This is a different callback routine used for dumping the database.
|
||||||
** Each row received by this callback consists of a table name,
|
** 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 ){
|
if( strcmp(zType, "table")==0 ){
|
||||||
sqlite3_stmt *pTableInfo = 0;
|
sqlite3_stmt *pTableInfo = 0;
|
||||||
sqlite3_stmt *pSelect = 0;
|
|
||||||
char *zSelect = 0;
|
char *zSelect = 0;
|
||||||
char *zTableInfo = 0;
|
char *zTableInfo = 0;
|
||||||
char *zTmp = 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, "|| ')' FROM ", 0);
|
||||||
zSelect = appendText(zSelect, zTable, '"');
|
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( 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 ){
|
if( rc!=SQLITE_OK ){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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
|
** Text of a help message
|
||||||
*/
|
*/
|
||||||
@@ -799,22 +837,26 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
open_db(p);
|
open_db(p);
|
||||||
fprintf(p->out, "BEGIN TRANSACTION;\n");
|
fprintf(p->out, "BEGIN TRANSACTION;\n");
|
||||||
if( nArg==1 ){
|
if( nArg==1 ){
|
||||||
sqlite3_exec(p->db,
|
run_schema_dump_query(p,
|
||||||
"SELECT name, type, sql FROM sqlite_master "
|
"SELECT name, type, sql FROM sqlite_master "
|
||||||
"WHERE type!='meta' AND sql NOT NULL "
|
"WHERE sql NOT NULL AND type=='table'", 0
|
||||||
"ORDER BY substr(type,2,1), name",
|
);
|
||||||
dump_callback, p, &zErrMsg
|
run_schema_dump_query(p,
|
||||||
|
"SELECT name, type, sql FROM sqlite_master "
|
||||||
|
"WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0
|
||||||
);
|
);
|
||||||
}else{
|
}else{
|
||||||
int i;
|
int i;
|
||||||
for(i=1; i<nArg && zErrMsg==0; i++){
|
for(i=1; i<nArg; i++){
|
||||||
zShellStatic = azArg[i];
|
zShellStatic = azArg[i];
|
||||||
sqlite3_exec(p->db,
|
run_schema_dump_query(p,
|
||||||
"SELECT name, type, sql FROM sqlite_master "
|
"SELECT name, type, sql FROM sqlite_master "
|
||||||
"WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOT NULL "
|
"WHERE tbl_name LIKE shellstatic() AND type=='table'"
|
||||||
"ORDER BY substr(type,2,1), name",
|
" AND sql NOT NULL", 0);
|
||||||
dump_callback, p, &zErrMsg
|
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;
|
zShellStatic = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user