1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Further fixes to comments in sqlite3recover.h. Also rework some data structures in sqlite3recover.c.

FossilOrigin-Name: 599d1f8ec2f9e24924a6f9e66c85664360c7b95531b07a4efe1dd8c096b3fc99
This commit is contained in:
dan
2022-09-09 20:44:56 +00:00
parent 7920162093
commit bc2e7fc228
6 changed files with 181 additions and 65 deletions

View File

@ -20,7 +20,76 @@
typedef unsigned int u32;
typedef sqlite3_int64 i64;
typedef struct RecoverTable RecoverTable;
typedef struct RecoverColumn RecoverColumn;
/*
** When recovering rows of data that can be associated with table
** definitions recovered from the sqlite_schema table, each table is
** represented by an instance of the following object.
**
** iRoot:
** The root page in the original database. Not necessarily (and usually
** not) the same in the recovered database.
**
** zTab:
** Name of the table.
**
** nCol/aCol[]:
** aCol[] is an array of nCol columns. In the order in which they appear
** in the table.
**
** bIntkey:
** Set to true for intkey tables, false for WITHOUT ROWID.
**
** iRowidBind:
** Each column in the aCol[] array has associated with it the index of
** the bind parameter its values will be bound to in the INSERT statement
** used to construct the output database. If the table does has a rowid
** but not an INTEGER PRIMARY KEY column, then iRowidBind contains the
** index of the bind paramater to which the rowid value should be bound.
** Otherwise, it contains -1. If the table does contain an INTEGER PRIMARY
** KEY column, then the rowid value should be bound to the index associated
** with the column.
**
** pNext:
** All RecoverTable objects used by the recovery operation are allocated
** and populated as part of creating the recovered database schema in
** the output database, before any non-schema data are recovered. They
** are then stored in a singly-linked list linked by this variable beginning
** at sqlite3_recover.pTblList.
*/
struct RecoverTable {
u32 iRoot; /* Root page in original database */
char *zTab; /* Name of table */
int nCol; /* Number of columns in table */
RecoverColumn *aCol; /* Array of columns */
int bIntkey; /* True for intkey, false for without rowid */
int iRowidBind; /* If >0, bind rowid to INSERT here */
RecoverTable *pNext;
};
/*
** Each database column is represented by an instance of the following object
** stored in the RecoverTable.aCol[] array of the associated table.
**
** iField:
** The index of the associated field within database records. Or -1 if
** there is no associated field (e.g. for virtual generated columns).
**
** iBind:
** The bind index of the INSERT statement to bind this columns values
** to. Or 0 if there is no such index (iff (iField<0)).
**
** bIPK:
** True if this is the INTEGER PRIMARY KEY column.
**
** zCol:
** Name of column.
**
** eHidden:
** A RECOVER_EHIDDEN_* constant value (see below for interpretation of each).
*/
struct RecoverColumn {
int iField; /* Field in record on disk */
int iBind; /* Binding to use in INSERT */
@ -29,59 +98,62 @@ struct RecoverColumn {
int eHidden;
};
#define RECOVER_EHIDDEN_NONE 0
#define RECOVER_EHIDDEN_HIDDEN 1
#define RECOVER_EHIDDEN_VIRTUAL 2
#define RECOVER_EHIDDEN_STORED 3
#define RECOVER_EHIDDEN_NONE 0 /* Normal database column */
#define RECOVER_EHIDDEN_HIDDEN 1 /* Column is __HIDDEN__ */
#define RECOVER_EHIDDEN_VIRTUAL 2 /* Virtual generated column */
#define RECOVER_EHIDDEN_STORED 3 /* Stored generated column */
/*
** When running the ".recover" command, each output table, and the special
** orphaned row table if it is required, is represented by an instance
** of the following struct.
** Bitmap object used to track pages in the input database. Allocated
** and manipulated only by the following functions:
**
** aCol[]:
** Array of nCol columns. In the order in which they appear in the table.
** recoverBitmapAlloc()
** recoverBitmapFree()
** recoverBitmapSet()
** recoverBitmapQuery()
**
** nPg:
** Largest page number that may be stored in the bitmap. The range
** of valid keys is 1 to nPg, inclusive.
**
** aElem[]:
** Array large enough to contain a bit for each key. For key value
** iKey, the associated bit is the bit (iKey%32) of aElem[iKey/32].
** In other words, the following is true if bit iKey is set, or
** false if it is clear:
**
** (aElem[iKey/32] & (1 << (iKey%32))) ? 1 : 0
*/
typedef struct RecoverTable RecoverTable;
struct RecoverTable {
u32 iRoot; /* Root page in original database */
char *zTab; /* Name of table */
int nCol; /* Number of columns in table */
RecoverColumn *aCol; /* Array of columns */
int bIntkey; /* True for intkey, false for without rowid */
int iRowidBind; /* If >0, bind rowid to INSERT here */
RecoverTable *pNext;
};
typedef struct RecoverBitmap RecoverBitmap;
struct RecoverBitmap {
i64 nPg; /* Size of bitmap */
u32 aElem[0]; /* Array of 32-bit bitmasks */
};
/*
**
*/
struct sqlite3_recover {
sqlite3 *dbIn;
sqlite3 *dbOut;
sqlite3 *dbIn; /* Input database */
sqlite3 *dbOut; /* Output database */
sqlite3_stmt *pGetPage;
sqlite3_stmt *pGetPage; /* SELECT against input db sqlite_dbdata */
char *zDb;
char *zUri;
RecoverTable *pTblList;
char *zDb; /* Name of input db ("main" etc.) */
char *zUri; /* URI for output database */
RecoverTable *pTblList; /* List of tables recovered from schem */
RecoverBitmap *pUsed; /* Used by recoverLostAndFound() */
int errCode; /* For sqlite3_recover_errcode() */
char *zErrMsg; /* For sqlite3_recover_errmsg() */
char *zStateDb;
char *zStateDb; /* State database to use (or NULL) */
char *zLostAndFound; /* Name of lost-and-found table (or NULL) */
int bFreelistCorrupt;
int bRecoverRowid;
int bFreelistCorrupt; /* SQLITE_RECOVER_FREELIST_CORRUPT setting */
int bRecoverRowid; /* SQLITE_RECOVER_ROWIDS setting */
void *pSqlCtx;
int (*xSql)(void*,const char*);
void *pSqlCtx; /* SQL callback context */
int (*xSql)(void*,const char*); /* Pointer to SQL callback function */
};
/*
@ -1340,7 +1412,7 @@ int sqlite3_recover_config(sqlite3_recover *p, int op, void *pArg){
int rc = SQLITE_OK;
switch( op ){
case SQLITE_RECOVER_TESTDB:
case 789:
sqlite3_free(p->zStateDb);
p->zStateDb = recoverMPrintf(p, "%s", (char*)pArg);
break;

View File

@ -37,7 +37,6 @@
** using sqlite3_recover_finish().
*/
#ifndef _SQLITE_RECOVER_H
#define _SQLITE_RECOVER_H
@ -95,13 +94,18 @@ sqlite3_recover *sqlite3_recover_init_sql(
);
/*
** Configure an sqlite3_recover object that has just been created using
** sqlite3_recover_init() or sqlite3_recover_init_sql(). The second
** argument passed to this function must be one of the SQLITE_RECOVER_*
** symbols defined below. Valid values for the third argument depend
** on the specific SQLITE_RECOVER_* symbol in use.
**
** SQLITE_OK is returned if the configuration operation was successful,
** or an SQLite error code otherwise.
*/
int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg);
/*
** SQLITE_RECOVER_TESTDB:
**
** SQLITE_RECOVER_LOST_AND_FOUND:
** The pArg argument points to a string buffer containing the name
** of a "lost-and-found" table in the output database, or NULL. If
@ -118,41 +122,79 @@ int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg);
** corrupt and an attempt is made to recover records from pages that
** appear to be linked into the freelist. Otherwise, pages on the freelist
** are ignored. Setting this option can recover more data from the
** database, but often ends up "recovering" deleted records.
** database, but often ends up "recovering" deleted records. The default
** value is 0 (clear).
**
** SQLITE_RECOVER_ROWIDS:
**
** SQLITE_RECOVER_SQLHOOK:
** The pArg value must actually be a pointer to a value of type
** int containing value 0 or 1 cast as a (void*). If this option is set
** (argument is 1), then an attempt is made to recover rowid values
** that are not also INTEGER PRIMARY KEY values. If this option is
** clear, then new rowids are assigned to all recovered rows. The
** default value is 1 (set).
*/
#define SQLITE_RECOVER_TESTDB 789
#define SQLITE_RECOVER_LOST_AND_FOUND 790
#define SQLITE_RECOVER_FREELIST_CORRUPT 791
#define SQLITE_RECOVER_ROWIDS 792
#define SQLITE_RECOVER_LOST_AND_FOUND 1
#define SQLITE_RECOVER_FREELIST_CORRUPT 2
#define SQLITE_RECOVER_ROWIDS 3
/*
** Run the recovery. Return an SQLite error code if an error occurs, or
** SQLITE_OK otherwise.
** Run the recovery operation. This function does not return until the
** recovery operation is completed - either the new database has been
** created and populated (sqlite3_recover_init()) or all SQL statements have
** been passed to the callback (sqlite3_recover_init_sql()) - or an error
** occurs. If the recovery is completed without error, SQLITE_OK
** is returned. It is not considered an error if data cannot be recovered
** due to database corruption.
**
** If an error (for example an out-of-memory or IO error) occurs, then
** an SQLite error code is returned. The final state of the output database
** or the results of running any SQL statements already passed to the
** callback in this case are undefined. An English language error
** message corresponding to the error may be available via the
** sqlite3_recover_errmsg() API.
**
** This function may only be called once on an sqlite3_recover handle.
** If it is called more than once, the second and subsequent calls
** return SQLITE_MISUSE. The error code and error message returned
** by sqlite3_recover_errcode() and sqlite3_recover_errmsg() are not
** updated in this case.
*/
int sqlite3_recover_run(sqlite3_recover*);
/*
** Return a pointer to a buffer containing the English language error
** message stored in the sqlite3_recover handle. If no error message
** is available (including in the case where no error has occurred),
** NULL is returned.
** If this is called on an sqlite3_recover handle before
** sqlite3_recover_run() has been called, or if the call to
** sqlite3_recover_run() returned SQLITE_OK, then this API always returns
** a NULL pointer.
**
** Otherwise, an attempt is made to return a pointer to a buffer containing
** an English language error message related to the error that occurred
** within the sqlite3_recover_run() call. If no error message is available,
** or if an out-of-memory error occurs while attempting to allocate a buffer
** for one, NULL may still be returned.
**
** The buffer remains valid until the sqlite3_recover handle is destroyed
** using sqlite3_recover_finish().
*/
const char *sqlite3_recover_errmsg(sqlite3_recover*);
/*
** Return the recover handle error code. SQLITE_OK is returned if no error
** has occurred.
** If this function is called on an sqlite3_recover handle before
** sqlite3_recover_run() has been called, it always returns SQLITE_OK.
** Otherwise, it returns a copy of the value returned by the first
** sqlite3_recover_run() call made on the handle.
*/
int sqlite3_recover_errcode(sqlite3_recover*);
/*
** Clean up a recovery object created by a call to sqlite3_recover_init().
** This function returns SQLITE_OK if no error occurred, or else a copy
** of the recover handle error code.
** The results of using a recovery object with any API after it has been
** passed to this function are undefined.
**
** If this function is called on an sqlite3_recover handle before
** sqlite3_recover_run() has been called, it always returns SQLITE_OK.
** Otherwise, it returns a copy of the value returned by the first
** sqlite3_recover_run() call made on the handle.
*/
int sqlite3_recover_finish(sqlite3_recover*);

View File

@ -117,7 +117,7 @@ static int testRecoverCmd(
switch( iOp ){
case 0:
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_TESTDB, (void*)Tcl_GetString(objv[3])
789, (void*)Tcl_GetString(objv[3]) /* MAGIC NUMBER! */
);
break;
case 1: