aboutsummaryrefslogtreecommitdiff
path: root/ext/recover/sqlite3recover.c
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2025-03-14 11:14:52 +0000
committerstephan <stephan@noemail.net>2025-03-14 11:14:52 +0000
commit5390f95f071ae83d2d89742b7a94ec1bfec6f6ff (patch)
tree3eba9019d68ded8463afa908365f262326ede5d9 /ext/recover/sqlite3recover.c
parent69eaadbee3dc5912aba995288bfb20eeeb1222e6 (diff)
parent1560045c328e5dc3b9a09e9c975b8626f984ef4f (diff)
downloadsqlite-5390f95f071ae83d2d89742b7a94ec1bfec6f6ff.tar.gz
sqlite-5390f95f071ae83d2d89742b7a94ec1bfec6f6ff.zip
Minor doc corrections for the sahpool-digest fix and merge in current trunk.
FossilOrigin-Name: 500f2e6ec74b4c0e4ac0365ba4e0d81ed6df8dd09dc0f8af65d294c3453f8865
Diffstat (limited to 'ext/recover/sqlite3recover.c')
-rw-r--r--ext/recover/sqlite3recover.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/ext/recover/sqlite3recover.c b/ext/recover/sqlite3recover.c
index 58d726f59..b13719083 100644
--- a/ext/recover/sqlite3recover.c
+++ b/ext/recover/sqlite3recover.c
@@ -2574,37 +2574,53 @@ static void recoverUninstallWrapper(sqlite3_recover *p){
static void recoverStep(sqlite3_recover *p){
assert( p && p->errCode==SQLITE_OK );
switch( p->eState ){
- case RECOVER_STATE_INIT:
+ case RECOVER_STATE_INIT: {
+ int bUseWrapper = 1;
/* This is the very first call to sqlite3_recover_step() on this object.
*/
recoverSqlCallback(p, "BEGIN");
recoverSqlCallback(p, "PRAGMA writable_schema = on");
+ recoverSqlCallback(p, "PRAGMA foreign_keys = off");
recoverEnterMutex();
- recoverInstallWrapper(p);
/* Open the output database. And register required virtual tables and
** user functions with the new handle. */
recoverOpenOutput(p);
- /* Open transactions on both the input and output databases. */
- sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
- recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
- recoverExec(p, p->dbIn, "BEGIN");
- if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
- recoverExec(p, p->dbIn, "SELECT 1 FROM sqlite_schema");
- recoverTransferSettings(p);
- recoverOpenRecovery(p);
- recoverCacheSchema(p);
-
- recoverUninstallWrapper(p);
- recoverLeaveMutex();
+ /* Attempt to open a transaction and read page 1 of the input database.
+ ** Two attempts may be made - one with a wrapper installed to ensure
+ ** that the database header is sane, and then if that attempt returns
+ ** SQLITE_NOTADB, then again with no wrapper. The second attempt is
+ ** required for encrypted databases. */
+ if( p->errCode==SQLITE_OK ){
+ do{
+ p->errCode = SQLITE_OK;
+ if( bUseWrapper ) recoverInstallWrapper(p);
+
+ /* Open a transaction on the input database. */
+ sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
+ recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
+ recoverExec(p, p->dbIn, "BEGIN");
+ if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
+ recoverExec(p, p->dbIn, "SELECT 1 FROM sqlite_schema");
+ recoverTransferSettings(p);
+ recoverOpenRecovery(p);
+ recoverCacheSchema(p);
+
+ if( bUseWrapper ) recoverUninstallWrapper(p);
+ }while( p->errCode==SQLITE_NOTADB
+ && (bUseWrapper--)
+ && SQLITE_OK==sqlite3_exec(p->dbIn, "ROLLBACK", 0, 0, 0)
+ );
+ }
+ recoverLeaveMutex();
recoverExec(p, p->dbOut, "BEGIN");
-
recoverWriteSchema1(p);
p->eState = RECOVER_STATE_WRITING;
break;
+ }
case RECOVER_STATE_WRITING: {
if( p->w1.pTbls==0 ){