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 */ 250