** 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. */
| 15308 | ** already allocated to a recovered schema element is determined. |
| 15309 | */ |
| 15310 | static void recoverLostAndFound1Init(sqlite3_recover *p){ |
| 15311 | RecoverStateLAF *pLaf = &p->laf; |
| 15312 | sqlite3_stmt *pStmt = 0; |
| 15313 | |
| 15314 | assert( p->laf.pUsed==0 ); |
| 15315 | pLaf->nPg = recoverPageCount(p); |
| 15316 | pLaf->pUsed = recoverBitmapAlloc(p, pLaf->nPg); |
| 15317 | |
| 15318 | /* Prepare a statement to iterate through all pages that are part of any tree |
| 15319 | ** in the recoverable part of the input database schema to the bitmap. And, |
| 15320 | ** if !p->bFreelistCorrupt, add all pages that appear to be part of the |
| 15321 | ** freelist. */ |
| 15322 | pStmt = recoverPrepare( |
| 15323 | p, p->dbOut, |
| 15324 | "WITH trunk(pgno) AS (" |
| 15325 | " SELECT read_i32(getpage(1), 8) AS x WHERE x>0" |
| 15326 | " UNION" |
| 15327 | " SELECT read_i32(getpage(trunk.pgno), 0) AS x FROM trunk WHERE x>0" |
| 15328 | ")," |
| 15329 | "trunkdata(pgno, data) AS (" |
| 15330 | " SELECT pgno, getpage(pgno) FROM trunk" |
| 15331 | ")," |
| 15332 | "freelist(data, n, freepgno) AS (" |
| 15333 | " SELECT data, min(16384, read_i32(data, 1)-1), pgno FROM trunkdata" |
| 15334 | " UNION ALL" |
| 15335 | " SELECT data, n-1, read_i32(data, 2+n) FROM freelist WHERE n>=0" |
| 15336 | ")," |
| 15337 | "" |
| 15338 | "roots(r) AS (" |
| 15339 | " SELECT 1 UNION ALL" |
| 15340 | " SELECT rootpage FROM recovery.schema WHERE rootpage>0" |
| 15341 | ")," |
| 15342 | "used(page) AS (" |
| 15343 | " SELECT r FROM roots" |
| 15344 | " UNION" |
| 15345 | " SELECT child FROM sqlite_dbptr('getpage()'), used " |
| 15346 | " WHERE pgno=page" |
| 15347 | ") " |
| 15348 | "SELECT page FROM used" |
| 15349 | " UNION ALL " |
| 15350 | "SELECT freepgno FROM freelist WHERE NOT ?" |
| 15351 | ); |
| 15352 | if( pStmt ) sqlite3_bind_int(pStmt, 1, p->bFreelistCorrupt); |
| 15353 | pLaf->pUsedPages = pStmt; |
| 15354 | } |
| 15355 | |
| 15356 | /* |
| 15357 | ** Perform one step (sqlite3_recover_step()) of work for the connection |
no test coverage detected