4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
16 #include "sqlite3recover.h"
20 #ifndef SQLITE_OMIT_VIRTUALTABLE
23 ** Declaration for public API function in file dbdata.c. This may be called
24 ** with NULL as the final two arguments to register the sqlite_dbptr and
25 ** sqlite_dbdata virtual tables with a database handle.
30 int sqlite3_dbdata_init(sqlite3
*, char**, const sqlite3_api_routines
*);
32 typedef unsigned int u32
;
33 typedef unsigned char u8
;
34 typedef sqlite3_int64 i64
;
36 typedef struct RecoverTable RecoverTable
;
37 typedef struct RecoverColumn RecoverColumn
;
40 ** When recovering rows of data that can be associated with table
41 ** definitions recovered from the sqlite_schema table, each table is
42 ** represented by an instance of the following object.
45 ** The root page in the original database. Not necessarily (and usually
46 ** not) the same in the recovered database.
52 ** aCol[] is an array of nCol columns. In the order in which they appear
56 ** Set to true for intkey tables, false for WITHOUT ROWID.
59 ** Each column in the aCol[] array has associated with it the index of
60 ** the bind parameter its values will be bound to in the INSERT statement
61 ** used to construct the output database. If the table does has a rowid
62 ** but not an INTEGER PRIMARY KEY column, then iRowidBind contains the
63 ** index of the bind paramater to which the rowid value should be bound.
64 ** Otherwise, it contains -1. If the table does contain an INTEGER PRIMARY
65 ** KEY column, then the rowid value should be bound to the index associated
69 ** All RecoverTable objects used by the recovery operation are allocated
70 ** and populated as part of creating the recovered database schema in
71 ** the output database, before any non-schema data are recovered. They
72 ** are then stored in a singly-linked list linked by this variable beginning
73 ** at sqlite3_recover.pTblList.
76 u32 iRoot
; /* Root page in original database */
77 char *zTab
; /* Name of table */
78 int nCol
; /* Number of columns in table */
79 RecoverColumn
*aCol
; /* Array of columns */
80 int bIntkey
; /* True for intkey, false for without rowid */
81 int iRowidBind
; /* If >0, bind rowid to INSERT here */
86 ** Each database column is represented by an instance of the following object
87 ** stored in the RecoverTable.aCol[] array of the associated table.
90 ** The index of the associated field within database records. Or -1 if
91 ** there is no associated field (e.g. for virtual generated columns).
94 ** The bind index of the INSERT statement to bind this columns values
95 ** to. Or 0 if there is no such index (iff (iField<0)).
98 ** True if this is the INTEGER PRIMARY KEY column.
104 ** A RECOVER_EHIDDEN_* constant value (see below for interpretation of each).
106 struct RecoverColumn
{
107 int iField
; /* Field in record on disk */
108 int iBind
; /* Binding to use in INSERT */
109 int bIPK
; /* True for IPK column */
114 #define RECOVER_EHIDDEN_NONE 0 /* Normal database column */
115 #define RECOVER_EHIDDEN_HIDDEN 1 /* Column is __HIDDEN__ */
116 #define RECOVER_EHIDDEN_VIRTUAL 2 /* Virtual generated column */
117 #define RECOVER_EHIDDEN_STORED 3 /* Stored generated column */
120 ** Bitmap object used to track pages in the input database. Allocated
121 ** and manipulated only by the following functions:
123 ** recoverBitmapAlloc()
124 ** recoverBitmapFree()
125 ** recoverBitmapSet()
126 ** recoverBitmapQuery()
129 ** Largest page number that may be stored in the bitmap. The range
130 ** of valid keys is 1 to nPg, inclusive.
133 ** Array large enough to contain a bit for each key. For key value
134 ** iKey, the associated bit is the bit (iKey%32) of aElem[iKey/32].
135 ** In other words, the following is true if bit iKey is set, or
136 ** false if it is clear:
138 ** (aElem[iKey/32] & (1 << (iKey%32))) ? 1 : 0
140 typedef struct RecoverBitmap RecoverBitmap
;
141 struct RecoverBitmap
{
142 i64 nPg
; /* Size of bitmap */
143 u32 aElem
[1]; /* Array of 32-bit bitmasks */
147 ** State variables (part of the sqlite3_recover structure) used while
148 ** recovering data for tables identified in the recovered schema (state
149 ** RECOVER_STATE_WRITING).
151 typedef struct RecoverStateW1 RecoverStateW1
;
152 struct RecoverStateW1
{
155 sqlite3_stmt
*pInsert
;
158 RecoverTable
*pTab
; /* Table currently being written */
159 int nMax
; /* Max column count in any schema table */
160 sqlite3_value
**apVal
; /* Array of nMax values */
161 int nVal
; /* Number of valid entries in apVal[] */
169 ** State variables (part of the sqlite3_recover structure) used while
170 ** recovering data destined for the lost and found table (states
171 ** RECOVER_STATE_LOSTANDFOUND[123]).
173 typedef struct RecoverStateLAF RecoverStateLAF
;
174 struct RecoverStateLAF
{
175 RecoverBitmap
*pUsed
;
176 i64 nPg
; /* Size of db in pages */
177 sqlite3_stmt
*pAllAndParent
;
178 sqlite3_stmt
*pMapInsert
;
179 sqlite3_stmt
*pMaxField
;
180 sqlite3_stmt
*pUsedPages
;
181 sqlite3_stmt
*pFindRoot
;
182 sqlite3_stmt
*pInsert
; /* INSERT INTO lost_and_found ... */
183 sqlite3_stmt
*pAllPage
;
184 sqlite3_stmt
*pPageData
;
185 sqlite3_value
**apVal
;
190 ** Main recover handle structure.
192 struct sqlite3_recover
{
193 /* Copies of sqlite3_recover_init[_sql]() parameters */
194 sqlite3
*dbIn
; /* Input database */
195 char *zDb
; /* Name of input db ("main" etc.) */
196 char *zUri
; /* URI for output database */
197 void *pSqlCtx
; /* SQL callback context */
198 int (*xSql
)(void*,const char*); /* Pointer to SQL callback function */
200 /* Values configured by sqlite3_recover_config() */
201 char *zStateDb
; /* State database to use (or NULL) */
202 char *zLostAndFound
; /* Name of lost-and-found table (or NULL) */
203 int bFreelistCorrupt
; /* SQLITE_RECOVER_FREELIST_CORRUPT setting */
204 int bRecoverRowid
; /* SQLITE_RECOVER_ROWIDS setting */
205 int bSlowIndexes
; /* SQLITE_RECOVER_SLOWINDEXES setting */
213 /* Error code and error message */
214 int errCode
; /* For sqlite3_recover_errcode() */
215 char *zErrMsg
; /* For sqlite3_recover_errmsg() */
218 int bCloseTransaction
;
220 /* Variables used with eState==RECOVER_STATE_WRITING */
223 /* Variables used with states RECOVER_STATE_LOSTANDFOUND[123] */
226 /* Fields used within sqlite3_recover_run() */
227 sqlite3
*dbOut
; /* Output database */
228 sqlite3_stmt
*pGetPage
; /* SELECT against input db sqlite_dbdata */
229 RecoverTable
*pTblList
; /* List of tables recovered from schema */
233 ** The various states in which an sqlite3_recover object may exist:
235 ** RECOVER_STATE_INIT:
236 ** The object is initially created in this state. sqlite3_recover_step()
237 ** has yet to be called. This is the only state in which it is permitted
238 ** to call sqlite3_recover_config().
240 ** RECOVER_STATE_WRITING:
242 ** RECOVER_STATE_LOSTANDFOUND1:
243 ** State to populate the bitmap of pages used by other tables or the
244 ** database freelist.
246 ** RECOVER_STATE_LOSTANDFOUND2:
247 ** Populate the recovery.map table - used to figure out a "root" page
248 ** for each lost page from in the database from which records are
251 ** RECOVER_STATE_LOSTANDFOUND3:
252 ** Populate the lost-and-found table itself.
254 #define RECOVER_STATE_INIT 0
255 #define RECOVER_STATE_WRITING 1
256 #define RECOVER_STATE_LOSTANDFOUND1 2
257 #define RECOVER_STATE_LOSTANDFOUND2 3
258 #define RECOVER_STATE_LOSTANDFOUND3 4
259 #define RECOVER_STATE_SCHEMA2 5
260 #define RECOVER_STATE_DONE 6
264 ** Global variables used by this extension.
266 typedef struct RecoverGlobal RecoverGlobal
;
267 struct RecoverGlobal
{
268 const sqlite3_io_methods
*pMethods
;
271 static RecoverGlobal recover_g
;
274 ** Use this static SQLite mutex to protect the globals during the
275 ** first call to sqlite3_recover_step().
277 #define RECOVER_MUTEX_ID SQLITE_MUTEX_STATIC_APP2
281 ** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid).
283 #define RECOVER_ROWID_DEFAULT 1
288 ** recoverEnterMutex() - Enter the recovery mutex
289 ** recoverLeaveMutex() - Leave the recovery mutex
290 ** recoverAssertMutexHeld() - Assert that the recovery mutex is held
292 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
293 # define recoverEnterMutex()
294 # define recoverLeaveMutex()
296 static void recoverEnterMutex(void){
297 sqlite3_mutex_enter(sqlite3_mutex_alloc(RECOVER_MUTEX_ID
));
299 static void recoverLeaveMutex(void){
300 sqlite3_mutex_leave(sqlite3_mutex_alloc(RECOVER_MUTEX_ID
));
303 #if SQLITE_THREADSAFE+0>=1 && defined(SQLITE_DEBUG)
304 static void recoverAssertMutexHeld(void){
305 assert( sqlite3_mutex_held(sqlite3_mutex_alloc(RECOVER_MUTEX_ID
)) );
308 # define recoverAssertMutexHeld()
313 ** Like strlen(). But handles NULL pointer arguments.
315 static int recoverStrlen(const char *zStr
){
316 if( zStr
==0 ) return 0;
317 return (int)(strlen(zStr
)&0x7fffffff);
321 ** This function is a no-op if the recover handle passed as the first
322 ** argument already contains an error (if p->errCode!=SQLITE_OK).
324 ** Otherwise, an attempt is made to allocate, zero and return a buffer nByte
325 ** bytes in size. If successful, a pointer to the new buffer is returned. Or,
326 ** if an OOM error occurs, NULL is returned and the handle error code
327 ** (p->errCode) set to SQLITE_NOMEM.
329 static void *recoverMalloc(sqlite3_recover
*p
, i64 nByte
){
332 if( p
->errCode
==SQLITE_OK
){
333 pRet
= sqlite3_malloc64(nByte
);
335 memset(pRet
, 0, nByte
);
337 p
->errCode
= SQLITE_NOMEM
;
344 ** Set the error code and error message for the recover handle passed as
345 ** the first argument. The error code is set to the value of parameter
348 ** Parameter zFmt must be a printf() style formatting string. The handle
349 ** error message is set to the result of using any trailing arguments for
350 ** parameter substitutions in the formatting string.
354 ** recoverError(p, SQLITE_ERROR, "no such table: %s", zTablename);
356 static int recoverError(
359 const char *zFmt
, ...
365 z
= sqlite3_vmprintf(zFmt
, ap
);
368 sqlite3_free(p
->zErrMsg
);
370 p
->errCode
= errCode
;
376 ** This function is a no-op if p->errCode is initially other than SQLITE_OK.
377 ** In this case it returns NULL.
379 ** Otherwise, an attempt is made to allocate and return a bitmap object
380 ** large enough to store a bit for all page numbers between 1 and nPg,
381 ** inclusive. The bitmap is initially zeroed.
383 static RecoverBitmap
*recoverBitmapAlloc(sqlite3_recover
*p
, i64 nPg
){
384 int nElem
= (nPg
+1+31) / 32;
385 int nByte
= sizeof(RecoverBitmap
) + nElem
*sizeof(u32
);
386 RecoverBitmap
*pRet
= (RecoverBitmap
*)recoverMalloc(p
, nByte
);
395 ** Free a bitmap object allocated by recoverBitmapAlloc().
397 static void recoverBitmapFree(RecoverBitmap
*pMap
){
402 ** Set the bit associated with page iPg in bitvec pMap.
404 static void recoverBitmapSet(RecoverBitmap
*pMap
, i64 iPg
){
405 if( iPg
<=pMap
->nPg
){
406 int iElem
= (iPg
/ 32);
407 int iBit
= (iPg
% 32);
408 pMap
->aElem
[iElem
] |= (((u32
)1) << iBit
);
413 ** Query bitmap object pMap for the state of the bit associated with page
414 ** iPg. Return 1 if it is set, or 0 otherwise.
416 static int recoverBitmapQuery(RecoverBitmap
*pMap
, i64 iPg
){
418 if( iPg
<=pMap
->nPg
&& iPg
>0 ){
419 int iElem
= (iPg
/ 32);
420 int iBit
= (iPg
% 32);
421 ret
= (pMap
->aElem
[iElem
] & (((u32
)1) << iBit
)) ? 1 : 0;
427 ** Set the recover handle error to the error code and message returned by
428 ** calling sqlite3_errcode() and sqlite3_errmsg(), respectively, on database
431 static int recoverDbError(sqlite3_recover
*p
, sqlite3
*db
){
432 return recoverError(p
, sqlite3_errcode(db
), "%s", sqlite3_errmsg(db
));
436 ** This function is a no-op if recover handle p already contains an error
437 ** (if p->errCode!=SQLITE_OK).
439 ** Otherwise, it attempts to prepare the SQL statement in zSql against
440 ** database handle db. If successful, the statement handle is returned.
441 ** Or, if an error occurs, NULL is returned and an error left in the
444 static sqlite3_stmt
*recoverPrepare(
449 sqlite3_stmt
*pStmt
= 0;
450 if( p
->errCode
==SQLITE_OK
){
451 if( sqlite3_prepare_v2(db
, zSql
, -1, &pStmt
, 0) ){
452 recoverDbError(p
, db
);
459 ** This function is a no-op if recover handle p already contains an error
460 ** (if p->errCode!=SQLITE_OK).
462 ** Otherwise, argument zFmt is used as a printf() style format string,
463 ** along with any trailing arguments, to create an SQL statement. This
464 ** SQL statement is prepared against database handle db and, if successful,
465 ** the statment handle returned. Or, if an error occurs - either during
466 ** the printf() formatting or when preparing the resulting SQL - an
467 ** error code and message are left in the recover handle.
469 static sqlite3_stmt
*recoverPreparePrintf(
472 const char *zFmt
, ...
474 sqlite3_stmt
*pStmt
= 0;
475 if( p
->errCode
==SQLITE_OK
){
479 z
= sqlite3_vmprintf(zFmt
, ap
);
482 p
->errCode
= SQLITE_NOMEM
;
484 pStmt
= recoverPrepare(p
, db
, z
);
492 ** Reset SQLite statement handle pStmt. If the call to sqlite3_reset()
493 ** indicates that an error occurred, and there is not already an error
494 ** in the recover handle passed as the first argument, set the error
495 ** code and error message appropriately.
497 ** This function returns a copy of the statement handle pointer passed
498 ** as the second argument.
500 static sqlite3_stmt
*recoverReset(sqlite3_recover
*p
, sqlite3_stmt
*pStmt
){
501 int rc
= sqlite3_reset(pStmt
);
502 if( rc
!=SQLITE_OK
&& rc
!=SQLITE_CONSTRAINT
&& p
->errCode
==SQLITE_OK
){
503 recoverDbError(p
, sqlite3_db_handle(pStmt
));
509 ** Finalize SQLite statement handle pStmt. If the call to sqlite3_reset()
510 ** indicates that an error occurred, and there is not already an error
511 ** in the recover handle passed as the first argument, set the error
512 ** code and error message appropriately.
514 static void recoverFinalize(sqlite3_recover
*p
, sqlite3_stmt
*pStmt
){
515 sqlite3
*db
= sqlite3_db_handle(pStmt
);
516 int rc
= sqlite3_finalize(pStmt
);
517 if( rc
!=SQLITE_OK
&& p
->errCode
==SQLITE_OK
){
518 recoverDbError(p
, db
);
523 ** This function is a no-op if recover handle p already contains an error
524 ** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this
527 ** Otherwise, execute SQL script zSql. If successful, return SQLITE_OK.
528 ** Or, if an error occurs, leave an error code and message in the recover
529 ** handle and return a copy of the error code.
531 static int recoverExec(sqlite3_recover
*p
, sqlite3
*db
, const char *zSql
){
532 if( p
->errCode
==SQLITE_OK
){
533 int rc
= sqlite3_exec(db
, zSql
, 0, 0, 0);
535 recoverDbError(p
, db
);
542 ** Bind the value pVal to parameter iBind of statement pStmt. Leave an
543 ** error in the recover handle passed as the first argument if an error
544 ** (e.g. an OOM) occurs.
546 static void recoverBindValue(
552 if( p
->errCode
==SQLITE_OK
){
553 int rc
= sqlite3_bind_value(pStmt
, iBind
, pVal
);
554 if( rc
) recoverError(p
, rc
, 0);
559 ** This function is a no-op if recover handle p already contains an error
560 ** (if p->errCode!=SQLITE_OK). NULL is returned in this case.
562 ** Otherwise, an attempt is made to interpret zFmt as a printf() style
563 ** formatting string and the result of using the trailing arguments for
564 ** parameter substitution with it written into a buffer obtained from
565 ** sqlite3_malloc(). If successful, a pointer to the buffer is returned.
566 ** It is the responsibility of the caller to eventually free the buffer
567 ** using sqlite3_free().
569 ** Or, if an error occurs, an error code and message is left in the recover
570 ** handle and NULL returned.
572 static char *recoverMPrintf(sqlite3_recover
*p
, const char *zFmt
, ...){
576 z
= sqlite3_vmprintf(zFmt
, ap
);
578 if( p
->errCode
==SQLITE_OK
){
579 if( z
==0 ) p
->errCode
= SQLITE_NOMEM
;
588 ** This function is a no-op if recover handle p already contains an error
589 ** (if p->errCode!=SQLITE_OK). Zero is returned in this case.
591 ** Otherwise, execute "PRAGMA page_count" against the input database. If
592 ** successful, return the integer result. Or, if an error occurs, leave an
593 ** error code and error message in the sqlite3_recover handle and return
596 static i64
recoverPageCount(sqlite3_recover
*p
){
598 if( p
->errCode
==SQLITE_OK
){
599 sqlite3_stmt
*pStmt
= 0;
600 pStmt
= recoverPreparePrintf(p
, p
->dbIn
, "PRAGMA %Q.page_count", p
->zDb
);
603 nPg
= sqlite3_column_int64(pStmt
, 0);
605 recoverFinalize(p
, pStmt
);
611 ** Implementation of SQL scalar function "read_i32". The first argument to
612 ** this function must be a blob. The second a non-negative integer. This
613 ** function reads and returns a 32-bit big-endian integer from byte
614 ** offset (4*<arg2>) of the blob.
616 ** SELECT read_i32(<blob>, <idx>)
618 static void recoverReadI32(
619 sqlite3_context
*context
,
623 const unsigned char *pBlob
;
628 nBlob
= sqlite3_value_bytes(argv
[0]);
629 pBlob
= (const unsigned char*)sqlite3_value_blob(argv
[0]);
630 iInt
= sqlite3_value_int(argv
[1]) & 0xFFFF;
632 if( (iInt
+1)*4<=nBlob
){
633 const unsigned char *a
= &pBlob
[iInt
*4];
634 i64 iVal
= ((i64
)a
[0]<<24)
638 sqlite3_result_int64(context
, iVal
);
643 ** Implementation of SQL scalar function "page_is_used". This function
644 ** is used as part of the procedure for locating orphan rows for the
645 ** lost-and-found table, and it depends on those routines having populated
646 ** the sqlite3_recover.laf.pUsed variable.
648 ** The only argument to this function is a page-number. It returns true
649 ** if the page has already been used somehow during data recovery, or false
652 ** SELECT page_is_used(<pgno>);
654 static void recoverPageIsUsed(
655 sqlite3_context
*pCtx
,
657 sqlite3_value
**apArg
659 sqlite3_recover
*p
= (sqlite3_recover
*)sqlite3_user_data(pCtx
);
660 i64 pgno
= sqlite3_value_int64(apArg
[0]);
662 sqlite3_result_int(pCtx
, recoverBitmapQuery(p
->laf
.pUsed
, pgno
));
666 ** The implementation of a user-defined SQL function invoked by the
667 ** sqlite_dbdata and sqlite_dbptr virtual table modules to access pages
668 ** of the database being recovered.
670 ** This function always takes a single integer argument. If the argument
671 ** is zero, then the value returned is the number of pages in the db being
672 ** recovered. If the argument is greater than zero, it is a page number.
673 ** The value returned in this case is an SQL blob containing the data for
674 ** the identified page of the db being recovered. e.g.
676 ** SELECT getpage(0); -- return number of pages in db
677 ** SELECT getpage(4); -- return page 4 of db as a blob of data
679 static void recoverGetPage(
680 sqlite3_context
*pCtx
,
682 sqlite3_value
**apArg
684 sqlite3_recover
*p
= (sqlite3_recover
*)sqlite3_user_data(pCtx
);
685 i64 pgno
= sqlite3_value_int64(apArg
[0]);
686 sqlite3_stmt
*pStmt
= 0;
690 i64 nPg
= recoverPageCount(p
);
691 sqlite3_result_int64(pCtx
, nPg
);
694 if( p
->pGetPage
==0 ){
695 pStmt
= p
->pGetPage
= recoverPreparePrintf(
696 p
, p
->dbIn
, "SELECT data FROM sqlite_dbpage(%Q) WHERE pgno=?", p
->zDb
698 }else if( p
->errCode
==SQLITE_OK
){
703 sqlite3_bind_int64(pStmt
, 1, pgno
);
704 if( SQLITE_ROW
==sqlite3_step(pStmt
) ){
707 assert( p
->errCode
==SQLITE_OK
);
708 aPg
= sqlite3_column_blob(pStmt
, 0);
709 nPg
= sqlite3_column_bytes(pStmt
, 0);
710 if( pgno
==1 && nPg
==p
->pgsz
&& 0==memcmp(p
->pPage1Cache
, aPg
, nPg
) ){
713 sqlite3_result_blob(pCtx
, aPg
, nPg
-p
->nReserve
, SQLITE_TRANSIENT
);
715 recoverReset(p
, pStmt
);
720 if( p
->zErrMsg
) sqlite3_result_error(pCtx
, p
->zErrMsg
, -1);
721 sqlite3_result_error_code(pCtx
, p
->errCode
);
726 ** Find a string that is not found anywhere in z[]. Return a pointer
729 ** Try to use zA and zB first. If both of those are already found in z[]
730 ** then make up some string and store it in the buffer zBuf.
732 static const char *recoverUnusedString(
733 const char *z
, /* Result must not appear anywhere in z */
734 const char *zA
, const char *zB
, /* Try these first */
735 char *zBuf
/* Space to store a generated string */
738 if( strstr(z
, zA
)==0 ) return zA
;
739 if( strstr(z
, zB
)==0 ) return zB
;
741 sqlite3_snprintf(20,zBuf
,"(%s%u)", zA
, i
++);
742 }while( strstr(z
,zBuf
)!=0 );
747 ** Implementation of scalar SQL function "escape_crnl". The argument passed to
748 ** this function is the output of built-in function quote(). If the first
749 ** character of the input is "'", indicating that the value passed to quote()
750 ** was a text value, then this function searches the input for "\n" and "\r"
751 ** characters and adds a wrapper similar to the following:
753 ** replace(replace(<input>, '\n', char(10), '\r', char(13));
755 ** Or, if the first character of the input is not "'", then a copy of the input
758 static void recoverEscapeCrnl(
759 sqlite3_context
*context
,
763 const char *zText
= (const char*)sqlite3_value_text(argv
[0]);
765 if( zText
&& zText
[0]=='\'' ){
766 int nText
= sqlite3_value_bytes(argv
[0]);
775 for(i
=0; zText
[i
]; i
++){
776 if( zNL
==0 && zText
[i
]=='\n' ){
777 zNL
= recoverUnusedString(zText
, "\\n", "\\012", zBuf1
);
778 nNL
= (int)strlen(zNL
);
780 if( zCR
==0 && zText
[i
]=='\r' ){
781 zCR
= recoverUnusedString(zText
, "\\r", "\\015", zBuf2
);
782 nCR
= (int)strlen(zCR
);
788 i64 nMax
= (nNL
> nCR
) ? nNL
: nCR
;
789 i64 nAlloc
= nMax
* nText
+ (nMax
+64)*2;
790 char *zOut
= (char*)sqlite3_malloc64(nAlloc
);
792 sqlite3_result_error_nomem(context
);
797 memcpy(&zOut
[iOut
], "replace(replace(", 16);
800 memcpy(&zOut
[iOut
], "replace(", 8);
803 for(i
=0; zText
[i
]; i
++){
804 if( zText
[i
]=='\n' ){
805 memcpy(&zOut
[iOut
], zNL
, nNL
);
807 }else if( zText
[i
]=='\r' ){
808 memcpy(&zOut
[iOut
], zCR
, nCR
);
811 zOut
[iOut
] = zText
[i
];
817 memcpy(&zOut
[iOut
], ",'", 2); iOut
+= 2;
818 memcpy(&zOut
[iOut
], zNL
, nNL
); iOut
+= nNL
;
819 memcpy(&zOut
[iOut
], "', char(10))", 12); iOut
+= 12;
822 memcpy(&zOut
[iOut
], ",'", 2); iOut
+= 2;
823 memcpy(&zOut
[iOut
], zCR
, nCR
); iOut
+= nCR
;
824 memcpy(&zOut
[iOut
], "', char(13))", 12); iOut
+= 12;
827 sqlite3_result_text(context
, zOut
, iOut
, SQLITE_TRANSIENT
);
833 sqlite3_result_value(context
, argv
[0]);
837 ** This function is a no-op if recover handle p already contains an error
838 ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in
841 ** Otherwise, attempt to populate temporary table "recovery.schema" with the
842 ** parts of the database schema that can be extracted from the input database.
844 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
845 ** and error message are left in the recover handle and a copy of the
846 ** error code returned. It is not considered an error if part of all of
847 ** the database schema cannot be recovered due to corruption.
849 static int recoverCacheSchema(sqlite3_recover
*p
){
850 return recoverExec(p
, p
->dbOut
,
851 "WITH RECURSIVE pages(p) AS ("
854 " SELECT child FROM sqlite_dbptr('getpage()'), pages WHERE pgno=p"
856 "INSERT INTO recovery.schema SELECT"
857 " max(CASE WHEN field=0 THEN value ELSE NULL END),"
858 " max(CASE WHEN field=1 THEN value ELSE NULL END),"
859 " max(CASE WHEN field=2 THEN value ELSE NULL END),"
860 " max(CASE WHEN field=3 THEN value ELSE NULL END),"
861 " max(CASE WHEN field=4 THEN value ELSE NULL END)"
862 "FROM sqlite_dbdata('getpage()') WHERE pgno IN ("
863 " SELECT p FROM pages"
864 ") GROUP BY pgno, cell"
869 ** If this recover handle is not in SQL callback mode (i.e. was not created
870 ** using sqlite3_recover_init_sql()) of if an error has already occurred,
871 ** this function is a no-op. Otherwise, issue a callback with SQL statement
872 ** zSql as the parameter.
874 ** If the callback returns non-zero, set the recover handle error code to
875 ** the value returned (so that the caller will abandon processing).
877 static void recoverSqlCallback(sqlite3_recover
*p
, const char *zSql
){
878 if( p
->errCode
==SQLITE_OK
&& p
->xSql
){
879 int res
= p
->xSql(p
->pSqlCtx
, zSql
);
881 recoverError(p
, SQLITE_ERROR
, "callback returned an error - %d", res
);
887 ** Transfer the following settings from the input database to the output
891 ** + auto-vacuum settings,
892 ** + database encoding,
893 ** + user-version (PRAGMA user_version), and
894 ** + application-id (PRAGMA application_id), and
896 static void recoverTransferSettings(sqlite3_recover
*p
){
897 const char *aPragma
[] = {
906 /* Truncate the output database to 0 pages in size. This is done by
907 ** opening a new, empty, temp db, then using the backup API to clobber
908 ** any existing output db with a copy of it. */
909 if( p
->errCode
==SQLITE_OK
){
911 int rc
= sqlite3_open("", &db2
);
913 recoverDbError(p
, db2
);
917 for(ii
=0; ii
<(int)(sizeof(aPragma
)/sizeof(aPragma
[0])); ii
++){
918 const char *zPrag
= aPragma
[ii
];
919 sqlite3_stmt
*p1
= 0;
920 p1
= recoverPreparePrintf(p
, p
->dbIn
, "PRAGMA %Q.%s", p
->zDb
, zPrag
);
921 if( p
->errCode
==SQLITE_OK
&& sqlite3_step(p1
)==SQLITE_ROW
){
922 const char *zArg
= (const char*)sqlite3_column_text(p1
, 0);
923 char *z2
= recoverMPrintf(p
, "PRAGMA %s = %Q", zPrag
, zArg
);
924 recoverSqlCallback(p
, z2
);
925 recoverExec(p
, db2
, z2
);
928 recoverError(p
, SQLITE_NOMEM
, 0);
931 recoverFinalize(p
, p1
);
933 recoverExec(p
, db2
, "CREATE TABLE t1(a); DROP TABLE t1;");
935 if( p
->errCode
==SQLITE_OK
){
936 sqlite3
*db
= p
->dbOut
;
937 sqlite3_backup
*pBackup
= sqlite3_backup_init(db
, "main", db2
, "main");
939 sqlite3_backup_step(pBackup
, -1);
940 p
->errCode
= sqlite3_backup_finish(pBackup
);
942 recoverDbError(p
, db
);
951 ** This function is a no-op if recover handle p already contains an error
952 ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in
955 ** Otherwise, an attempt is made to open the output database, attach
956 ** and create the schema of the temporary database used to store
957 ** intermediate data, and to register all required user functions and
958 ** virtual table modules with the output handle.
960 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
961 ** and error message are left in the recover handle and a copy of the
962 ** error code returned.
964 static int recoverOpenOutput(sqlite3_recover
*p
){
968 void (*xFunc
)(sqlite3_context
*,int,sqlite3_value
**);
970 { "getpage", 1, recoverGetPage
},
971 { "page_is_used", 1, recoverPageIsUsed
},
972 { "read_i32", 2, recoverReadI32
},
973 { "escape_crnl", 1, recoverEscapeCrnl
},
976 const int flags
= SQLITE_OPEN_URI
|SQLITE_OPEN_CREATE
|SQLITE_OPEN_READWRITE
;
977 sqlite3
*db
= 0; /* New database handle */
978 int ii
; /* For iterating through aFunc[] */
980 assert( p
->dbOut
==0 );
982 if( sqlite3_open_v2(p
->zUri
, &db
, flags
, 0) ){
983 recoverDbError(p
, db
);
986 /* Register the sqlite_dbdata and sqlite_dbptr virtual table modules.
987 ** These two are registered with the output database handle - this
988 ** module depends on the input handle supporting the sqlite_dbpage
989 ** virtual table only. */
990 if( p
->errCode
==SQLITE_OK
){
991 p
->errCode
= sqlite3_dbdata_init(db
, 0, 0);
994 /* Register the custom user-functions with the output handle. */
996 p
->errCode
==SQLITE_OK
&& ii
<(int)(sizeof(aFunc
)/sizeof(aFunc
[0]));
998 p
->errCode
= sqlite3_create_function(db
, aFunc
[ii
].zName
,
999 aFunc
[ii
].nArg
, SQLITE_UTF8
, (void*)p
, aFunc
[ii
].xFunc
, 0, 0
1008 ** Attach the auxiliary database 'recovery' to the output database handle.
1009 ** This temporary database is used during the recovery process and then
1012 static void recoverOpenRecovery(sqlite3_recover
*p
){
1013 char *zSql
= recoverMPrintf(p
, "ATTACH %Q AS recovery;", p
->zStateDb
);
1014 recoverExec(p
, p
->dbOut
, zSql
);
1015 recoverExec(p
, p
->dbOut
,
1016 "PRAGMA writable_schema = 1;"
1017 "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);"
1018 "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
1025 ** This function is a no-op if recover handle p already contains an error
1026 ** (if p->errCode!=SQLITE_OK).
1028 ** Otherwise, argument zName must be the name of a table that has just been
1029 ** created in the output database. This function queries the output db
1030 ** for the schema of said table, and creates a RecoverTable object to
1031 ** store the schema in memory. The new RecoverTable object is linked into
1032 ** the list at sqlite3_recover.pTblList.
1034 ** Parameter iRoot must be the root page of table zName in the INPUT
1037 static void recoverAddTable(
1039 const char *zName
, /* Name of table created in output db */
1040 i64 iRoot
/* Root page of same table in INPUT db */
1042 sqlite3_stmt
*pStmt
= recoverPreparePrintf(p
, p
->dbOut
,
1043 "PRAGMA table_xinfo(%Q)", zName
1049 RecoverTable
*pNew
= 0;
1051 int nName
= recoverStrlen(zName
);
1053 while( sqlite3_step(pStmt
)==SQLITE_ROW
){
1055 nByte
+= (sqlite3_column_bytes(pStmt
, 1)+1);
1057 nByte
+= sizeof(RecoverTable
) + nCol
*sizeof(RecoverColumn
) + nName
+1;
1058 recoverReset(p
, pStmt
);
1060 pNew
= recoverMalloc(p
, nByte
);
1065 pNew
->aCol
= (RecoverColumn
*)&pNew
[1];
1066 pNew
->zTab
= csr
= (char*)&pNew
->aCol
[nCol
];
1068 pNew
->iRoot
= iRoot
;
1069 memcpy(csr
, zName
, nName
);
1072 for(i
=0; sqlite3_step(pStmt
)==SQLITE_ROW
; i
++){
1073 int iPKF
= sqlite3_column_int(pStmt
, 5);
1074 int n
= sqlite3_column_bytes(pStmt
, 1);
1075 const char *z
= (const char*)sqlite3_column_text(pStmt
, 1);
1076 const char *zType
= (const char*)sqlite3_column_text(pStmt
, 2);
1077 int eHidden
= sqlite3_column_int(pStmt
, 6);
1079 if( iPk
==-1 && iPKF
==1 && !sqlite3_stricmp("integer", zType
) ) iPk
= i
;
1080 if( iPKF
>1 ) iPk
= -2;
1081 pNew
->aCol
[i
].zCol
= csr
;
1082 pNew
->aCol
[i
].eHidden
= eHidden
;
1083 if( eHidden
==RECOVER_EHIDDEN_VIRTUAL
){
1084 pNew
->aCol
[i
].iField
= -1;
1086 pNew
->aCol
[i
].iField
= iField
++;
1088 if( eHidden
!=RECOVER_EHIDDEN_VIRTUAL
1089 && eHidden
!=RECOVER_EHIDDEN_STORED
1091 pNew
->aCol
[i
].iBind
= iBind
++;
1097 pNew
->pNext
= p
->pTblList
;
1102 recoverFinalize(p
, pStmt
);
1104 pStmt
= recoverPreparePrintf(p
, p
->dbOut
, "PRAGMA index_xinfo(%Q)", zName
);
1105 while( pStmt
&& sqlite3_step(pStmt
)==SQLITE_ROW
){
1106 int iField
= sqlite3_column_int(pStmt
, 0);
1107 int iCol
= sqlite3_column_int(pStmt
, 1);
1109 assert( iCol
<pNew
->nCol
);
1110 pNew
->aCol
[iCol
].iField
= iField
;
1115 recoverFinalize(p
, pStmt
);
1117 if( p
->errCode
==SQLITE_OK
){
1119 pNew
->aCol
[iPk
].bIPK
= 1;
1120 }else if( pNew
->bIntkey
){
1121 pNew
->iRowidBind
= iBind
++;
1128 ** This function is called after recoverCacheSchema() has cached those parts
1129 ** of the input database schema that could be recovered in temporary table
1130 ** "recovery.schema". This function creates in the output database copies
1131 ** of all parts of that schema that must be created before the tables can
1132 ** be populated. Specifically, this means:
1134 ** * all tables that are not VIRTUAL, and
1135 ** * UNIQUE indexes.
1137 ** If the recovery handle uses SQL callbacks, then callbacks containing
1138 ** the associated "CREATE TABLE" and "CREATE INDEX" statements are made.
1140 ** Additionally, records are added to the sqlite_schema table of the
1141 ** output database for any VIRTUAL tables. The CREATE VIRTUAL TABLE
1142 ** records are written directly to sqlite_schema, not actually executed.
1143 ** If the handle is in SQL callback mode, then callbacks are invoked
1144 ** with equivalent SQL statements.
1146 static int recoverWriteSchema1(sqlite3_recover
*p
){
1147 sqlite3_stmt
*pSelect
= 0;
1148 sqlite3_stmt
*pTblname
= 0;
1150 pSelect
= recoverPrepare(p
, p
->dbOut
,
1151 "WITH dbschema(rootpage, name, sql, tbl, isVirtual, isIndex) AS ("
1152 " SELECT rootpage, name, sql, "
1154 " sql LIKE 'create virtual%',"
1155 " (type='index' AND (sql LIKE '%unique%' OR ?1))"
1156 " FROM recovery.schema"
1158 "SELECT rootpage, tbl, isVirtual, name, sql"
1160 " WHERE tbl OR isIndex"
1161 " ORDER BY tbl DESC, name=='sqlite_sequence' DESC"
1164 pTblname
= recoverPrepare(p
, p
->dbOut
,
1165 "SELECT name FROM sqlite_schema "
1166 "WHERE type='table' ORDER BY rowid DESC LIMIT 1"
1170 sqlite3_bind_int(pSelect
, 1, p
->bSlowIndexes
);
1171 while( sqlite3_step(pSelect
)==SQLITE_ROW
){
1172 i64 iRoot
= sqlite3_column_int64(pSelect
, 0);
1173 int bTable
= sqlite3_column_int(pSelect
, 1);
1174 int bVirtual
= sqlite3_column_int(pSelect
, 2);
1175 const char *zName
= (const char*)sqlite3_column_text(pSelect
, 3);
1176 const char *zSql
= (const char*)sqlite3_column_text(pSelect
, 4);
1181 zSql
= (const char*)(zFree
= recoverMPrintf(p
,
1182 "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
1186 rc
= sqlite3_exec(p
->dbOut
, zSql
, 0, 0, 0);
1187 if( rc
==SQLITE_OK
){
1188 recoverSqlCallback(p
, zSql
);
1189 if( bTable
&& !bVirtual
){
1190 if( SQLITE_ROW
==sqlite3_step(pTblname
) ){
1191 const char *zTbl
= (const char*)sqlite3_column_text(pTblname
, 0);
1192 if( zTbl
) recoverAddTable(p
, zTbl
, iRoot
);
1194 recoverReset(p
, pTblname
);
1196 }else if( rc
!=SQLITE_ERROR
){
1197 recoverDbError(p
, p
->dbOut
);
1199 sqlite3_free(zFree
);
1202 recoverFinalize(p
, pSelect
);
1203 recoverFinalize(p
, pTblname
);
1209 ** This function is called after the output database has been populated. It
1210 ** adds all recovered schema elements that were not created in the output
1211 ** database by recoverWriteSchema1() - everything except for tables and
1212 ** UNIQUE indexes. Specifically:
1216 ** * non-UNIQUE indexes.
1218 ** If the recover handle is in SQL callback mode, then equivalent callbacks
1219 ** are issued to create the schema elements.
1221 static int recoverWriteSchema2(sqlite3_recover
*p
){
1222 sqlite3_stmt
*pSelect
= 0;
1224 pSelect
= recoverPrepare(p
, p
->dbOut
,
1226 "SELECT rootpage, sql FROM recovery.schema "
1227 " WHERE type!='table' AND type!='index'"
1229 "SELECT rootpage, sql FROM recovery.schema "
1230 " WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')"
1234 while( sqlite3_step(pSelect
)==SQLITE_ROW
){
1235 const char *zSql
= (const char*)sqlite3_column_text(pSelect
, 1);
1236 int rc
= sqlite3_exec(p
->dbOut
, zSql
, 0, 0, 0);
1237 if( rc
==SQLITE_OK
){
1238 recoverSqlCallback(p
, zSql
);
1239 }else if( rc
!=SQLITE_ERROR
){
1240 recoverDbError(p
, p
->dbOut
);
1244 recoverFinalize(p
, pSelect
);
1250 ** This function is a no-op if recover handle p already contains an error
1251 ** (if p->errCode!=SQLITE_OK). In this case it returns NULL.
1253 ** Otherwise, if the recover handle is configured to create an output
1254 ** database (was created by sqlite3_recover_init()), then this function
1255 ** prepares and returns an SQL statement to INSERT a new record into table
1256 ** pTab, assuming the first nField fields of a record extracted from disk
1259 ** For example, if table pTab is:
1261 ** CREATE TABLE name(a, b GENERATED ALWAYS AS (a+1) STORED, c, d, e);
1263 ** And nField is 4, then the SQL statement prepared and returned is:
1265 ** INSERT INTO (a, c, d) VALUES (?1, ?2, ?3);
1267 ** In this case even though 4 values were extracted from the input db,
1268 ** only 3 are written to the output, as the generated STORED column
1269 ** cannot be written.
1271 ** If the recover handle is in SQL callback mode, then the SQL statement
1272 ** prepared is such that evaluating it returns a single row containing
1273 ** a single text value - itself an SQL statement similar to the above,
1274 ** except with SQL literals in place of the variables. For example:
1276 ** SELECT 'INSERT INTO (a, c, d) VALUES ('
1277 ** || quote(?1) || ', '
1278 ** || quote(?2) || ', '
1279 ** || quote(?3) || ')';
1281 ** In either case, it is the responsibility of the caller to eventually
1282 ** free the statement handle using sqlite3_finalize().
1284 static sqlite3_stmt
*recoverInsertStmt(
1289 sqlite3_stmt
*pRet
= 0;
1290 const char *zSep
= "";
1291 const char *zSqlSep
= "";
1296 int bSql
= p
->xSql
? 1 : 0;
1298 if( nField
<=0 ) return 0;
1300 assert( nField
<=pTab
->nCol
);
1302 zSql
= recoverMPrintf(p
, "INSERT OR IGNORE INTO %Q(", pTab
->zTab
);
1304 if( pTab
->iRowidBind
){
1305 assert( pTab
->bIntkey
);
1306 zSql
= recoverMPrintf(p
, "%z_rowid_", zSql
);
1308 zBind
= recoverMPrintf(p
, "%zquote(?%d)", zBind
, pTab
->iRowidBind
);
1310 zBind
= recoverMPrintf(p
, "%z?%d", zBind
, pTab
->iRowidBind
);
1312 zSqlSep
= "||', '||";
1316 for(ii
=0; ii
<nField
; ii
++){
1317 int eHidden
= pTab
->aCol
[ii
].eHidden
;
1318 if( eHidden
!=RECOVER_EHIDDEN_VIRTUAL
1319 && eHidden
!=RECOVER_EHIDDEN_STORED
1321 assert( pTab
->aCol
[ii
].iField
>=0 && pTab
->aCol
[ii
].iBind
>=1 );
1322 zSql
= recoverMPrintf(p
, "%z%s%Q", zSql
, zSep
, pTab
->aCol
[ii
].zCol
);
1325 zBind
= recoverMPrintf(p
,
1326 "%z%sescape_crnl(quote(?%d))", zBind
, zSqlSep
, pTab
->aCol
[ii
].iBind
1328 zSqlSep
= "||', '||";
1330 zBind
= recoverMPrintf(p
, "%z%s?%d", zBind
, zSep
, pTab
->aCol
[ii
].iBind
);
1337 zFinal
= recoverMPrintf(p
, "SELECT %Q || ') VALUES (' || %s || ')'",
1341 zFinal
= recoverMPrintf(p
, "%s) VALUES (%s)", zSql
, zBind
);
1344 pRet
= recoverPrepare(p
, p
->dbOut
, zFinal
);
1346 sqlite3_free(zBind
);
1347 sqlite3_free(zFinal
);
1354 ** Search the list of RecoverTable objects at p->pTblList for one that
1355 ** has root page iRoot in the input database. If such an object is found,
1356 ** return a pointer to it. Otherwise, return NULL.
1358 static RecoverTable
*recoverFindTable(sqlite3_recover
*p
, u32 iRoot
){
1359 RecoverTable
*pRet
= 0;
1360 for(pRet
=p
->pTblList
; pRet
&& pRet
->iRoot
!=iRoot
; pRet
=pRet
->pNext
);
1365 ** This function attempts to create a lost and found table within the
1366 ** output db. If successful, it returns a pointer to a buffer containing
1367 ** the name of the new table. It is the responsibility of the caller to
1368 ** eventually free this buffer using sqlite3_free().
1370 ** If an error occurs, NULL is returned and an error code and error
1371 ** message left in the recover handle.
1373 static char *recoverLostAndFoundCreate(
1374 sqlite3_recover
*p
, /* Recover object */
1375 int nField
/* Number of column fields in new table */
1378 sqlite3_stmt
*pProbe
= 0;
1381 pProbe
= recoverPrepare(p
, p
->dbOut
,
1382 "SELECT 1 FROM sqlite_schema WHERE name=?"
1384 for(ii
=-1; zTbl
==0 && p
->errCode
==SQLITE_OK
&& ii
<1000; ii
++){
1387 zTbl
= recoverMPrintf(p
, "%s", p
->zLostAndFound
);
1389 zTbl
= recoverMPrintf(p
, "%s_%d", p
->zLostAndFound
, ii
);
1392 if( p
->errCode
==SQLITE_OK
){
1393 sqlite3_bind_text(pProbe
, 1, zTbl
, -1, SQLITE_STATIC
);
1394 if( SQLITE_ROW
==sqlite3_step(pProbe
) ){
1397 recoverReset(p
, pProbe
);
1401 sqlite3_clear_bindings(pProbe
);
1406 recoverFinalize(p
, pProbe
);
1409 const char *zSep
= 0;
1413 zSep
= "rootpgno INTEGER, pgno INTEGER, nfield INTEGER, id INTEGER, ";
1414 for(ii
=0; p
->errCode
==SQLITE_OK
&& ii
<nField
; ii
++){
1415 zField
= recoverMPrintf(p
, "%z%sc%d", zField
, zSep
, ii
);
1419 zSql
= recoverMPrintf(p
, "CREATE TABLE %s(%s)", zTbl
, zField
);
1420 sqlite3_free(zField
);
1422 recoverExec(p
, p
->dbOut
, zSql
);
1423 recoverSqlCallback(p
, zSql
);
1425 }else if( p
->errCode
==SQLITE_OK
){
1427 p
, SQLITE_ERROR
, "failed to create %s output table", p
->zLostAndFound
1435 ** Synthesize and prepare an INSERT statement to write to the lost_and_found
1436 ** table in the output database. The name of the table is zTab, and it has
1437 ** nField c* fields.
1439 static sqlite3_stmt
*recoverLostAndFoundInsert(
1444 int nTotal
= nField
+ 4;
1447 sqlite3_stmt
*pRet
= 0;
1450 for(ii
=0; ii
<nTotal
; ii
++){
1451 zBind
= recoverMPrintf(p
, "%z%s?", zBind
, zBind
?", ":"", ii
);
1453 pRet
= recoverPreparePrintf(
1454 p
, p
->dbOut
, "INSERT INTO %s VALUES(%s)", zTab
, zBind
1457 const char *zSep
= "";
1458 for(ii
=0; ii
<nTotal
; ii
++){
1459 zBind
= recoverMPrintf(p
, "%z%squote(?)", zBind
, zSep
);
1460 zSep
= "|| ', ' ||";
1462 pRet
= recoverPreparePrintf(
1463 p
, p
->dbOut
, "SELECT 'INSERT INTO %s VALUES(' || %s || ')'", zTab
, zBind
1467 sqlite3_free(zBind
);
1472 ** Input database page iPg contains data that will be written to the
1473 ** lost-and-found table of the output database. This function attempts
1474 ** to identify the root page of the tree that page iPg belonged to.
1475 ** If successful, it sets output variable (*piRoot) to the page number
1476 ** of the root page and returns SQLITE_OK. Otherwise, if an error occurs,
1477 ** an SQLite error code is returned and the final value of *piRoot
1480 static int recoverLostAndFoundFindRoot(
1485 RecoverStateLAF
*pLaf
= &p
->laf
;
1487 if( pLaf
->pFindRoot
==0 ){
1488 pLaf
->pFindRoot
= recoverPrepare(p
, p
->dbOut
,
1489 "WITH RECURSIVE p(pgno) AS ("
1492 " SELECT parent FROM recovery.map AS m, p WHERE m.pgno=p.pgno"
1494 "SELECT p.pgno FROM p, recovery.map m WHERE m.pgno=p.pgno "
1495 " AND m.parent IS NULL"
1498 if( p
->errCode
==SQLITE_OK
){
1499 sqlite3_bind_int64(pLaf
->pFindRoot
, 1, iPg
);
1500 if( sqlite3_step(pLaf
->pFindRoot
)==SQLITE_ROW
){
1501 *piRoot
= sqlite3_column_int64(pLaf
->pFindRoot
, 0);
1505 recoverReset(p
, pLaf
->pFindRoot
);
1511 ** Recover data from page iPage of the input database and write it to
1512 ** the lost-and-found table in the output database.
1514 static void recoverLostAndFoundOnePage(sqlite3_recover
*p
, i64 iPage
){
1515 RecoverStateLAF
*pLaf
= &p
->laf
;
1516 sqlite3_value
**apVal
= pLaf
->apVal
;
1517 sqlite3_stmt
*pPageData
= pLaf
->pPageData
;
1518 sqlite3_stmt
*pInsert
= pLaf
->pInsert
;
1527 if( recoverLostAndFoundFindRoot(p
, iPage
, &iRoot
) ) return;
1528 sqlite3_bind_int64(pPageData
, 1, iPage
);
1529 while( p
->errCode
==SQLITE_OK
&& SQLITE_ROW
==sqlite3_step(pPageData
) ){
1530 int iCell
= sqlite3_column_int64(pPageData
, 0);
1531 int iField
= sqlite3_column_int64(pPageData
, 1);
1533 if( iPrevCell
!=iCell
&& nVal
>=0 ){
1534 /* Insert the new row */
1535 sqlite3_bind_int64(pInsert
, 1, iRoot
); /* rootpgno */
1536 sqlite3_bind_int64(pInsert
, 2, iPage
); /* pgno */
1537 sqlite3_bind_int(pInsert
, 3, nVal
); /* nfield */
1539 sqlite3_bind_int64(pInsert
, 4, iRowid
); /* id */
1541 for(ii
=0; ii
<nVal
; ii
++){
1542 recoverBindValue(p
, pInsert
, 5+ii
, apVal
[ii
]);
1544 if( sqlite3_step(pInsert
)==SQLITE_ROW
){
1545 recoverSqlCallback(p
, (const char*)sqlite3_column_text(pInsert
, 0));
1547 recoverReset(p
, pInsert
);
1549 /* Discard the accumulated row data */
1550 for(ii
=0; ii
<nVal
; ii
++){
1551 sqlite3_value_free(apVal
[ii
]);
1554 sqlite3_clear_bindings(pInsert
);
1559 if( iCell
<0 ) break;
1563 iRowid
= sqlite3_column_int64(pPageData
, 2);
1566 }else if( iField
<pLaf
->nMaxField
){
1567 sqlite3_value
*pVal
= sqlite3_column_value(pPageData
, 2);
1568 apVal
[iField
] = sqlite3_value_dup(pVal
);
1569 assert( iField
==nVal
|| (nVal
==-1 && iField
==0) );
1571 if( apVal
[iField
]==0 ){
1572 recoverError(p
, SQLITE_NOMEM
, 0);
1578 recoverReset(p
, pPageData
);
1580 for(ii
=0; ii
<nVal
; ii
++){
1581 sqlite3_value_free(apVal
[ii
]);
1587 ** Perform one step (sqlite3_recover_step()) of work for the connection
1588 ** passed as the only argument, which is guaranteed to be in
1589 ** RECOVER_STATE_LOSTANDFOUND3 state - during which the lost-and-found
1590 ** table of the output database is populated with recovered data that can
1591 ** not be assigned to any recovered schema object.
1593 static int recoverLostAndFound3Step(sqlite3_recover
*p
){
1594 RecoverStateLAF
*pLaf
= &p
->laf
;
1595 if( p
->errCode
==SQLITE_OK
){
1596 if( pLaf
->pInsert
==0 ){
1599 if( p
->errCode
==SQLITE_OK
){
1600 int res
= sqlite3_step(pLaf
->pAllPage
);
1601 if( res
==SQLITE_ROW
){
1602 i64 iPage
= sqlite3_column_int64(pLaf
->pAllPage
, 0);
1603 if( recoverBitmapQuery(pLaf
->pUsed
, iPage
)==0 ){
1604 recoverLostAndFoundOnePage(p
, iPage
);
1607 recoverReset(p
, pLaf
->pAllPage
);
1617 ** Initialize resources required in RECOVER_STATE_LOSTANDFOUND3
1618 ** state - during which the lost-and-found table of the output database
1619 ** is populated with recovered data that can not be assigned to any
1620 ** recovered schema object.
1622 static void recoverLostAndFound3Init(sqlite3_recover
*p
){
1623 RecoverStateLAF
*pLaf
= &p
->laf
;
1625 if( pLaf
->nMaxField
>0 ){
1626 char *zTab
= 0; /* Name of lost_and_found table */
1628 zTab
= recoverLostAndFoundCreate(p
, pLaf
->nMaxField
);
1629 pLaf
->pInsert
= recoverLostAndFoundInsert(p
, zTab
, pLaf
->nMaxField
);
1632 pLaf
->pAllPage
= recoverPreparePrintf(p
, p
->dbOut
,
1633 "WITH RECURSIVE seq(ii) AS ("
1634 " SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld"
1636 "SELECT ii FROM seq" , p
->laf
.nPg
1638 pLaf
->pPageData
= recoverPrepare(p
, p
->dbOut
,
1639 "SELECT cell, field, value "
1640 "FROM sqlite_dbdata('getpage()') d WHERE d.pgno=? "
1645 pLaf
->apVal
= (sqlite3_value
**)recoverMalloc(p
,
1646 pLaf
->nMaxField
*sizeof(sqlite3_value
*)
1652 ** Initialize resources required in RECOVER_STATE_WRITING state - during which
1653 ** tables recovered from the schema of the input database are populated with
1656 static int recoverWriteDataInit(sqlite3_recover
*p
){
1657 RecoverStateW1
*p1
= &p
->w1
;
1658 RecoverTable
*pTbl
= 0;
1661 /* Figure out the maximum number of columns for any table in the schema */
1662 assert( p1
->nMax
==0 );
1663 for(pTbl
=p
->pTblList
; pTbl
; pTbl
=pTbl
->pNext
){
1664 if( pTbl
->nCol
>p1
->nMax
) p1
->nMax
= pTbl
->nCol
;
1667 /* Allocate an array of (sqlite3_value*) in which to accumulate the values
1668 ** that will be written to the output database in a single row. */
1669 nByte
= sizeof(sqlite3_value
*) * (p1
->nMax
+1);
1670 p1
->apVal
= (sqlite3_value
**)recoverMalloc(p
, nByte
);
1671 if( p1
->apVal
==0 ) return p
->errCode
;
1673 /* Prepare the SELECT to loop through schema tables (pTbls) and the SELECT
1674 ** to loop through cells that appear to belong to a single table (pSel). */
1675 p1
->pTbls
= recoverPrepare(p
, p
->dbOut
,
1676 "SELECT rootpage FROM recovery.schema "
1677 " WHERE type='table' AND (sql NOT LIKE 'create virtual%')"
1678 " ORDER BY (tbl_name='sqlite_sequence') ASC"
1680 p1
->pSel
= recoverPrepare(p
, p
->dbOut
,
1681 "WITH RECURSIVE pages(page) AS ("
1684 " SELECT child FROM sqlite_dbptr('getpage()'), pages "
1687 "SELECT page, cell, field, value "
1688 "FROM sqlite_dbdata('getpage()') d, pages p WHERE p.page=d.pgno "
1697 ** Clean up resources allocated by recoverWriteDataInit() (stuff in
1698 ** sqlite3_recover.w1).
1700 static void recoverWriteDataCleanup(sqlite3_recover
*p
){
1701 RecoverStateW1
*p1
= &p
->w1
;
1703 for(ii
=0; ii
<p1
->nVal
; ii
++){
1704 sqlite3_value_free(p1
->apVal
[ii
]);
1706 sqlite3_free(p1
->apVal
);
1707 recoverFinalize(p
, p1
->pInsert
);
1708 recoverFinalize(p
, p1
->pTbls
);
1709 recoverFinalize(p
, p1
->pSel
);
1710 memset(p1
, 0, sizeof(*p1
));
1714 ** Perform one step (sqlite3_recover_step()) of work for the connection
1715 ** passed as the only argument, which is guaranteed to be in
1716 ** RECOVER_STATE_WRITING state - during which tables recovered from the
1717 ** schema of the input database are populated with recovered data.
1719 static int recoverWriteDataStep(sqlite3_recover
*p
){
1720 RecoverStateW1
*p1
= &p
->w1
;
1721 sqlite3_stmt
*pSel
= p1
->pSel
;
1722 sqlite3_value
**apVal
= p1
->apVal
;
1724 if( p
->errCode
==SQLITE_OK
&& p1
->pTab
==0 ){
1725 if( sqlite3_step(p1
->pTbls
)==SQLITE_ROW
){
1726 i64 iRoot
= sqlite3_column_int64(p1
->pTbls
, 0);
1727 p1
->pTab
= recoverFindTable(p
, iRoot
);
1729 recoverFinalize(p
, p1
->pInsert
);
1732 /* If this table is unknown, return early. The caller will invoke this
1733 ** function again and it will move on to the next table. */
1734 if( p1
->pTab
==0 ) return p
->errCode
;
1736 /* If this is the sqlite_sequence table, delete any rows added by
1737 ** earlier INSERT statements on tables with AUTOINCREMENT primary
1738 ** keys before recovering its contents. The p1->pTbls SELECT statement
1739 ** is rigged to deliver "sqlite_sequence" last of all, so we don't
1740 ** worry about it being modified after it is recovered. */
1741 if( sqlite3_stricmp("sqlite_sequence", p1
->pTab
->zTab
)==0 ){
1742 recoverExec(p
, p
->dbOut
, "DELETE FROM sqlite_sequence");
1743 recoverSqlCallback(p
, "DELETE FROM sqlite_sequence");
1746 /* Bind the root page of this table within the original database to
1747 ** SELECT statement p1->pSel. The SELECT statement will then iterate
1748 ** through cells that look like they belong to table pTab. */
1749 sqlite3_bind_int64(pSel
, 1, iRoot
);
1759 assert( p
->errCode
!=SQLITE_OK
|| p1
->pTab
);
1761 if( p
->errCode
==SQLITE_OK
&& sqlite3_step(pSel
)==SQLITE_ROW
){
1762 RecoverTable
*pTab
= p1
->pTab
;
1764 i64 iPage
= sqlite3_column_int64(pSel
, 0);
1765 int iCell
= sqlite3_column_int(pSel
, 1);
1766 int iField
= sqlite3_column_int(pSel
, 2);
1767 sqlite3_value
*pVal
= sqlite3_column_value(pSel
, 3);
1768 int bNewCell
= (p1
->iPrevPage
!=iPage
|| p1
->iPrevCell
!=iCell
);
1770 assert( bNewCell
==0 || (iField
==-1 || iField
==0) );
1771 assert( bNewCell
|| iField
==p1
->nVal
|| p1
->nVal
==pTab
->nCol
);
1776 if( p1
->pInsert
==0 || p1
->nVal
!=p1
->nInsert
){
1777 recoverFinalize(p
, p1
->pInsert
);
1778 p1
->pInsert
= recoverInsertStmt(p
, pTab
, p1
->nVal
);
1779 p1
->nInsert
= p1
->nVal
;
1782 sqlite3_stmt
*pInsert
= p1
->pInsert
;
1783 for(ii
=0; ii
<pTab
->nCol
; ii
++){
1784 RecoverColumn
*pCol
= &pTab
->aCol
[ii
];
1785 int iBind
= pCol
->iBind
;
1788 sqlite3_bind_int64(pInsert
, iBind
, p1
->iRowid
);
1789 }else if( pCol
->iField
<p1
->nVal
){
1790 recoverBindValue(p
, pInsert
, iBind
, apVal
[pCol
->iField
]);
1794 if( p
->bRecoverRowid
&& pTab
->iRowidBind
>0 && p1
->bHaveRowid
){
1795 sqlite3_bind_int64(pInsert
, pTab
->iRowidBind
, p1
->iRowid
);
1797 if( SQLITE_ROW
==sqlite3_step(pInsert
) ){
1798 const char *z
= (const char*)sqlite3_column_text(pInsert
, 0);
1799 recoverSqlCallback(p
, z
);
1801 recoverReset(p
, pInsert
);
1802 assert( p
->errCode
|| pInsert
);
1803 if( pInsert
) sqlite3_clear_bindings(pInsert
);
1807 for(ii
=0; ii
<p1
->nVal
; ii
++){
1808 sqlite3_value_free(apVal
[ii
]);
1817 p1
->iRowid
= sqlite3_column_int64(pSel
, 3);
1818 assert( p1
->nVal
==-1 );
1821 }else if( iField
<pTab
->nCol
){
1822 assert( apVal
[iField
]==0 );
1823 apVal
[iField
] = sqlite3_value_dup( pVal
);
1824 if( apVal
[iField
]==0 ){
1825 recoverError(p
, SQLITE_NOMEM
, 0);
1827 p1
->nVal
= iField
+1;
1829 p1
->iPrevCell
= iCell
;
1830 p1
->iPrevPage
= iPage
;
1833 recoverReset(p
, pSel
);
1841 ** Initialize resources required by sqlite3_recover_step() in
1842 ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not
1843 ** already allocated to a recovered schema element is determined.
1845 static void recoverLostAndFound1Init(sqlite3_recover
*p
){
1846 RecoverStateLAF
*pLaf
= &p
->laf
;
1847 sqlite3_stmt
*pStmt
= 0;
1849 assert( p
->laf
.pUsed
==0 );
1850 pLaf
->nPg
= recoverPageCount(p
);
1851 pLaf
->pUsed
= recoverBitmapAlloc(p
, pLaf
->nPg
);
1853 /* Prepare a statement to iterate through all pages that are part of any tree
1854 ** in the recoverable part of the input database schema to the bitmap. And,
1855 ** if !p->bFreelistCorrupt, add all pages that appear to be part of the
1857 pStmt
= recoverPrepare(
1859 "WITH trunk(pgno) AS ("
1860 " SELECT read_i32(getpage(1), 8) AS x WHERE x>0"
1862 " SELECT read_i32(getpage(trunk.pgno), 0) AS x FROM trunk WHERE x>0"
1864 "trunkdata(pgno, data) AS ("
1865 " SELECT pgno, getpage(pgno) FROM trunk"
1867 "freelist(data, n, freepgno) AS ("
1868 " SELECT data, min(16384, read_i32(data, 1)-1), pgno FROM trunkdata"
1870 " SELECT data, n-1, read_i32(data, 2+n) FROM freelist WHERE n>=0"
1874 " SELECT 1 UNION ALL"
1875 " SELECT rootpage FROM recovery.schema WHERE rootpage>0"
1878 " SELECT r FROM roots"
1880 " SELECT child FROM sqlite_dbptr('getpage()'), used "
1883 "SELECT page FROM used"
1885 "SELECT freepgno FROM freelist WHERE NOT ?"
1887 if( pStmt
) sqlite3_bind_int(pStmt
, 1, p
->bFreelistCorrupt
);
1888 pLaf
->pUsedPages
= pStmt
;
1892 ** Perform one step (sqlite3_recover_step()) of work for the connection
1893 ** passed as the only argument, which is guaranteed to be in
1894 ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not
1895 ** already allocated to a recovered schema element is determined.
1897 static int recoverLostAndFound1Step(sqlite3_recover
*p
){
1898 RecoverStateLAF
*pLaf
= &p
->laf
;
1899 int rc
= p
->errCode
;
1900 if( rc
==SQLITE_OK
){
1901 rc
= sqlite3_step(pLaf
->pUsedPages
);
1902 if( rc
==SQLITE_ROW
){
1903 i64 iPg
= sqlite3_column_int64(pLaf
->pUsedPages
, 0);
1904 recoverBitmapSet(pLaf
->pUsed
, iPg
);
1907 recoverFinalize(p
, pLaf
->pUsedPages
);
1908 pLaf
->pUsedPages
= 0;
1915 ** Initialize resources required by RECOVER_STATE_LOSTANDFOUND2
1916 ** state - during which the pages identified in RECOVER_STATE_LOSTANDFOUND1
1917 ** are sorted into sets that likely belonged to the same database tree.
1919 static void recoverLostAndFound2Init(sqlite3_recover
*p
){
1920 RecoverStateLAF
*pLaf
= &p
->laf
;
1922 assert( p
->laf
.pAllAndParent
==0 );
1923 assert( p
->laf
.pMapInsert
==0 );
1924 assert( p
->laf
.pMaxField
==0 );
1925 assert( p
->laf
.nMaxField
==0 );
1927 pLaf
->pMapInsert
= recoverPrepare(p
, p
->dbOut
,
1928 "INSERT OR IGNORE INTO recovery.map(pgno, parent) VALUES(?, ?)"
1930 pLaf
->pAllAndParent
= recoverPreparePrintf(p
, p
->dbOut
,
1931 "WITH RECURSIVE seq(ii) AS ("
1932 " SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld"
1934 "SELECT pgno, child FROM sqlite_dbptr('getpage()') "
1936 "SELECT NULL, ii FROM seq", p
->laf
.nPg
1938 pLaf
->pMaxField
= recoverPreparePrintf(p
, p
->dbOut
,
1939 "SELECT max(field)+1 FROM sqlite_dbdata('getpage') WHERE pgno = ?"
1944 ** Perform one step (sqlite3_recover_step()) of work for the connection
1945 ** passed as the only argument, which is guaranteed to be in
1946 ** RECOVER_STATE_LOSTANDFOUND2 state - during which the pages identified
1947 ** in RECOVER_STATE_LOSTANDFOUND1 are sorted into sets that likely belonged
1948 ** to the same database tree.
1950 static int recoverLostAndFound2Step(sqlite3_recover
*p
){
1951 RecoverStateLAF
*pLaf
= &p
->laf
;
1952 if( p
->errCode
==SQLITE_OK
){
1953 int res
= sqlite3_step(pLaf
->pAllAndParent
);
1954 if( res
==SQLITE_ROW
){
1955 i64 iChild
= sqlite3_column_int(pLaf
->pAllAndParent
, 1);
1956 if( recoverBitmapQuery(pLaf
->pUsed
, iChild
)==0 ){
1957 sqlite3_bind_int64(pLaf
->pMapInsert
, 1, iChild
);
1958 sqlite3_bind_value(pLaf
->pMapInsert
, 2,
1959 sqlite3_column_value(pLaf
->pAllAndParent
, 0)
1961 sqlite3_step(pLaf
->pMapInsert
);
1962 recoverReset(p
, pLaf
->pMapInsert
);
1963 sqlite3_bind_int64(pLaf
->pMaxField
, 1, iChild
);
1964 if( SQLITE_ROW
==sqlite3_step(pLaf
->pMaxField
) ){
1965 int nMax
= sqlite3_column_int(pLaf
->pMaxField
, 0);
1966 if( nMax
>pLaf
->nMaxField
) pLaf
->nMaxField
= nMax
;
1968 recoverReset(p
, pLaf
->pMaxField
);
1971 recoverFinalize(p
, pLaf
->pAllAndParent
);
1972 pLaf
->pAllAndParent
=0;
1980 ** Free all resources allocated as part of sqlite3_recover_step() calls
1981 ** in one of the RECOVER_STATE_LOSTANDFOUND[123] states.
1983 static void recoverLostAndFoundCleanup(sqlite3_recover
*p
){
1984 recoverBitmapFree(p
->laf
.pUsed
);
1986 sqlite3_finalize(p
->laf
.pUsedPages
);
1987 sqlite3_finalize(p
->laf
.pAllAndParent
);
1988 sqlite3_finalize(p
->laf
.pMapInsert
);
1989 sqlite3_finalize(p
->laf
.pMaxField
);
1990 sqlite3_finalize(p
->laf
.pFindRoot
);
1991 sqlite3_finalize(p
->laf
.pInsert
);
1992 sqlite3_finalize(p
->laf
.pAllPage
);
1993 sqlite3_finalize(p
->laf
.pPageData
);
1994 p
->laf
.pUsedPages
= 0;
1995 p
->laf
.pAllAndParent
= 0;
1996 p
->laf
.pMapInsert
= 0;
1997 p
->laf
.pMaxField
= 0;
1998 p
->laf
.pFindRoot
= 0;
2000 p
->laf
.pAllPage
= 0;
2001 p
->laf
.pPageData
= 0;
2002 sqlite3_free(p
->laf
.apVal
);
2007 ** Free all resources allocated as part of sqlite3_recover_step() calls.
2009 static void recoverFinalCleanup(sqlite3_recover
*p
){
2010 RecoverTable
*pTab
= 0;
2011 RecoverTable
*pNext
= 0;
2013 recoverWriteDataCleanup(p
);
2014 recoverLostAndFoundCleanup(p
);
2016 for(pTab
=p
->pTblList
; pTab
; pTab
=pNext
){
2017 pNext
= pTab
->pNext
;
2021 sqlite3_finalize(p
->pGetPage
);
2023 sqlite3_file_control(p
->dbIn
, p
->zDb
, SQLITE_FCNTL_RESET_CACHE
, 0);
2029 sqlite3_close(p
->dbOut
);
2030 assert( res
==SQLITE_OK
);
2036 ** Decode and return an unsigned 16-bit big-endian integer value from
2039 static u32
recoverGetU16(const u8
*a
){
2040 return (((u32
)a
[0])<<8) + ((u32
)a
[1]);
2044 ** Decode and return an unsigned 32-bit big-endian integer value from
2047 static u32
recoverGetU32(const u8
*a
){
2048 return (((u32
)a
[0])<<24) + (((u32
)a
[1])<<16) + (((u32
)a
[2])<<8) + ((u32
)a
[3]);
2052 ** Decode an SQLite varint from buffer a[]. Write the decoded value to (*pVal)
2053 ** and return the number of bytes consumed.
2055 static int recoverGetVarint(const u8
*a
, i64
*pVal
){
2056 sqlite3_uint64 u
= 0;
2059 u
= (u
<<7) + (a
[i
]&0x7f);
2060 if( (a
[i
]&0x80)==0 ){ *pVal
= (sqlite3_int64
)u
; return i
+1; }
2062 u
= (u
<<8) + (a
[i
]&0xff);
2063 *pVal
= (sqlite3_int64
)u
;
2068 ** The second argument points to a buffer n bytes in size. If this buffer
2069 ** or a prefix thereof appears to contain a well-formed SQLite b-tree page,
2070 ** return the page-size in bytes. Otherwise, if the buffer does not
2071 ** appear to contain a well-formed b-tree page, return 0.
2073 static int recoverIsValidPage(u8
*aTmp
, const u8
*a
, int n
){
2078 int nCell
= 0; /* Number of cells on page */
2079 int iCellOff
= 0; /* Offset of cell array in page */
2085 if( eType
!=0x02 && eType
!=0x05 && eType
!=0x0A && eType
!=0x0D ) return 0;
2087 iFree
= (int)recoverGetU16(&a
[1]);
2088 nCell
= (int)recoverGetU16(&a
[3]);
2089 iContent
= (int)recoverGetU16(&a
[5]);
2090 if( iContent
==0 ) iContent
= 65536;
2093 if( iContent
>n
) return 0;
2095 memset(aUsed
, 0, n
);
2096 memset(aUsed
, 0xFF, iContent
);
2098 /* Follow the free-list. This is the same format for all b-tree pages. */
2099 if( iFree
&& iFree
<=iContent
) return 0;
2103 if( iFree
>(n
-4) ) return 0;
2104 iNext
= recoverGetU16(&a
[iFree
]);
2105 nByte
= recoverGetU16(&a
[iFree
+2]);
2106 if( iFree
+nByte
>n
|| nByte
<4 ) return 0;
2107 if( iNext
&& iNext
<iFree
+nByte
) return 0;
2108 memset(&aUsed
[iFree
], 0xFF, nByte
);
2112 /* Run through the cells */
2113 if( eType
==0x02 || eType
==0x05 ){
2118 if( (iCellOff
+ 2*nCell
)>iContent
) return 0;
2119 for(ii
=0; ii
<nCell
; ii
++){
2123 int iOff
= recoverGetU16(&a
[iCellOff
+ 2*ii
]);
2124 if( iOff
<iContent
|| iOff
>n
){
2127 if( eType
==0x05 || eType
==0x02 ) nByte
+= 4;
2128 nByte
+= recoverGetVarint(&a
[iOff
+nByte
], &nPayload
);
2131 nByte
+= recoverGetVarint(&a
[iOff
+nByte
], &dummy
);
2134 int X
= (eType
==0x0D) ? n
-35 : (((n
-12)*64/255)-23);
2135 int M
= ((n
-12)*32/255)-23;
2136 int K
= M
+((nPayload
-M
)%(n
-4));
2150 for(iByte
=iOff
; iByte
<(iOff
+nByte
); iByte
++){
2151 if( aUsed
[iByte
]!=0 ){
2154 aUsed
[iByte
] = 0xFF;
2159 for(ii
=0; ii
<n
; ii
++){
2160 if( aUsed
[ii
]==0 ) nActual
++;
2162 return (nActual
==nFrag
);
2166 static int recoverVfsClose(sqlite3_file
*);
2167 static int recoverVfsRead(sqlite3_file
*, void*, int iAmt
, sqlite3_int64 iOfst
);
2168 static int recoverVfsWrite(sqlite3_file
*, const void*, int, sqlite3_int64
);
2169 static int recoverVfsTruncate(sqlite3_file
*, sqlite3_int64 size
);
2170 static int recoverVfsSync(sqlite3_file
*, int flags
);
2171 static int recoverVfsFileSize(sqlite3_file
*, sqlite3_int64
*pSize
);
2172 static int recoverVfsLock(sqlite3_file
*, int);
2173 static int recoverVfsUnlock(sqlite3_file
*, int);
2174 static int recoverVfsCheckReservedLock(sqlite3_file
*, int *pResOut
);
2175 static int recoverVfsFileControl(sqlite3_file
*, int op
, void *pArg
);
2176 static int recoverVfsSectorSize(sqlite3_file
*);
2177 static int recoverVfsDeviceCharacteristics(sqlite3_file
*);
2178 static int recoverVfsShmMap(sqlite3_file
*, int, int, int, void volatile**);
2179 static int recoverVfsShmLock(sqlite3_file
*, int offset
, int n
, int flags
);
2180 static void recoverVfsShmBarrier(sqlite3_file
*);
2181 static int recoverVfsShmUnmap(sqlite3_file
*, int deleteFlag
);
2182 static int recoverVfsFetch(sqlite3_file
*, sqlite3_int64
, int, void**);
2183 static int recoverVfsUnfetch(sqlite3_file
*pFd
, sqlite3_int64 iOff
, void *p
);
2185 static sqlite3_io_methods recover_methods
= {
2195 recoverVfsCheckReservedLock
,
2196 recoverVfsFileControl
,
2197 recoverVfsSectorSize
,
2198 recoverVfsDeviceCharacteristics
,
2201 recoverVfsShmBarrier
,
2207 static int recoverVfsClose(sqlite3_file
*pFd
){
2208 assert( pFd
->pMethods
!=&recover_methods
);
2209 return pFd
->pMethods
->xClose(pFd
);
2213 ** Write value v to buffer a[] as a 16-bit big-endian unsigned integer.
2215 static void recoverPutU16(u8
*a
, u32 v
){
2216 a
[0] = (v
>>8) & 0x00FF;
2217 a
[1] = (v
>>0) & 0x00FF;
2221 ** Write value v to buffer a[] as a 32-bit big-endian unsigned integer.
2223 static void recoverPutU32(u8
*a
, u32 v
){
2224 a
[0] = (v
>>24) & 0x00FF;
2225 a
[1] = (v
>>16) & 0x00FF;
2226 a
[2] = (v
>>8) & 0x00FF;
2227 a
[3] = (v
>>0) & 0x00FF;
2231 ** Detect the page-size of the database opened by file-handle pFd by
2232 ** searching the first part of the file for a well-formed SQLite b-tree
2233 ** page. If parameter nReserve is non-zero, then as well as searching for
2234 ** a b-tree page with zero reserved bytes, this function searches for one
2235 ** with nReserve reserved bytes at the end of it.
2237 ** If successful, set variable p->detected_pgsz to the detected page-size
2238 ** in bytes and return SQLITE_OK. Or, if no error occurs but no valid page
2239 ** can be found, return SQLITE_OK but leave p->detected_pgsz set to 0. Or,
2240 ** if an error occurs (e.g. an IO or OOM error), then an SQLite error code
2241 ** is returned. The final value of p->detected_pgsz is undefined in this
2244 static int recoverVfsDetectPagesize(
2245 sqlite3_recover
*p
, /* Recover handle */
2246 sqlite3_file
*pFd
, /* File-handle open on input database */
2247 u32 nReserve
, /* Possible nReserve value */
2248 i64 nSz
/* Size of database file in bytes */
2251 const int nMin
= 512;
2252 const int nMax
= 65536;
2253 const int nMaxBlk
= 4;
2260 aPg
= (u8
*)sqlite3_malloc(2*nMax
);
2261 if( aPg
==0 ) return SQLITE_NOMEM
;
2264 nBlk
= (nSz
+nMax
-1)/nMax
;
2265 if( nBlk
>nMaxBlk
) nBlk
= nMaxBlk
;
2268 for(iBlk
=0; rc
==SQLITE_OK
&& iBlk
<nBlk
; iBlk
++){
2269 int nByte
= (nSz
>=((iBlk
+1)*nMax
)) ? nMax
: (nSz
% nMax
);
2270 memset(aPg
, 0, nMax
);
2271 rc
= pFd
->pMethods
->xRead(pFd
, aPg
, nByte
, iBlk
*nMax
);
2272 if( rc
==SQLITE_OK
){
2274 for(pgsz2
=(pgsz
? pgsz
*2 : nMin
); pgsz2
<=nMax
; pgsz2
=pgsz2
*2){
2276 for(iOff
=0; iOff
<nMax
; iOff
+=pgsz2
){
2277 if( recoverIsValidPage(aTmp
, &aPg
[iOff
], pgsz2
-nReserve
) ){
2285 if( pgsz
>(u32
)p
->detected_pgsz
){
2286 p
->detected_pgsz
= pgsz
;
2287 p
->nReserve
= nReserve
;
2289 if( nReserve
==0 ) break;
2293 p
->detected_pgsz
= pgsz
;
2299 ** The xRead() method of the wrapper VFS. This is used to intercept calls
2300 ** to read page 1 of the input database.
2302 static int recoverVfsRead(sqlite3_file
*pFd
, void *aBuf
, int nByte
, i64 iOff
){
2304 if( pFd
->pMethods
==&recover_methods
){
2305 pFd
->pMethods
= recover_g
.pMethods
;
2306 rc
= pFd
->pMethods
->xRead(pFd
, aBuf
, nByte
, iOff
);
2308 sqlite3_randomness(16, aBuf
);
2310 if( rc
==SQLITE_OK
&& iOff
==0 && nByte
>=108 ){
2311 /* Ensure that the database has a valid header file. The only fields
2312 ** that really matter to recovery are:
2314 ** + Database page size (16-bits at offset 16)
2315 ** + Size of db in pages (32-bits at offset 28)
2316 ** + Database encoding (32-bits at offset 56)
2318 ** Also preserved are:
2320 ** + first freelist page (32-bits at offset 32)
2321 ** + size of freelist (32-bits at offset 36)
2322 ** + the wal-mode flags (16-bits at offset 18)
2324 ** We also try to preserve the auto-vacuum, incr-value, user-version
2325 ** and application-id fields - all 32 bit quantities at offsets
2326 ** 52, 60, 64 and 68. All other fields are set to known good values.
2328 ** Byte offset 105 should also contain the page-size as a 16-bit
2331 const int aPreserve
[] = {32, 36, 52, 60, 64, 68};
2333 0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66,
2334 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00,
2335 0xFF, 0xFF, 0x01, 0x01, 0x00, 0x40, 0x20, 0x20,
2336 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
2337 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
2339 0x00, 0x00, 0x10, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
2340 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2341 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2345 0x00, 0x2e, 0x5b, 0x30,
2347 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00
2351 u32 pgsz
= recoverGetU16(&a
[16]);
2352 u32 nReserve
= a
[20];
2353 u32 enc
= recoverGetU32(&a
[56]);
2357 sqlite3_recover
*p
= recover_g
.p
;
2359 if( pgsz
==0x01 ) pgsz
= 65536;
2360 rc
= pFd
->pMethods
->xFileSize(pFd
, &dbFileSize
);
2362 if( rc
==SQLITE_OK
&& p
->detected_pgsz
==0 ){
2363 rc
= recoverVfsDetectPagesize(p
, pFd
, nReserve
, dbFileSize
);
2365 if( p
->detected_pgsz
){
2366 pgsz
= p
->detected_pgsz
;
2367 nReserve
= p
->nReserve
;
2371 dbsz
= dbFileSize
/ pgsz
;
2373 if( enc
!=SQLITE_UTF8
&& enc
!=SQLITE_UTF16BE
&& enc
!=SQLITE_UTF16LE
){
2377 sqlite3_free(p
->pPage1Cache
);
2382 p
->pPage1Cache
= (u8
*)recoverMalloc(p
, nByte
*2);
2383 if( p
->pPage1Cache
){
2384 p
->pPage1Disk
= &p
->pPage1Cache
[nByte
];
2385 memcpy(p
->pPage1Disk
, aBuf
, nByte
);
2388 recoverPutU32(&aHdr
[28], dbsz
);
2389 recoverPutU32(&aHdr
[56], enc
);
2390 recoverPutU16(&aHdr
[105], pgsz
-nReserve
);
2391 if( pgsz
==65536 ) pgsz
= 1;
2392 recoverPutU16(&aHdr
[16], pgsz
);
2393 aHdr
[20] = nReserve
;
2394 for(ii
=0; ii
<(int)(sizeof(aPreserve
)/sizeof(aPreserve
[0])); ii
++){
2395 memcpy(&aHdr
[aPreserve
[ii
]], &a
[aPreserve
[ii
]], 4);
2397 memcpy(aBuf
, aHdr
, sizeof(aHdr
));
2398 memset(&((u8
*)aBuf
)[sizeof(aHdr
)], 0, nByte
-sizeof(aHdr
));
2400 memcpy(p
->pPage1Cache
, aBuf
, nByte
);
2406 pFd
->pMethods
= &recover_methods
;
2408 rc
= pFd
->pMethods
->xRead(pFd
, aBuf
, nByte
, iOff
);
2414 ** Used to make sqlite3_io_methods wrapper methods less verbose.
2416 #define RECOVER_VFS_WRAPPER(code) \
2417 int rc = SQLITE_OK; \
2418 if( pFd->pMethods==&recover_methods ){ \
2419 pFd->pMethods = recover_g.pMethods; \
2421 pFd->pMethods = &recover_methods; \
2428 ** Methods of the wrapper VFS. All methods except for xRead() and xClose()
2429 ** simply uninstall the sqlite3_io_methods wrapper, invoke the equivalent
2430 ** method on the lower level VFS, then reinstall the wrapper before returning.
2431 ** Those that return an integer value use the RECOVER_VFS_WRAPPER macro.
2433 static int recoverVfsWrite(
2434 sqlite3_file
*pFd
, const void *aBuf
, int nByte
, i64 iOff
2436 RECOVER_VFS_WRAPPER (
2437 pFd
->pMethods
->xWrite(pFd
, aBuf
, nByte
, iOff
)
2440 static int recoverVfsTruncate(sqlite3_file
*pFd
, sqlite3_int64 size
){
2441 RECOVER_VFS_WRAPPER (
2442 pFd
->pMethods
->xTruncate(pFd
, size
)
2445 static int recoverVfsSync(sqlite3_file
*pFd
, int flags
){
2446 RECOVER_VFS_WRAPPER (
2447 pFd
->pMethods
->xSync(pFd
, flags
)
2450 static int recoverVfsFileSize(sqlite3_file
*pFd
, sqlite3_int64
*pSize
){
2451 RECOVER_VFS_WRAPPER (
2452 pFd
->pMethods
->xFileSize(pFd
, pSize
)
2455 static int recoverVfsLock(sqlite3_file
*pFd
, int eLock
){
2456 RECOVER_VFS_WRAPPER (
2457 pFd
->pMethods
->xLock(pFd
, eLock
)
2460 static int recoverVfsUnlock(sqlite3_file
*pFd
, int eLock
){
2461 RECOVER_VFS_WRAPPER (
2462 pFd
->pMethods
->xUnlock(pFd
, eLock
)
2465 static int recoverVfsCheckReservedLock(sqlite3_file
*pFd
, int *pResOut
){
2466 RECOVER_VFS_WRAPPER (
2467 pFd
->pMethods
->xCheckReservedLock(pFd
, pResOut
)
2470 static int recoverVfsFileControl(sqlite3_file
*pFd
, int op
, void *pArg
){
2471 RECOVER_VFS_WRAPPER (
2472 (pFd
->pMethods
? pFd
->pMethods
->xFileControl(pFd
, op
, pArg
) : SQLITE_NOTFOUND
)
2475 static int recoverVfsSectorSize(sqlite3_file
*pFd
){
2476 RECOVER_VFS_WRAPPER (
2477 pFd
->pMethods
->xSectorSize(pFd
)
2480 static int recoverVfsDeviceCharacteristics(sqlite3_file
*pFd
){
2481 RECOVER_VFS_WRAPPER (
2482 pFd
->pMethods
->xDeviceCharacteristics(pFd
)
2485 static int recoverVfsShmMap(
2486 sqlite3_file
*pFd
, int iPg
, int pgsz
, int bExtend
, void volatile **pp
2488 RECOVER_VFS_WRAPPER (
2489 pFd
->pMethods
->xShmMap(pFd
, iPg
, pgsz
, bExtend
, pp
)
2492 static int recoverVfsShmLock(sqlite3_file
*pFd
, int offset
, int n
, int flags
){
2493 RECOVER_VFS_WRAPPER (
2494 pFd
->pMethods
->xShmLock(pFd
, offset
, n
, flags
)
2497 static void recoverVfsShmBarrier(sqlite3_file
*pFd
){
2498 if( pFd
->pMethods
==&recover_methods
){
2499 pFd
->pMethods
= recover_g
.pMethods
;
2500 pFd
->pMethods
->xShmBarrier(pFd
);
2501 pFd
->pMethods
= &recover_methods
;
2503 pFd
->pMethods
->xShmBarrier(pFd
);
2506 static int recoverVfsShmUnmap(sqlite3_file
*pFd
, int deleteFlag
){
2507 RECOVER_VFS_WRAPPER (
2508 pFd
->pMethods
->xShmUnmap(pFd
, deleteFlag
)
2512 static int recoverVfsFetch(
2524 static int recoverVfsUnfetch(sqlite3_file
*pFd
, sqlite3_int64 iOff
, void *p
){
2532 ** Install the VFS wrapper around the file-descriptor open on the input
2533 ** database for recover handle p. Mutex RECOVER_MUTEX_ID must be held
2534 ** when this function is called.
2536 static void recoverInstallWrapper(sqlite3_recover
*p
){
2537 sqlite3_file
*pFd
= 0;
2538 assert( recover_g
.pMethods
==0 );
2539 recoverAssertMutexHeld();
2540 sqlite3_file_control(p
->dbIn
, p
->zDb
, SQLITE_FCNTL_FILE_POINTER
, (void*)&pFd
);
2541 assert( pFd
==0 || pFd
->pMethods
!=&recover_methods
);
2542 if( pFd
&& pFd
->pMethods
){
2543 int iVersion
= 1 + (pFd
->pMethods
->iVersion
>1 && pFd
->pMethods
->xShmMap
!=0);
2544 recover_g
.pMethods
= pFd
->pMethods
;
2546 recover_methods
.iVersion
= iVersion
;
2547 pFd
->pMethods
= &recover_methods
;
2552 ** Uninstall the VFS wrapper that was installed around the file-descriptor open
2553 ** on the input database for recover handle p. Mutex RECOVER_MUTEX_ID must be
2554 ** held when this function is called.
2556 static void recoverUninstallWrapper(sqlite3_recover
*p
){
2557 sqlite3_file
*pFd
= 0;
2558 recoverAssertMutexHeld();
2559 sqlite3_file_control(p
->dbIn
, p
->zDb
,SQLITE_FCNTL_FILE_POINTER
,(void*)&pFd
);
2560 if( pFd
&& pFd
->pMethods
){
2561 pFd
->pMethods
= recover_g
.pMethods
;
2562 recover_g
.pMethods
= 0;
2568 ** This function does the work of a single sqlite3_recover_step() call. It
2569 ** is guaranteed that the handle is not in an error state when this
2570 ** function is called.
2572 static void recoverStep(sqlite3_recover
*p
){
2573 assert( p
&& p
->errCode
==SQLITE_OK
);
2574 switch( p
->eState
){
2575 case RECOVER_STATE_INIT
:
2576 /* This is the very first call to sqlite3_recover_step() on this object.
2578 recoverSqlCallback(p
, "BEGIN");
2579 recoverSqlCallback(p
, "PRAGMA writable_schema = on");
2581 recoverEnterMutex();
2582 recoverInstallWrapper(p
);
2584 /* Open the output database. And register required virtual tables and
2585 ** user functions with the new handle. */
2586 recoverOpenOutput(p
);
2588 /* Open transactions on both the input and output databases. */
2589 sqlite3_file_control(p
->dbIn
, p
->zDb
, SQLITE_FCNTL_RESET_CACHE
, 0);
2590 recoverExec(p
, p
->dbIn
, "PRAGMA writable_schema = on");
2591 recoverExec(p
, p
->dbIn
, "BEGIN");
2592 if( p
->errCode
==SQLITE_OK
) p
->bCloseTransaction
= 1;
2593 recoverExec(p
, p
->dbIn
, "SELECT 1 FROM sqlite_schema");
2594 recoverTransferSettings(p
);
2595 recoverOpenRecovery(p
);
2596 recoverCacheSchema(p
);
2598 recoverUninstallWrapper(p
);
2599 recoverLeaveMutex();
2601 recoverExec(p
, p
->dbOut
, "BEGIN");
2603 recoverWriteSchema1(p
);
2604 p
->eState
= RECOVER_STATE_WRITING
;
2607 case RECOVER_STATE_WRITING
: {
2608 if( p
->w1
.pTbls
==0 ){
2609 recoverWriteDataInit(p
);
2611 if( SQLITE_DONE
==recoverWriteDataStep(p
) ){
2612 recoverWriteDataCleanup(p
);
2613 if( p
->zLostAndFound
){
2614 p
->eState
= RECOVER_STATE_LOSTANDFOUND1
;
2616 p
->eState
= RECOVER_STATE_SCHEMA2
;
2622 case RECOVER_STATE_LOSTANDFOUND1
: {
2623 if( p
->laf
.pUsed
==0 ){
2624 recoverLostAndFound1Init(p
);
2626 if( SQLITE_DONE
==recoverLostAndFound1Step(p
) ){
2627 p
->eState
= RECOVER_STATE_LOSTANDFOUND2
;
2631 case RECOVER_STATE_LOSTANDFOUND2
: {
2632 if( p
->laf
.pAllAndParent
==0 ){
2633 recoverLostAndFound2Init(p
);
2635 if( SQLITE_DONE
==recoverLostAndFound2Step(p
) ){
2636 p
->eState
= RECOVER_STATE_LOSTANDFOUND3
;
2641 case RECOVER_STATE_LOSTANDFOUND3
: {
2642 if( p
->laf
.pInsert
==0 ){
2643 recoverLostAndFound3Init(p
);
2645 if( SQLITE_DONE
==recoverLostAndFound3Step(p
) ){
2646 p
->eState
= RECOVER_STATE_SCHEMA2
;
2651 case RECOVER_STATE_SCHEMA2
: {
2654 recoverWriteSchema2(p
);
2655 p
->eState
= RECOVER_STATE_DONE
;
2657 /* If no error has occurred, commit the write transaction on the output
2658 ** database. Regardless of whether or not an error has occurred, make
2659 ** an attempt to end the read transaction on the input database. */
2660 recoverExec(p
, p
->dbOut
, "COMMIT");
2661 rc
= sqlite3_exec(p
->dbIn
, "END", 0, 0, 0);
2662 if( p
->errCode
==SQLITE_OK
) p
->errCode
= rc
;
2664 recoverSqlCallback(p
, "PRAGMA writable_schema = off");
2665 recoverSqlCallback(p
, "COMMIT");
2666 p
->eState
= RECOVER_STATE_DONE
;
2667 recoverFinalCleanup(p
);
2671 case RECOVER_STATE_DONE
: {
2680 ** This is a worker function that does the heavy lifting for both init
2683 ** sqlite3_recover_init()
2684 ** sqlite3_recover_init_sql()
2686 ** All this function does is allocate space for the recover handle and
2687 ** take copies of the input parameters. All the real work is done within
2688 ** sqlite3_recover_run().
2690 sqlite3_recover
*recoverInit(
2693 const char *zUri
, /* Output URI for _recover_init() */
2694 int (*xSql
)(void*, const char*),/* SQL callback for _recover_init_sql() */
2695 void *pSqlCtx
/* Context arg for _recover_init_sql() */
2697 sqlite3_recover
*pRet
= 0;
2702 if( zDb
==0 ){ zDb
= "main"; }
2704 nDb
= recoverStrlen(zDb
);
2705 nUri
= recoverStrlen(zUri
);
2707 nByte
= sizeof(sqlite3_recover
) + nDb
+1 + nUri
+1;
2708 pRet
= (sqlite3_recover
*)sqlite3_malloc(nByte
);
2710 memset(pRet
, 0, nByte
);
2712 pRet
->zDb
= (char*)&pRet
[1];
2713 pRet
->zUri
= &pRet
->zDb
[nDb
+1];
2714 memcpy(pRet
->zDb
, zDb
, nDb
);
2715 if( nUri
>0 && zUri
) memcpy(pRet
->zUri
, zUri
, nUri
);
2717 pRet
->pSqlCtx
= pSqlCtx
;
2718 pRet
->bRecoverRowid
= RECOVER_ROWID_DEFAULT
;
2725 ** Initialize a recovery handle that creates a new database containing
2726 ** the recovered data.
2728 sqlite3_recover
*sqlite3_recover_init(
2733 return recoverInit(db
, zDb
, zUri
, 0, 0);
2737 ** Initialize a recovery handle that returns recovered data in the
2738 ** form of SQL statements via a callback.
2740 sqlite3_recover
*sqlite3_recover_init_sql(
2743 int (*xSql
)(void*, const char*),
2746 return recoverInit(db
, zDb
, 0, xSql
, pSqlCtx
);
2750 ** Return the handle error message, if any.
2752 const char *sqlite3_recover_errmsg(sqlite3_recover
*p
){
2753 return (p
&& p
->errCode
!=SQLITE_NOMEM
) ? p
->zErrMsg
: "out of memory";
2757 ** Return the handle error code.
2759 int sqlite3_recover_errcode(sqlite3_recover
*p
){
2760 return p
? p
->errCode
: SQLITE_NOMEM
;
2764 ** Configure the handle.
2766 int sqlite3_recover_config(sqlite3_recover
*p
, int op
, void *pArg
){
2770 }else if( p
->eState
!=RECOVER_STATE_INIT
){
2775 /* This undocumented magic configuration option is used to set the
2776 ** name of the auxiliary database that is ATTACH-ed to the database
2777 ** connection and used to hold state information during the
2778 ** recovery process. This option is for debugging use only and
2779 ** is subject to change or removal at any time. */
2780 sqlite3_free(p
->zStateDb
);
2781 p
->zStateDb
= recoverMPrintf(p
, "%s", (char*)pArg
);
2784 case SQLITE_RECOVER_LOST_AND_FOUND
: {
2785 const char *zArg
= (const char*)pArg
;
2786 sqlite3_free(p
->zLostAndFound
);
2788 p
->zLostAndFound
= recoverMPrintf(p
, "%s", zArg
);
2790 p
->zLostAndFound
= 0;
2795 case SQLITE_RECOVER_FREELIST_CORRUPT
:
2796 p
->bFreelistCorrupt
= *(int*)pArg
;
2799 case SQLITE_RECOVER_ROWIDS
:
2800 p
->bRecoverRowid
= *(int*)pArg
;
2803 case SQLITE_RECOVER_SLOWINDEXES
:
2804 p
->bSlowIndexes
= *(int*)pArg
;
2808 rc
= SQLITE_NOTFOUND
;
2817 ** Do a unit of work towards the recovery job. Return SQLITE_OK if
2818 ** no error has occurred but database recovery is not finished, SQLITE_DONE
2819 ** if database recovery has been successfully completed, or an SQLite
2820 ** error code if an error has occurred.
2822 int sqlite3_recover_step(sqlite3_recover
*p
){
2823 if( p
==0 ) return SQLITE_NOMEM
;
2824 if( p
->errCode
==SQLITE_OK
) recoverStep(p
);
2825 if( p
->eState
==RECOVER_STATE_DONE
&& p
->errCode
==SQLITE_OK
){
2832 ** Do the configured recovery operation. Return SQLITE_OK if successful, or
2833 ** else an SQLite error code.
2835 int sqlite3_recover_run(sqlite3_recover
*p
){
2836 while( SQLITE_OK
==sqlite3_recover_step(p
) );
2837 return sqlite3_recover_errcode(p
);
2842 ** Free all resources associated with the recover handle passed as the only
2843 ** argument. The results of using a handle with any sqlite3_recover_**
2844 ** API function after it has been passed to this function are undefined.
2846 ** A copy of the value returned by the first call made to sqlite3_recover_run()
2847 ** on this handle is returned, or SQLITE_OK if sqlite3_recover_run() has
2848 ** not been called on this handle.
2850 int sqlite3_recover_finish(sqlite3_recover
*p
){
2855 recoverFinalCleanup(p
);
2856 if( p
->bCloseTransaction
&& sqlite3_get_autocommit(p
->dbIn
)==0 ){
2857 rc
= sqlite3_exec(p
->dbIn
, "END", 0, 0, 0);
2858 if( p
->errCode
==SQLITE_OK
) p
->errCode
= rc
;
2861 sqlite3_free(p
->zErrMsg
);
2862 sqlite3_free(p
->zStateDb
);
2863 sqlite3_free(p
->zLostAndFound
);
2864 sqlite3_free(p
->pPage1Cache
);
2870 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */