| 1 | /* |
| 2 | ** 2022-08-27 |
| 3 | ** |
| 4 | ** The author disclaims copyright to this source code. In place of |
| 5 | ** a legal notice, here is a blessing: |
| 6 | ** |
| 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. |
| 10 | ** |
| 11 | ************************************************************************* |
| 12 | ** |
| 13 | ** This file contains the public interface to the "recover" extension - |
| 14 | ** an SQLite extension designed to recover data from corrupted database |
| 15 | ** files. |
| 16 | */ |
| 17 | |
| 18 | /* |
| 19 | ** OVERVIEW: |
| 20 | ** |
| 21 | ** To use the API to recover data from a corrupted database, an |
| 22 | ** application: |
| 23 | ** |
| 24 | ** 1) Creates an sqlite3_recover handle by calling either |
| 25 | ** sqlite3_recover_init() or sqlite3_recover_init_sql(). |
| 26 | ** |
| 27 | ** 2) Configures the new handle using one or more calls to |
| 28 | ** sqlite3_recover_config(). |
| 29 | ** |
| 30 | ** 3) Executes the recovery by repeatedly calling sqlite3_recover_step() on |
| 31 | ** the handle until it returns something other than SQLITE_OK. If it |
| 32 | ** returns SQLITE_DONE, then the recovery operation completed without |
| 33 | ** error. If it returns some other non-SQLITE_OK value, then an error |
| 34 | ** has occurred. |
| 35 | ** |
| 36 | ** 4) Retrieves any error code and English language error message using the |
| 37 | ** sqlite3_recover_errcode() and sqlite3_recover_errmsg() APIs, |
| 38 | ** respectively. |
| 39 | ** |
| 40 | ** 5) Destroys the sqlite3_recover handle and frees all resources |
| 41 | ** using sqlite3_recover_finish(). |
| 42 | ** |
| 43 | ** The application may abandon the recovery operation at any point |
| 44 | ** before it is finished by passing the sqlite3_recover handle to |
| 45 | ** sqlite3_recover_finish(). This is not an error, but the final state |
| 46 | ** of the output database, or the results of running the partial script |
| 47 | ** delivered to the SQL callback, are undefined. |
| 48 | */ |
| 49 | |
| 50 | #ifndef _SQLITE_RECOVER_H |
| 51 | #define _SQLITE_RECOVER_H |
| 52 | |
| 53 | #include "sqlite3.h" |
| 54 | |
| 55 | #ifdef __cplusplus |
| 56 | extern "C" { |
| 57 | #endif |
| 58 | |
| 59 | /* |
| 60 | ** An instance of the sqlite3_recover object represents a recovery |
| 61 | ** operation in progress. |
| 62 | ** |
| 63 | ** Constructors: |
| 64 | ** |
| 65 | ** sqlite3_recover_init() |
| 66 | ** sqlite3_recover_init_sql() |
| 67 | ** |
| 68 | ** Destructor: |
| 69 | ** |
| 70 | ** sqlite3_recover_finish() |
| 71 | ** |
| 72 | ** Methods: |
| 73 | ** |
| 74 | ** sqlite3_recover_config() |
| 75 | ** sqlite3_recover_errcode() |
| 76 | ** sqlite3_recover_errmsg() |
| 77 | ** sqlite3_recover_run() |
| 78 | ** sqlite3_recover_step() |
| 79 | */ |
| 80 | typedef struct sqlite3_recover sqlite3_recover; |
| 81 | |
| 82 | /* |
| 83 | ** These two APIs attempt to create and return a new sqlite3_recover object. |
| 84 | ** In both cases the first two arguments identify the (possibly |
| 85 | ** corrupt) database to recover data from. The first argument is an open |
| 86 | ** database handle and the second the name of a database attached to that |
| 87 | ** handle (i.e. "main", "temp" or the name of an attached database). |
| 88 | ** |
| 89 | ** If sqlite3_recover_init() is used to create the new sqlite3_recover |
| 90 | ** handle, then data is recovered into a new database, identified by |
| 91 | ** string parameter zUri. zUri may be an absolute or relative file path, |
| 92 | ** or may be an SQLite URI. If the identified database file already exists, |
| 93 | ** it is overwritten. |
| 94 | ** |
| 95 | ** If sqlite3_recover_init_sql() is invoked, then any recovered data will |
| 96 | ** be returned to the user as a series of SQL statements. Executing these |
| 97 | ** SQL statements results in the same database as would have been created |
| 98 | ** had sqlite3_recover_init() been used. For each SQL statement in the |
| 99 | ** output, the callback function passed as the third argument (xSql) is |
| 100 | ** invoked once. The first parameter is a passed a copy of the fourth argument |
| 101 | ** to this function (pCtx) as its first parameter, and a pointer to a |
| 102 | ** nul-terminated buffer containing the SQL statement formated as UTF-8 as |
| 103 | ** the second. If the xSql callback returns any value other than SQLITE_OK, |
| 104 | ** then processing is immediately abandoned and the value returned used as |
| 105 | ** the recover handle error code (see below). |
| 106 | ** |
| 107 | ** If an out-of-memory error occurs, NULL may be returned instead of |
| 108 | ** a valid handle. In all other cases, it is the responsibility of the |
| 109 | ** application to avoid resource leaks by ensuring that |
| 110 | ** sqlite3_recover_finish() is called on all allocated handles. |
| 111 | */ |
| 112 | sqlite3_recover *sqlite3_recover_init( |
| 113 | sqlite3* db, |
| 114 | const char *zDb, |
| 115 | const char *zUri |
| 116 | ); |
| 117 | sqlite3_recover *sqlite3_recover_init_sql( |
| 118 | sqlite3* db, |
| 119 | const char *zDb, |
| 120 | int (*xSql)(void*, const char*), |
| 121 | void *pCtx |
| 122 | ); |
| 123 | |
| 124 | /* |
| 125 | ** Configure an sqlite3_recover object that has just been created using |
| 126 | ** sqlite3_recover_init() or sqlite3_recover_init_sql(). This function |
| 127 | ** may only be called before the first call to sqlite3_recover_step() |
| 128 | ** or sqlite3_recover_run() on the object. |
| 129 | ** |
| 130 | ** The second argument passed to this function must be one of the |
| 131 | ** SQLITE_RECOVER_* symbols defined below. Valid values for the third argument |
| 132 | ** depend on the specific SQLITE_RECOVER_* symbol in use. |
| 133 | ** |
| 134 | ** SQLITE_OK is returned if the configuration operation was successful, |
| 135 | ** or an SQLite error code otherwise. |
| 136 | */ |
| 137 | int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg); |
| 138 | |
| 139 | /* |
| 140 | ** SQLITE_RECOVER_LOST_AND_FOUND: |
| 141 | ** The pArg argument points to a string buffer containing the name |
| 142 | ** of a "lost-and-found" table in the output database, or NULL. If |
| 143 | ** the argument is non-NULL and the database contains seemingly |
| 144 | ** valid pages that cannot be associated with any table in the |
| 145 | ** recovered part of the schema, data is extracted from these |
| 146 | ** pages to add to the lost-and-found table. |
| 147 | ** |
| 148 | ** SQLITE_RECOVER_FREELIST_CORRUPT: |
| 149 | ** The pArg value must actually be a pointer to a value of type |
| 150 | ** int containing value 0 or 1 cast as a (void*). If this option is set |
| 151 | ** (argument is 1) and a lost-and-found table has been configured using |
| 152 | ** SQLITE_RECOVER_LOST_AND_FOUND, then is assumed that the freelist is |
| 153 | ** corrupt and an attempt is made to recover records from pages that |
| 154 | ** appear to be linked into the freelist. Otherwise, pages on the freelist |
| 155 | ** are ignored. Setting this option can recover more data from the |
| 156 | ** database, but often ends up "recovering" deleted records. The default |
| 157 | ** value is 0 (clear). |
| 158 | ** |
| 159 | ** SQLITE_RECOVER_ROWIDS: |
| 160 | ** The pArg value must actually be a pointer to a value of type |
| 161 | ** int containing value 0 or 1 cast as a (void*). If this option is set |
| 162 | ** (argument is 1), then an attempt is made to recover rowid values |
| 163 | ** that are not also INTEGER PRIMARY KEY values. If this option is |
| 164 | ** clear, then new rowids are assigned to all recovered rows. The |
| 165 | ** default value is 1 (set). |
| 166 | ** |
| 167 | ** SQLITE_RECOVER_SLOWINDEXES: |
| 168 | ** The pArg value must actually be a pointer to a value of type |
| 169 | ** int containing value 0 or 1 cast as a (void*). If this option is clear |
| 170 | ** (argument is 0), then when creating an output database, the recover |
| 171 | ** module creates and populates non-UNIQUE indexes right at the end of the |
| 172 | ** recovery operation - after all recoverable data has been inserted |
| 173 | ** into the new database. This is faster overall, but means that the |
| 174 | ** final call to sqlite3_recover_step() for a recovery operation may |
| 175 | ** be need to create a large number of indexes, which may be very slow. |
| 176 | ** |
| 177 | ** Or, if this option is set (argument is 1), then non-UNIQUE indexes |
| 178 | ** are created in the output database before it is populated with |
| 179 | ** recovered data. This is slower overall, but avoids the slow call |
| 180 | ** to sqlite3_recover_step() at the end of the recovery operation. |
| 181 | ** |
| 182 | ** The default option value is 0. |
| 183 | */ |
| 184 | #define SQLITE_RECOVER_LOST_AND_FOUND 1 |
| 185 | #define SQLITE_RECOVER_FREELIST_CORRUPT 2 |
| 186 | #define SQLITE_RECOVER_ROWIDS 3 |
| 187 | #define SQLITE_RECOVER_SLOWINDEXES 4 |
| 188 | |
| 189 | /* |
| 190 | ** Perform a unit of work towards the recovery operation. This function |
| 191 | ** must normally be called multiple times to complete database recovery. |
| 192 | ** |
| 193 | ** If no error occurs but the recovery operation is not completed, this |
| 194 | ** function returns SQLITE_OK. If recovery has been completed successfully |
| 195 | ** then SQLITE_DONE is returned. If an error has occurred, then an SQLite |
| 196 | ** error code (e.g. SQLITE_IOERR or SQLITE_NOMEM) is returned. It is not |
| 197 | ** considered an error if some or all of the data cannot be recovered |
| 198 | ** due to database corruption. |
| 199 | ** |
| 200 | ** Once sqlite3_recover_step() has returned a value other than SQLITE_OK, |
| 201 | ** all further such calls on the same recover handle are no-ops that return |
| 202 | ** the same non-SQLITE_OK value. |
| 203 | */ |
| 204 | int sqlite3_recover_step(sqlite3_recover*); |
| 205 | |
| 206 | /* |
| 207 | ** Run the recovery operation to completion. Return SQLITE_OK if successful, |
| 208 | ** or an SQLite error code otherwise. Calling this function is the same |
| 209 | ** as executing: |
| 210 | ** |
| 211 | ** while( SQLITE_OK==sqlite3_recover_step(p) ); |
| 212 | ** return sqlite3_recover_errcode(p); |
| 213 | */ |
| 214 | int sqlite3_recover_run(sqlite3_recover*); |
| 215 | |
| 216 | /* |
| 217 | ** If an error has been encountered during a prior call to |
| 218 | ** sqlite3_recover_step(), then this function attempts to return a |
| 219 | ** pointer to a buffer containing an English language explanation of |
| 220 | ** the error. If no error message is available, or if an out-of memory |
| 221 | ** error occurs while attempting to allocate a buffer in which to format |
| 222 | ** the error message, NULL is returned. |
| 223 | ** |
| 224 | ** The returned buffer remains valid until the sqlite3_recover handle is |
| 225 | ** destroyed using sqlite3_recover_finish(). |
| 226 | */ |
| 227 | const char *sqlite3_recover_errmsg(sqlite3_recover*); |
| 228 | |
| 229 | /* |
| 230 | ** If this function is called on an sqlite3_recover handle after |
| 231 | ** an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK. |
| 232 | */ |
| 233 | int sqlite3_recover_errcode(sqlite3_recover*); |
| 234 | |
| 235 | /* |
| 236 | ** Clean up a recovery object created by a call to sqlite3_recover_init(). |
| 237 | ** The results of using a recovery object with any API after it has been |
| 238 | ** passed to this function are undefined. |
| 239 | ** |
| 240 | ** This function returns the same value as sqlite3_recover_errcode(). |
| 241 | */ |
| 242 | int sqlite3_recover_finish(sqlite3_recover*); |
| 243 | |
| 244 | |
| 245 | #ifdef __cplusplus |
| 246 | } /* end of the 'extern "C"' block */ |
| 247 | #endif |
| 248 | |
| 249 | #endif /* ifndef _SQLITE_RECOVER_H */ |