mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
Update things to use sqlite3_recover_step() internally.
FossilOrigin-Name: f4b15aad3005237b7ac507eed2b9b07e0f5c9407ab28f2656a21c9845f13d35f
This commit is contained in:
@ -203,7 +203,7 @@ do_test 12.1 {
|
|||||||
do_test 12.2 {
|
do_test 12.2 {
|
||||||
$R run
|
$R run
|
||||||
$R run
|
$R run
|
||||||
} {21}
|
} {0}
|
||||||
|
|
||||||
do_test 12.3 {
|
do_test 12.3 {
|
||||||
$R finish
|
$R finish
|
||||||
|
@ -178,20 +178,32 @@ struct sqlite3_recover {
|
|||||||
int errCode; /* For sqlite3_recover_errcode() */
|
int errCode; /* For sqlite3_recover_errcode() */
|
||||||
char *zErrMsg; /* For sqlite3_recover_errmsg() */
|
char *zErrMsg; /* For sqlite3_recover_errmsg() */
|
||||||
|
|
||||||
|
int eState;
|
||||||
|
int bCloseTransaction;
|
||||||
|
|
||||||
/* Variables used with eState==RECOVER_STATE_WRITING */
|
/* Variables used with eState==RECOVER_STATE_WRITING */
|
||||||
RecoverStateW1 w1;
|
RecoverStateW1 w1;
|
||||||
|
|
||||||
/* Fields used within sqlite3_recover_run() */
|
/* Fields used within sqlite3_recover_run() */
|
||||||
int bRun; /* True once _recover_run() has been called */
|
|
||||||
sqlite3 *dbOut; /* Output database */
|
sqlite3 *dbOut; /* Output database */
|
||||||
sqlite3_stmt *pGetPage; /* SELECT against input db sqlite_dbdata */
|
sqlite3_stmt *pGetPage; /* SELECT against input db sqlite_dbdata */
|
||||||
RecoverTable *pTblList; /* List of tables recovered from schema */
|
RecoverTable *pTblList; /* List of tables recovered from schema */
|
||||||
RecoverBitmap *pUsed; /* Used by recoverLostAndFound() */
|
RecoverBitmap *pUsed; /* Used by recoverLostAndFound() */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The various states in which an sqlite3_recover object may exist:
|
||||||
|
**
|
||||||
|
** RECOVER_STATE_INIT:
|
||||||
|
** The object is initially created in this state. sqlite3_recover_step()
|
||||||
|
** has yet to be called. This is the only state in which it is permitted
|
||||||
|
** to call sqlite3_recover_config().
|
||||||
|
*/
|
||||||
#define RECOVER_STATE_INIT 0
|
#define RECOVER_STATE_INIT 0
|
||||||
#define RECOVER_STATE_WRITING 1
|
#define RECOVER_STATE_WRITING 1
|
||||||
#define RECOVER_STATE_LOSTANDFOUND 2
|
#define RECOVER_STATE_LOSTANDFOUND 2
|
||||||
|
#define RECOVER_STATE_SCHEMA2 3
|
||||||
|
#define RECOVER_STATE_DONE 4
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid).
|
** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid).
|
||||||
@ -758,7 +770,7 @@ static int recoverOpenOutput(sqlite3_recover *p){
|
|||||||
"PRAGMA writable_schema = 1;"
|
"PRAGMA writable_schema = 1;"
|
||||||
"CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);"
|
"CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);"
|
||||||
"CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
|
"CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
|
||||||
);
|
);
|
||||||
sqlite3_free(zSql);
|
sqlite3_free(zSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1547,6 +1559,7 @@ static void recoverWriteDataCleanup(sqlite3_recover *p){
|
|||||||
recoverFinalize(p, p1->pInsert);
|
recoverFinalize(p, p1->pInsert);
|
||||||
recoverFinalize(p, p1->pTbls);
|
recoverFinalize(p, p1->pTbls);
|
||||||
recoverFinalize(p, p1->pSel);
|
recoverFinalize(p, p1->pSel);
|
||||||
|
memset(p1, 0, sizeof(*p1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int recoverWriteDataStep(sqlite3_recover *p){
|
static int recoverWriteDataStep(sqlite3_recover *p){
|
||||||
@ -1554,7 +1567,7 @@ static int recoverWriteDataStep(sqlite3_recover *p){
|
|||||||
sqlite3_stmt *pSel = p1->pSel;
|
sqlite3_stmt *pSel = p1->pSel;
|
||||||
sqlite3_value **apVal = p1->apVal;
|
sqlite3_value **apVal = p1->apVal;
|
||||||
|
|
||||||
if( p1->pTab==0 ){
|
if( p->errCode==SQLITE_OK && p1->pTab==0 ){
|
||||||
if( sqlite3_step(p1->pTbls)==SQLITE_ROW ){
|
if( sqlite3_step(p1->pTbls)==SQLITE_ROW ){
|
||||||
i64 iRoot = sqlite3_column_int64(p1->pTbls, 0);
|
i64 iRoot = sqlite3_column_int64(p1->pTbls, 0);
|
||||||
p1->pTab = recoverFindTable(p, iRoot);
|
p1->pTab = recoverFindTable(p, iRoot);
|
||||||
@ -1589,7 +1602,7 @@ static int recoverWriteDataStep(sqlite3_recover *p){
|
|||||||
return SQLITE_DONE;
|
return SQLITE_DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( p1->pTab );
|
assert( p->errCode!=SQLITE_OK || p1->pTab );
|
||||||
|
|
||||||
if( p->errCode==SQLITE_OK && sqlite3_step(pSel)==SQLITE_ROW ){
|
if( p->errCode==SQLITE_OK && sqlite3_step(pSel)==SQLITE_ROW ){
|
||||||
RecoverTable *pTab = p1->pTab;
|
RecoverTable *pTab = p1->pTab;
|
||||||
@ -1698,8 +1711,7 @@ static void recoverRun(sqlite3_recover *p){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
assert( p->errCode==SQLITE_OK );
|
assert( p->errCode==SQLITE_OK );
|
||||||
assert( p->bRun==0 );
|
p->eState = 1;
|
||||||
p->bRun = 1;
|
|
||||||
|
|
||||||
recoverSqlCallback(p, "BEGIN");
|
recoverSqlCallback(p, "BEGIN");
|
||||||
recoverSqlCallback(p, "PRAGMA writable_schema = on");
|
recoverSqlCallback(p, "PRAGMA writable_schema = on");
|
||||||
@ -1741,6 +1753,100 @@ static void recoverRun(sqlite3_recover *p){
|
|||||||
sqlite3_close(p->dbOut);
|
sqlite3_close(p->dbOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void recoverFinalCleanup(sqlite3_recover *p){
|
||||||
|
RecoverTable *pTab = 0;
|
||||||
|
RecoverTable *pNext = 0;
|
||||||
|
|
||||||
|
recoverWriteDataCleanup(p);
|
||||||
|
for(pTab=p->pTblList; pTab; pTab=pNext){
|
||||||
|
pNext = pTab->pNext;
|
||||||
|
sqlite3_free(pTab);
|
||||||
|
}
|
||||||
|
p->pTblList = 0;
|
||||||
|
sqlite3_finalize(p->pGetPage);
|
||||||
|
p->pGetPage = 0;
|
||||||
|
recoverBitmapFree(p->pUsed);
|
||||||
|
p->pUsed = 0;
|
||||||
|
{
|
||||||
|
int res = sqlite3_close(p->dbOut);
|
||||||
|
assert( res==SQLITE_OK );
|
||||||
|
}
|
||||||
|
p->dbOut = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recoverStep(sqlite3_recover *p){
|
||||||
|
assert( p && p->errCode==SQLITE_OK );
|
||||||
|
switch( p->eState ){
|
||||||
|
case RECOVER_STATE_INIT:
|
||||||
|
/* This is the very first call to sqlite3_recover_step() on this object.
|
||||||
|
*/
|
||||||
|
recoverSqlCallback(p, "BEGIN");
|
||||||
|
recoverSqlCallback(p, "PRAGMA writable_schema = on");
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
|
||||||
|
recoverExec(p, p->dbIn, "BEGIN");
|
||||||
|
if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
|
||||||
|
recoverExec(p, p->dbOut, "BEGIN");
|
||||||
|
|
||||||
|
recoverCacheSchema(p);
|
||||||
|
recoverWriteSchema1(p);
|
||||||
|
|
||||||
|
p->eState = RECOVER_STATE_WRITING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECOVER_STATE_WRITING: {
|
||||||
|
if( p->w1.pTbls==0 ){
|
||||||
|
recoverWriteDataInit(p);
|
||||||
|
}
|
||||||
|
if( SQLITE_DONE==recoverWriteDataStep(p) ){
|
||||||
|
recoverWriteDataCleanup(p);
|
||||||
|
if( p->zLostAndFound ){
|
||||||
|
p->eState = RECOVER_STATE_LOSTANDFOUND;
|
||||||
|
}else{
|
||||||
|
p->eState = RECOVER_STATE_SCHEMA2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RECOVER_STATE_LOSTANDFOUND: {
|
||||||
|
recoverLostAndFound(p);
|
||||||
|
p->eState = RECOVER_STATE_SCHEMA2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RECOVER_STATE_SCHEMA2: {
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
|
recoverWriteSchema2(p);
|
||||||
|
p->eState = RECOVER_STATE_DONE;
|
||||||
|
|
||||||
|
/* If no error has occurred, commit the write transaction on the output
|
||||||
|
** database. Regardless of whether or not an error has occurred, make
|
||||||
|
** an attempt to end the read transaction on the input database. */
|
||||||
|
recoverExec(p, p->dbOut, "COMMIT");
|
||||||
|
rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
|
||||||
|
if( p->errCode==SQLITE_OK ) p->errCode = rc;
|
||||||
|
|
||||||
|
recoverSqlCallback(p, "PRAGMA writable_schema = off");
|
||||||
|
recoverSqlCallback(p, "COMMIT");
|
||||||
|
p->eState = RECOVER_STATE_DONE;
|
||||||
|
recoverFinalCleanup(p);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
case RECOVER_STATE_DONE: {
|
||||||
|
/* no-op */
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This is a worker function that does the heavy lifting for both init
|
** This is a worker function that does the heavy lifting for both init
|
||||||
@ -1866,14 +1972,24 @@ int sqlite3_recover_config(sqlite3_recover *p, int op, void *pArg){
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sqlite3_recover_step(sqlite3_recover *p){
|
||||||
|
if( p==0 ) return SQLITE_NOMEM;
|
||||||
|
if( p->errCode==SQLITE_OK ) recoverStep(p);
|
||||||
|
if( p->eState==RECOVER_STATE_DONE && p->errCode==SQLITE_OK ){
|
||||||
|
return SQLITE_DONE;
|
||||||
|
}
|
||||||
|
return p->errCode;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Do the configured recovery operation. Return SQLITE_OK if successful, or
|
** Do the configured recovery operation. Return SQLITE_OK if successful, or
|
||||||
** else an SQLite error code.
|
** else an SQLite error code.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
int sqlite3_recover_run(sqlite3_recover *p){
|
int sqlite3_recover_run(sqlite3_recover *p){
|
||||||
if( p ){
|
if( p ){
|
||||||
recoverExec(p, p->dbIn, "PRAGMA writable_schema=1");
|
recoverExec(p, p->dbIn, "PRAGMA writable_schema=1");
|
||||||
if( p->bRun ) return SQLITE_MISUSE; /* Has already run */
|
if( p->eState ) return SQLITE_MISUSE; /* Has already run */
|
||||||
if( p->errCode==SQLITE_OK ) recoverRun(p);
|
if( p->errCode==SQLITE_OK ) recoverRun(p);
|
||||||
if( sqlite3_exec(p->dbIn, "PRAGMA writable_schema=0", 0, 0, 0) ){
|
if( sqlite3_exec(p->dbIn, "PRAGMA writable_schema=0", 0, 0, 0) ){
|
||||||
recoverDbError(p, p->dbIn);
|
recoverDbError(p, p->dbIn);
|
||||||
@ -1881,6 +1997,14 @@ int sqlite3_recover_run(sqlite3_recover *p){
|
|||||||
}
|
}
|
||||||
return p ? p->errCode : SQLITE_NOMEM;
|
return p ? p->errCode : SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
int sqlite3_recover_run(sqlite3_recover *p){
|
||||||
|
if( p==0 ) return SQLITE_NOMEM;
|
||||||
|
while( SQLITE_OK==sqlite3_recover_step(p) );
|
||||||
|
return p->errCode;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Free all resources associated with the recover handle passed as the only
|
** Free all resources associated with the recover handle passed as the only
|
||||||
@ -1896,6 +2020,11 @@ int sqlite3_recover_finish(sqlite3_recover *p){
|
|||||||
if( p==0 ){
|
if( p==0 ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
|
recoverFinalCleanup(p);
|
||||||
|
if( p->bCloseTransaction && sqlite3_get_autocommit(p->dbIn)==0 ){
|
||||||
|
rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
|
||||||
|
if( p->errCode==SQLITE_OK ) p->errCode = rc;
|
||||||
|
}
|
||||||
rc = p->errCode;
|
rc = p->errCode;
|
||||||
sqlite3_free(p->zErrMsg);
|
sqlite3_free(p->zErrMsg);
|
||||||
sqlite3_free(p->zStateDb);
|
sqlite3_free(p->zStateDb);
|
||||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Internal\schanges\sto\sthe\srecover\sextension\stowards\sa\sstep()\sstyle\sinterface.
|
C Update\sthings\sto\suse\ssqlite3_recover_step()\sinternally.
|
||||||
D 2022-09-23T21:01:10.829
|
D 2022-09-24T18:05:52.914
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -387,7 +387,7 @@ F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2
|
|||||||
F ext/rbu/sqlite3rbu.c 8737cabdfbee84bb25a7851ecef8b1312be332761238da9be6ddb10c62ad4291
|
F ext/rbu/sqlite3rbu.c 8737cabdfbee84bb25a7851ecef8b1312be332761238da9be6ddb10c62ad4291
|
||||||
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
|
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
|
||||||
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
|
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
|
||||||
F ext/recover/recover1.test 3f26db7692ed98c0de4fc9511f3d3a2f2c91a137b7e6666f3b85b593438b5d09
|
F ext/recover/recover1.test 2b0f048ba572c3ca4e4235b632bf75702975a9656146eab766f6c75861f946a0
|
||||||
F ext/recover/recover_common.tcl 6679af7dffc858e345053a91c9b0a897595b4a13007aceffafca75304ccb137c
|
F ext/recover/recover_common.tcl 6679af7dffc858e345053a91c9b0a897595b4a13007aceffafca75304ccb137c
|
||||||
F ext/recover/recoverclobber.test 294dcc894124ab4ca3a7b35766630742a3d25810fceac22220beb64f70a33a60
|
F ext/recover/recoverclobber.test 294dcc894124ab4ca3a7b35766630742a3d25810fceac22220beb64f70a33a60
|
||||||
F ext/recover/recovercorrupt.test e3f3cbe0162ba681518aac9ea0ae8119f32ac93fb0900b5f09b6318966108e54
|
F ext/recover/recovercorrupt.test e3f3cbe0162ba681518aac9ea0ae8119f32ac93fb0900b5f09b6318966108e54
|
||||||
@ -397,7 +397,7 @@ F ext/recover/recoverfault2.test 321036336af23e778a87f148c4cc4407f88fbdab1fd72dd
|
|||||||
F ext/recover/recoverold.test 46e9d99b595fac583d4c67f74d7d89c20a435c752ef6eeb3e918b599940c88e0
|
F ext/recover/recoverold.test 46e9d99b595fac583d4c67f74d7d89c20a435c752ef6eeb3e918b599940c88e0
|
||||||
F ext/recover/recoverrowid.test 1694a1a5526d825f71279f3d02ab02a1ee4c5265de18858bf54cb8ec54487ac8
|
F ext/recover/recoverrowid.test 1694a1a5526d825f71279f3d02ab02a1ee4c5265de18858bf54cb8ec54487ac8
|
||||||
F ext/recover/recoversql.test f9872ff2114e13ffd8ee31e1de06919f62b9b48bc080191b5bd076d10becb60f
|
F ext/recover/recoversql.test f9872ff2114e13ffd8ee31e1de06919f62b9b48bc080191b5bd076d10becb60f
|
||||||
F ext/recover/sqlite3recover.c cfb2e7df6ac7405109fa4f04b9b1fea4dbb704f37985f2f34d5526949734817f
|
F ext/recover/sqlite3recover.c efed077977b195d2ac6c12f1485abf9c7e8c8d282834b05beee7151dabf21e88
|
||||||
F ext/recover/sqlite3recover.h 81108efb8c4618d3d9c6da4df785212b0e4501aa0d25edfc463405fe839a6640
|
F ext/recover/sqlite3recover.h 81108efb8c4618d3d9c6da4df785212b0e4501aa0d25edfc463405fe839a6640
|
||||||
F ext/recover/test_recover.c 72a765616a3fa9dae2ed537d79b00f365d9f639d347858341b71bda7a3a45f56
|
F ext/recover/test_recover.c 72a765616a3fa9dae2ed537d79b00f365d9f639d347858341b71bda7a3a45f56
|
||||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||||
@ -2013,8 +2013,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P ae49e9efde3012158061def6e0a8d993abbc5933514a21f84bc10f700f61b5e2
|
P 73926d5c8cd1ecece134b5a73b44ee1dfca74dc200606e3f009b06cdecf8cee9
|
||||||
R 84e101ee349aff282424e130c05c161d
|
R 0646ea13d6a7cac9dceb7b54cdbc6bf0
|
||||||
U dan
|
U dan
|
||||||
Z 2ba1da8e5fc1c584cb2093e5d330b18c
|
Z 958e4f167968f03754a4ebdb81e44d68
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
73926d5c8cd1ecece134b5a73b44ee1dfca74dc200606e3f009b06cdecf8cee9
|
f4b15aad3005237b7ac507eed2b9b07e0f5c9407ab28f2656a21c9845f13d35f
|
Reference in New Issue
Block a user