From f0799fdf6d5516c69753260a3ba3a662266b5c67 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 15 Oct 2022 18:26:30 +0000 Subject: [PATCH] Add missing comments and fix other code issues. FossilOrigin-Name: 8ed4e4a80d8104d20b211a0b3e299abdb955cabdd36979bf6aae54266dc9778d --- ext/recover/sqlite3recover.c | 162 +++++++++++++++++++++++++++++++++-- manifest | 18 ++-- manifest.uuid | 2 +- 3 files changed, 164 insertions(+), 18 deletions(-) diff --git a/ext/recover/sqlite3recover.c b/ext/recover/sqlite3recover.c index 70f3386924..74b7f8a369 100644 --- a/ext/recover/sqlite3recover.c +++ b/ext/recover/sqlite3recover.c @@ -141,6 +141,11 @@ struct RecoverBitmap { u32 aElem[1]; /* Array of 32-bit bitmasks */ }; +/* +** State variables (part of the sqlite3_recover structure) used while +** recovering data for tables identified in the recovered schema (state +** RECOVER_STATE_WRITING). +*/ typedef struct RecoverStateW1 RecoverStateW1; struct RecoverStateW1 { sqlite3_stmt *pTbls; @@ -158,6 +163,11 @@ struct RecoverStateW1 { int iPrevCell; }; +/* +** State variables (part of the sqlite3_recover structure) used while +** recovering data destined for the lost and found table (states +** RECOVER_STATE_LOSTANDFOUND[123]). +*/ typedef struct RecoverStateLAF RecoverStateLAF; struct RecoverStateLAF { RecoverBitmap *pUsed; @@ -208,7 +218,7 @@ struct sqlite3_recover { /* Variables used with eState==RECOVER_STATE_WRITING */ RecoverStateW1 w1; - /* Variables used with states RECOVER_STATE_LOSTANDFOUND* */ + /* Variables used with states RECOVER_STATE_LOSTANDFOUND[123] */ RecoverStateLAF laf; /* Fields used within sqlite3_recover_run() */ @@ -265,7 +275,6 @@ static RecoverGlobal recover_g; #define RECOVER_MUTEX_ID SQLITE_MUTEX_STATIC_APP2 - /* ** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid). */ @@ -965,6 +974,11 @@ static int recoverOpenOutput(sqlite3_recover *p){ return p->errCode; } +/* +** Attach the auxiliary database 'recovery' to the output database handle. +** This temporary database is used during the recovery process and then +** discarded. +*/ static void recoverOpenRecovery(sqlite3_recover *p){ char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;", p->zStateDb); recoverExec(p, p->dbOut, zSql); @@ -1424,6 +1438,15 @@ static sqlite3_stmt *recoverLostAndFoundInsert( return pRet; } +/* +** Input database page iPg contains data that will be written to the +** lost-and-found table of the output database. This function attempts +** to identify the root page of the tree that page iPg belonged to. +** If successful, it sets output variable (*piRoot) to the page number +** of the root page and returns SQLITE_OK. Otherwise, if an error occurs, +** an SQLite error code is returned and the final value of *piRoot +** undefined. +*/ static int recoverLostAndFoundFindRoot( sqlite3_recover *p, i64 iPg, @@ -1454,6 +1477,10 @@ static int recoverLostAndFoundFindRoot( return p->errCode; } +/* +** Recover data from page iPage of the input database and write it to +** the lost-and-found table in the output database. +*/ static void recoverLostAndFoundOnePage(sqlite3_recover *p, i64 iPage){ RecoverStateLAF *pLaf = &p->laf; sqlite3_value **apVal = pLaf->apVal; @@ -1526,6 +1553,13 @@ static void recoverLostAndFoundOnePage(sqlite3_recover *p, i64 iPage){ } } +/* +** Perform one step (sqlite3_recover_step()) of work for the connection +** passed as the only argument, which is guaranteed to be in +** RECOVER_STATE_LOSTANDFOUND3 state - during which the lost-and-found +** table of the output database is populated with recovered data that can +** not be assigned to any recovered schema object. +*/ static int recoverLostAndFound3Step(sqlite3_recover *p){ RecoverStateLAF *pLaf = &p->laf; if( p->errCode==SQLITE_OK ){ @@ -1549,6 +1583,12 @@ static int recoverLostAndFound3Step(sqlite3_recover *p){ return SQLITE_OK; } +/* +** Initialize resources required in RECOVER_STATE_LOSTANDFOUND3 +** state - during which the lost-and-found table of the output database +** is populated with recovered data that can not be assigned to any +** recovered schema object. +*/ static void recoverLostAndFound3Init(sqlite3_recover *p){ RecoverStateLAF *pLaf = &p->laf; @@ -1578,6 +1618,11 @@ static void recoverLostAndFound3Init(sqlite3_recover *p){ } } +/* +** Initialize resources required in RECOVER_STATE_WRITING state - during which +** tables recovered from the schema of the input database are populated with +** recovered data. +*/ static int recoverWriteDataInit(sqlite3_recover *p){ RecoverStateW1 *p1 = &p->w1; RecoverTable *pTbl = 0; @@ -1635,6 +1680,12 @@ static void recoverWriteDataCleanup(sqlite3_recover *p){ memset(p1, 0, sizeof(*p1)); } +/* +** Perform one step (sqlite3_recover_step()) of work for the connection +** passed as the only argument, which is guaranteed to be in +** RECOVER_STATE_WRITING state - during which tables recovered from the +** schema of the input database are populated with recovered data. +*/ static int recoverWriteDataStep(sqlite3_recover *p){ RecoverStateW1 *p1 = &p->w1; sqlite3_stmt *pSel = p1->pSel; @@ -1756,6 +1807,11 @@ static int recoverWriteDataStep(sqlite3_recover *p){ return p->errCode; } +/* +** Initialize resources required by sqlite3_recover_step() in +** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not +** already allocated to a recovered schema element is determined. +*/ static void recoverLostAndFound1Init(sqlite3_recover *p){ RecoverStateLAF *pLaf = &p->laf; sqlite3_stmt *pStmt = 0; @@ -1802,6 +1858,12 @@ static void recoverLostAndFound1Init(sqlite3_recover *p){ pLaf->pUsedPages = pStmt; } +/* +** Perform one step (sqlite3_recover_step()) of work for the connection +** passed as the only argument, which is guaranteed to be in +** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not +** already allocated to a recovered schema element is determined. +*/ static int recoverLostAndFound1Step(sqlite3_recover *p){ RecoverStateLAF *pLaf = &p->laf; int rc = p->errCode; @@ -1819,6 +1881,11 @@ static int recoverLostAndFound1Step(sqlite3_recover *p){ return rc; } +/* +** Initialize resources required by RECOVER_STATE_LOSTANDFOUND2 +** state - during which the pages identified in RECOVER_STATE_LOSTANDFOUND1 +** are sorted into sets that likely belonged to the same database tree. +*/ static void recoverLostAndFound2Init(sqlite3_recover *p){ RecoverStateLAF *pLaf = &p->laf; @@ -1843,6 +1910,13 @@ static void recoverLostAndFound2Init(sqlite3_recover *p){ ); } +/* +** Perform one step (sqlite3_recover_step()) of work for the connection +** passed as the only argument, which is guaranteed to be in +** RECOVER_STATE_LOSTANDFOUND2 state - during which the pages identified +** in RECOVER_STATE_LOSTANDFOUND1 are sorted into sets that likely belonged +** to the same database tree. +*/ static int recoverLostAndFound2Step(sqlite3_recover *p){ RecoverStateLAF *pLaf = &p->laf; if( p->errCode==SQLITE_OK ){ @@ -1872,6 +1946,10 @@ static int recoverLostAndFound2Step(sqlite3_recover *p){ return p->errCode; } +/* +** Free all resources allocated as part of sqlite3_recover_step() calls +** in one of the RECOVER_STATE_LOSTANDFOUND[123] states. +*/ static void recoverLostAndFoundCleanup(sqlite3_recover *p){ recoverBitmapFree(p->laf.pUsed); p->laf.pUsed = 0; @@ -1895,6 +1973,9 @@ static void recoverLostAndFoundCleanup(sqlite3_recover *p){ p->laf.apVal = 0; } +/* +** Free all resources allocated as part of sqlite3_recover_step() calls. +*/ static void recoverFinalCleanup(sqlite3_recover *p){ RecoverTable *pTab = 0; RecoverTable *pNext = 0; @@ -1917,12 +1998,26 @@ static void recoverFinalCleanup(sqlite3_recover *p){ p->dbOut = 0; } +/* +** Decode and return an unsigned 16-bit big-endian integer value from +** buffer a[]. +*/ static u32 recoverGetU16(const u8 *a){ return (((u32)a[0])<<8) + ((u32)a[1]); } + +/* +** Decode and return an unsigned 32-bit big-endian integer value from +** buffer a[]. +*/ static u32 recoverGetU32(const u8 *a){ return (((u32)a[0])<<24) + (((u32)a[1])<<16) + (((u32)a[2])<<8) + ((u32)a[3]); } + +/* +** Decode an SQLite varint from buffer a[]. Write the decoded value to (*pVal) +** and return the number of bytes consumed. +*/ static int recoverGetVarint(const u8 *a, i64 *pVal){ sqlite3_int64 v = 0; int i; @@ -2077,10 +2172,17 @@ static int recoverVfsClose(sqlite3_file *pFd){ return pFd->pMethods->xClose(pFd); } +/* +** Write value v to buffer a[] as a 16-bit big-endian unsigned integer. +*/ static void recoverPutU16(u8 *a, u32 v){ a[0] = (v>>8) & 0x00FF; a[1] = (v>>0) & 0x00FF; } + +/* +** Write value v to buffer a[] as a 32-bit big-endian unsigned integer. +*/ static void recoverPutU32(u8 *a, u32 v){ a[0] = (v>>24) & 0x00FF; a[1] = (v>>16) & 0x00FF; @@ -2088,11 +2190,25 @@ static void recoverPutU32(u8 *a, u32 v){ a[3] = (v>>0) & 0x00FF; } +/* +** Detect the page-size of the database opened by file-handle pFd by +** searching the first part of the file for a well-formed SQLite b-tree +** page. If parameter nReserve is non-zero, then as well as searching for +** a b-tree page with zero reserved bytes, this function searches for one +** with nReserve reserved bytes at the end of it. +** +** If successful, set variable p->detected_pgsz to the detected page-size +** in bytes and return SQLITE_OK. Or, if no error occurs but no valid page +** can be found, return SQLITE_OK but leave p->detected_pgsz set to 0. Or, +** if an error occurs (e.g. an IO or OOM error), then an SQLite error code +** is returned. The final value of p->detected_pgsz is undefined in this +** case. +*/ static int recoverVfsDetectPagesize( - sqlite3_recover *p, - sqlite3_file *pFd, + sqlite3_recover *p, /* Recover handle */ + sqlite3_file *pFd, /* File-handle open on input database */ u32 nReserve, /* Possible nReserve value */ - i64 nSz + i64 nSz /* Size of database file in bytes */ ){ int rc = SQLITE_OK; const int nMin = 512; @@ -2142,6 +2258,10 @@ static int recoverVfsDetectPagesize( return rc; } +/* +** The xRead() method of the wrapper VFS. This is used to intercept calls +** to read page 1 of the input database. +*/ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){ int rc = SQLITE_OK; if( pFd->pMethods==&recover_methods ){ @@ -2252,6 +2372,9 @@ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){ return rc; } +/* +** Used to make sqlite3_io_methods wrapper methods less verbose. +*/ #define RECOVER_VFS_WRAPPER(code) \ int rc = SQLITE_OK; \ if( pFd->pMethods==&recover_methods ){ \ @@ -2263,6 +2386,12 @@ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){ } \ return rc; +/* +** Methods of the wrapper VFS. All methods except for xRead() and xClose() +** simply uninstall the sqlite3_io_methods wrapper, invoke the equivalent +** method on the lower level VFS, then reinstall the wrapper before returning. +** Those that return an integer value use the RECOVER_VFS_WRAPPER macro. +*/ static int recoverVfsWrite( sqlite3_file *pFd, const void *aBuf, int nByte, i64 iOff ){ @@ -2275,7 +2404,6 @@ static int recoverVfsTruncate(sqlite3_file *pFd, sqlite3_int64 size){ pFd->pMethods->xTruncate(pFd, size) ); } - static int recoverVfsSync(sqlite3_file *pFd, int flags){ RECOVER_VFS_WRAPPER ( pFd->pMethods->xSync(pFd, flags) @@ -2343,9 +2471,15 @@ static int recoverVfsShmUnmap(sqlite3_file *pFd, int deleteFlag){ ); } +/* +** Install the VFS wrapper around the file-descriptor open on the input +** database for recover handle p. Mutex RECOVER_MUTEX_ID must be held +** when this function is called. +*/ static void recoverInstallWrapper(sqlite3_recover *p){ sqlite3_file *pFd = 0; assert( recover_g.pMethods==0 ); + assert( sqlite3_mutex_held( sqlite3_mutex_alloc(RECOVER_MUTEX_ID) ) ); sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd); if( pFd ){ recover_g.pMethods = pFd->pMethods; @@ -2353,7 +2487,14 @@ static void recoverInstallWrapper(sqlite3_recover *p){ pFd->pMethods = &recover_methods; } } + +/* +** Uninstall the VFS wrapper that was installed around the file-descriptor open +** on the input database for recover handle p. Mutex RECOVER_MUTEX_ID must be +** held when this function is called. +*/ static void recoverUninstallWrapper(sqlite3_recover *p){ + assert( sqlite3_mutex_held( sqlite3_mutex_alloc(RECOVER_MUTEX_ID) ) ); if( recover_g.pMethods ){ sqlite3_file *pFd = 0; sqlite3_file_control(p->dbIn, p->zDb,SQLITE_FCNTL_FILE_POINTER,(void*)&pFd); @@ -2364,6 +2505,11 @@ static void recoverUninstallWrapper(sqlite3_recover *p){ } } +/* +** This function does the work of a single sqlite3_recover_step() call. It +** is guaranteed that the handle is not in an error state when this +** function is called. +*/ static void recoverStep(sqlite3_recover *p){ assert( p && p->errCode==SQLITE_OK ); switch( p->eState ){ @@ -2373,7 +2519,7 @@ static void recoverStep(sqlite3_recover *p){ recoverSqlCallback(p, "BEGIN"); recoverSqlCallback(p, "PRAGMA writable_schema = on"); - sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_APP2) ); + sqlite3_mutex_enter( sqlite3_mutex_alloc(RECOVER_MUTEX_ID) ); recoverInstallWrapper(p); /* Open the output database. And register required virtual tables and @@ -2390,7 +2536,7 @@ static void recoverStep(sqlite3_recover *p){ recoverCacheSchema(p); recoverUninstallWrapper(p); - sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_APP2) ); + sqlite3_mutex_leave( sqlite3_mutex_alloc(RECOVER_MUTEX_ID) ); recoverExec(p, p->dbOut, "BEGIN"); diff --git a/manifest b/manifest index 6ea8d64d5c..a8752032f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges. -D 2022-10-15T15:39:46.578 +C Add\smissing\scomments\sand\sfix\sother\scode\sissues. +D 2022-10-15T18:26:30.696 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -398,7 +398,7 @@ F ext/recover/recoverpgsz.test 93e970eab05e4e89f8fd6b1bd23f9ec137ea09857e66ba0d4 F ext/recover/recoverrowid.test 1694a1a5526d825f71279f3d02ab02a1ee4c5265de18858bf54cb8ec54487ac8 F ext/recover/recoverslowidx.test f356bb9fba7ffd6fc50e045e419464f0129ac6e24decf6e919584f79c3493727 F ext/recover/recoversql.test f9872ff2114e13ffd8ee31e1de06919f62b9b48bc080191b5bd076d10becb60f -F ext/recover/sqlite3recover.c 3ab2017a947fa8c9286aa6257d0b19443ec04e557af9d989227b89f36ff50dd6 +F ext/recover/sqlite3recover.c db8f2166dbbdfc09a58a85f51f8e848858858ca8b4915a2f9c8cd5fd5ca536a8 F ext/recover/sqlite3recover.h f698ccc94bd4da38761035415ad08c4549a408491ff9fd5f52d34d2214f64e36 F ext/recover/test_recover.c 61ec931e47abca6b2210f46239cafd9f3060741605e3d3c45a7c7a53f63dd957 F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -486,7 +486,7 @@ F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb -F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c w ext/wasm/EXPORTED_FUNCTIONS.fiddle +F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle 0e88c8cfc3719e4b7e74980d9da664c709e68acf863e48386cda376edfd3bfb0 F ext/wasm/GNUmakefile 4ec270532b921c7c4b437fbdb06f6a0ce41f3bd874395ce70dbc933c8553efa9 F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8a3066 @@ -503,7 +503,7 @@ F ext/wasm/api/sqlite3-api-glue.js 842dc03783aecc951a543a209523343a6fda9af258fb0 F ext/wasm/api/sqlite3-api-oo1.js 00f5cfce0989d2e08d7b21765d703c69234245d03a0cce8fcb32ccfcd53ffdbb F ext/wasm/api/sqlite3-api-opfs.js 5a8ab3b76880c8ada8710ca9ba1ca5b160872edfd8bd5322e4f179a7f41cc616 F ext/wasm/api/sqlite3-api-prologue.js b7c82a22d50658a48463fa646a23135273bc2cfa843aedda32627ff281c12e4d -F ext/wasm/api/sqlite3-api-worker1.js 7f4f46cb6b512a48572d7567233896e6a9c46570c44bdc3d13419730c7c221c8 w ext/wasm/api/sqlite3-api-worker.js +F ext/wasm/api/sqlite3-api-worker1.js 7f4f46cb6b512a48572d7567233896e6a9c46570c44bdc3d13419730c7c221c8 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 F ext/wasm/api/sqlite3-wasm.c 4c131945ced4b08a694d287abcdb066b896d961ef79ee5241805ecc37e83d63a F ext/wasm/batch-runner.html cf1a410c92bad50fcec2ddc71390b4e9df63a6ea1bef12a5163a66a0af4d78d9 @@ -536,7 +536,7 @@ F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d826 F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5 F ext/wasm/sqlite3-opfs-async-proxy.js 206ce6bbc3c30ad51a37d9c25e3a2712e70b586e0f9a2cf8cb0b9619017c2671 F ext/wasm/sqlite3-worker1-promiser.js 307d7837420ca6a9d3780dfc81194f1c0715637e6d9540e935514086b96913d8 -F ext/wasm/sqlite3-worker1.js 466e9bd39409ab03f3e00999887aaffc11e95b416e2689596e3d7f1516673fdf w ext/wasm/api/sqlite3-worker.js +F ext/wasm/sqlite3-worker1.js 466e9bd39409ab03f3e00999887aaffc11e95b416e2689596e3d7f1516673fdf F ext/wasm/test-opfs-vfs.html eb69dda21eb414b8f5e3f7c1cc0f774103cc9c0f87b2d28a33419e778abfbab5 F ext/wasm/test-opfs-vfs.js 56c3d725044c668fa7910451e96c1195d25ad95825f9ac79f747a7759d1973d0 F ext/wasm/tester1-worker.html 0af7a22025ff1da72a84765d64f8f221844a57c6e6e314acf3a30f176101fd3f @@ -2046,8 +2046,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 52d0235ef3f21683daadf2343514f7b95a67c3589266f75c1e00e04f11dc6214 ed14863dd72e35fa3a23320c3d5a8166515faea39a555c28a27b2d35e701eac4 -R 67f4b2d0a660b4df4f4f8911e9f69960 +P 42255ead8e44b24a8abc04aca49f170c55f3b52f42366a0d8ef248ee65fcc7ce +R ba398a54428773327d217095fdca83a1 U dan -Z 2f155b3b54b3254ee16d85f44719ac5e +Z 9c11c46950d6b0a76e0307ada9a3c264 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c99ce61654..49018171fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42255ead8e44b24a8abc04aca49f170c55f3b52f42366a0d8ef248ee65fcc7ce \ No newline at end of file +8ed4e4a80d8104d20b211a0b3e299abdb955cabdd36979bf6aae54266dc9778d \ No newline at end of file