mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Update the recovery extension so that it works with encrypted databases.
FossilOrigin-Name: b0b66f21159b47e1950ca63a01f92fe4f621efb9a2962b310d65fa7ebdbb43b3
This commit is contained in:
@ -2574,37 +2574,52 @@ 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");
|
||||
|
||||
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);
|
||||
/* 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)
|
||||
);
|
||||
}
|
||||
|
||||
recoverUninstallWrapper(p);
|
||||
recoverLeaveMutex();
|
||||
|
||||
recoverExec(p, p->dbOut, "BEGIN");
|
||||
|
||||
recoverWriteSchema1(p);
|
||||
p->eState = RECOVER_STATE_WRITING;
|
||||
break;
|
||||
}
|
||||
|
||||
case RECOVER_STATE_WRITING: {
|
||||
if( p->w1.pTbls==0 ){
|
||||
|
Reference in New Issue
Block a user