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