Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a bug preventing .recover from working on databases where the final page of the db is corrupt. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | dbdata |
Files: | files | file ages | folders |
SHA3-256: |
959bbd11e92cc789973daf20dfcb8a6d |
User & Date: | dan 2019-04-25 16:20:40.499 |
Context
2019-04-25
| ||
19:23 | Unless the "--freelist-corrupt" option is specified, do not have the .recover command attempt to recover data from pages that are on the database free-list. (check-in: 8d2f52bb64 user: dan tags: dbdata) | |
16:20 | Fix a bug preventing .recover from working on databases where the final page of the db is corrupt. (check-in: 959bbd11e9 user: dan tags: dbdata) | |
2019-04-24
| ||
20:48 | Improve the performance of the .recover command. (check-in: a50768314d user: dan tags: dbdata) | |
Changes
Changes to src/shell.c.in.
︙ | ︙ | |||
6365 6366 6367 6368 6369 6370 6371 | } /* ** This function is called to recover data from the database. A script ** to construct a new database containing all recovered data is output ** on stream pState->out. */ | | | 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 | } /* ** This function is called to recover data from the database. A script ** to construct a new database containing all recovered data is output ** on stream pState->out. */ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ int rc = SQLITE_OK; sqlite3_stmt *pLoop = 0; /* Loop through all root pages */ sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */ sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */ shellExec(pState->db, &rc, /* Attach an in-memory database named 'recovery'. Create an indexed |
︙ | ︙ | |||
6402 6403 6404 6405 6406 6407 6408 | "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT" ");" /* Populate table [map]. If there are circular loops of pages in the ** database, the following adds all pages in such a loop to the map ** as individual root pages. This could be handled better. */ "WITH pages(i, maxlen) AS (" | | | > | 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 | "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT" ");" /* Populate table [map]. If there are circular loops of pages in the ** database, the following adds all pages in such a loop to the map ** as individual root pages. This could be handled better. */ "WITH pages(i, maxlen) AS (" " SELECT page_count, (" " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count" " ) FROM pragma_page_count" " UNION ALL" " SELECT i-1, (" " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1" " ) FROM pages WHERE i>=2" ")" "INSERT INTO recovery.map(pgno, maxlen, intkey, root) " " SELECT i, maxlen, NULL, (" |
︙ | ︙ | |||
6827 6828 6829 6830 6831 6832 6833 | if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){ rc = shell_dbinfo_command(p, nArg, azArg); }else if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){ open_db(p, 0); | | | 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 | if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){ rc = shell_dbinfo_command(p, nArg, azArg); }else if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){ open_db(p, 0); rc = recoverDatabaseCmd(p, nArg, azArg); }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ const char *zLike = 0; int i; int savedShowHeader = p->showHeader; int savedShellFlags = p->shellFlgs; |
︙ | ︙ |