3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
20 * ====================================================================
27 #include <apr_pools.h>
29 #include "svn_types.h"
30 #include "svn_checksum.h"
31 #include "svn_error.h"
33 #include "private/svn_token.h" /* for svn_token_map_t */
37 #endif /* __cplusplus */
40 /* Because the SQLite code can be inlined into libsvn_subre/sqlite.c,
41 we define accessors to its compile-time and run-time version
44 /* Return the value that SQLITE_VERSION had at compile time. */
45 const char *svn_sqlite__compiled_version(void);
47 /* Return the value of sqlite3_libversion() at run time. */
48 const char *svn_sqlite__runtime_version(void);
51 typedef struct svn_sqlite__db_t svn_sqlite__db_t;
52 typedef struct svn_sqlite__stmt_t svn_sqlite__stmt_t;
53 typedef struct svn_sqlite__context_t svn_sqlite__context_t;
54 typedef struct svn_sqlite__value_t svn_sqlite__value_t;
56 typedef enum svn_sqlite__mode_e {
57 svn_sqlite__mode_readonly, /* open the database read-only */
58 svn_sqlite__mode_readwrite, /* open the database read-write */
59 svn_sqlite__mode_rwcreate /* open/create the database read-write */
62 /* The type used for callback functions. */
63 typedef svn_error_t *(*svn_sqlite__func_t)(svn_sqlite__context_t *sctx,
65 svn_sqlite__value_t *values[],
66 apr_pool_t *scatch_pool);
69 /* Step the given statement; if it returns SQLITE_DONE, reset the statement.
70 Otherwise, raise an SVN error. */
72 svn_sqlite__step_done(svn_sqlite__stmt_t *stmt);
74 /* Step the given statement; raise an SVN error (and reset the
75 statement) if it doesn't return SQLITE_ROW. */
77 svn_sqlite__step_row(svn_sqlite__stmt_t *stmt);
79 /* Step the given statement; raise an SVN error (and reset the
80 statement) if it doesn't return SQLITE_DONE or SQLITE_ROW. Set
81 *GOT_ROW to true iff it got SQLITE_ROW.
84 svn_sqlite__step(svn_boolean_t *got_row, svn_sqlite__stmt_t *stmt);
86 /* Perform an insert as given by the prepared and bound STMT, and set
87 *ROW_ID to the id of the inserted row if ROW_ID is non-NULL.
88 STMT will be reset prior to returning. */
90 svn_sqlite__insert(apr_int64_t *row_id, svn_sqlite__stmt_t *stmt);
92 /* Perform an update/delete and then return the number of affected rows.
93 If AFFECTED_ROWS is not NULL, then set *AFFECTED_ROWS to the
94 number of rows changed.
95 STMT will be reset prior to returning. */
97 svn_sqlite__update(int *affected_rows, svn_sqlite__stmt_t *stmt);
99 /* Return in *VERSION the version of the schema in DB. Use SCRATCH_POOL
100 for temporary allocations. */
102 svn_sqlite__read_schema_version(int *version,
103 svn_sqlite__db_t *db,
104 apr_pool_t *scratch_pool);
108 /* Open a connection in *DB to the database at PATH. Validate the schema,
109 creating/upgrading to LATEST_SCHEMA if needed using the instructions
110 in UPGRADE_SQL. The resulting DB is allocated in RESULT_POOL, and any
111 temporary allocations are made in SCRATCH_POOL.
113 STATEMENTS is an array of strings which may eventually be executed, the
114 last element of which should be NULL. These strings and the array itself
115 are not duplicated internally, and should have a lifetime at least as long
117 STATEMENTS itself may be NULL, in which case it has no impact.
118 See svn_sqlite__get_statement() for how these strings are used.
120 The statements will be finalized and the SQLite database will be closed
121 when RESULT_POOL is cleaned up. */
123 svn_sqlite__open(svn_sqlite__db_t **db, const char *repos_path,
124 svn_sqlite__mode_t mode, const char * const statements[],
125 int latest_schema, const char * const *upgrade_sql,
126 apr_pool_t *result_pool, apr_pool_t *scratch_pool);
128 /* Explicitly close the connection in DB. */
130 svn_sqlite__close(svn_sqlite__db_t *db);
132 /* Add a custom function to be used with this database connection. The data
133 in BATON should live at least as long as the connection in DB. */
135 svn_sqlite__create_scalar_function(svn_sqlite__db_t *db,
136 const char *func_name,
138 svn_sqlite__func_t func,
141 /* Execute the (multiple) statements in the STATEMENTS[STMT_IDX] string. */
143 svn_sqlite__exec_statements(svn_sqlite__db_t *db, int stmt_idx);
145 /* Return the statement in *STMT which has been prepared from the
146 STATEMENTS[STMT_IDX] string, where STATEMENTS is the array that was
147 passed to svn_sqlite__open(). This statement is allocated in the same
148 pool as the DB, and will be cleaned up when DB is closed. */
150 svn_sqlite__get_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
154 /* ---------------------------------------------------------------------
160 /* Bind values to SQL parameters in STMT, according to FMT. FMT may contain:
162 Spec Argument type Item type
163 ---- ----------------- ---------
164 n <none, absent> Column assignment skip
167 i apr_int64_t Number (deprecated format spec)
168 s const char * String
169 b const void * Blob data
170 apr_size_t Blob length
171 r svn_revnum_t Revision number
172 t const svn_token_map_t * Token mapping table
175 Each character in FMT maps to one SQL parameter, and one or two function
176 parameters, in the order they appear.
179 svn_sqlite__bindf(svn_sqlite__stmt_t *stmt, const char *fmt, ...);
181 /* Error-handling wrapper around sqlite3_bind_int. */
183 svn_sqlite__bind_int(svn_sqlite__stmt_t *stmt, int slot, int val);
185 /* Error-handling wrapper around sqlite3_bind_int64. */
187 svn_sqlite__bind_int64(svn_sqlite__stmt_t *stmt, int slot,
190 /* Error-handling wrapper around sqlite3_bind_text. VAL cannot contain
191 zero bytes; we always pass SQLITE_TRANSIENT. */
193 svn_sqlite__bind_text(svn_sqlite__stmt_t *stmt, int slot,
196 /* Error-handling wrapper around sqlite3_bind_blob. */
198 svn_sqlite__bind_blob(svn_sqlite__stmt_t *stmt,
203 /* Look up VALUE in MAP, and bind the resulting token word at SLOT. */
205 svn_sqlite__bind_token(svn_sqlite__stmt_t *stmt,
207 const svn_token_map_t *map,
210 /* Bind the value to SLOT, unless SVN_IS_VALID_REVNUM(value) is false,
211 in which case it binds NULL. */
213 svn_sqlite__bind_revnum(svn_sqlite__stmt_t *stmt, int slot,
216 /* Bind a set of properties to the given slot. If PROPS is NULL, then no
217 binding will occur. PROPS will be stored as a serialized skel. */
219 svn_sqlite__bind_properties(svn_sqlite__stmt_t *stmt,
221 const apr_hash_t *props,
222 apr_pool_t *scratch_pool);
224 /* Bind a set of inherited properties to the given slot. If INHERITED_PROPS
225 is NULL, then no binding will occur. INHERITED_PROPS will be stored as a
228 svn_sqlite__bind_iprops(svn_sqlite__stmt_t *stmt,
230 const apr_array_header_t *inherited_props,
231 apr_pool_t *scratch_pool);
233 /* Bind a checksum's value to the given slot. If CHECKSUM is NULL, then no
234 binding will occur. */
236 svn_sqlite__bind_checksum(svn_sqlite__stmt_t *stmt,
238 const svn_checksum_t *checksum,
239 apr_pool_t *scratch_pool);
242 /* ---------------------------------------------------------------------
248 /* Wrapper around sqlite3_column_blob and sqlite3_column_bytes. The return
249 value will be NULL if the column is null.
251 If RESULT_POOL is not NULL, allocate the return value (if any) in it.
252 If RESULT_POOL is NULL, the return value will be valid until an
253 invocation of svn_sqlite__column_* performs a data type conversion (as
254 described in the SQLite documentation) or the statement is stepped or
255 reset or finalized. */
257 svn_sqlite__column_blob(svn_sqlite__stmt_t *stmt, int column,
258 apr_size_t *len, apr_pool_t *result_pool);
260 /* Wrapper around sqlite3_column_text. If the column is null, then the
261 return value will be NULL.
263 If RESULT_POOL is not NULL, allocate the return value (if any) in it.
264 If RESULT_POOL is NULL, the return value will be valid until an
265 invocation of svn_sqlite__column_* performs a data type conversion (as
266 described in the SQLite documentation) or the statement is stepped or
267 reset or finalized. */
269 svn_sqlite__column_text(svn_sqlite__stmt_t *stmt, int column,
270 apr_pool_t *result_pool);
272 /* Wrapper around sqlite3_column_int64. If the column is null, then the
273 return value will be SVN_INVALID_REVNUM. */
275 svn_sqlite__column_revnum(svn_sqlite__stmt_t *stmt, int column);
277 /* Wrapper around sqlite3_column_int64. If the column is null, then the
278 return value will be FALSE. */
280 svn_sqlite__column_boolean(svn_sqlite__stmt_t *stmt, int column);
282 /* Wrapper around sqlite3_column_int. If the column is null, then the
283 return value will be 0. */
285 svn_sqlite__column_int(svn_sqlite__stmt_t *stmt, int column);
287 /* Wrapper around sqlite3_column_int64. If the column is null, then the
288 return value will be 0. */
290 svn_sqlite__column_int64(svn_sqlite__stmt_t *stmt, int column);
292 /* Fetch the word at COLUMN, look it up in the MAP, and return its value.
293 MALFUNCTION is thrown if the column is null or contains an unknown word. */
295 svn_sqlite__column_token(svn_sqlite__stmt_t *stmt,
297 const svn_token_map_t *map);
299 /* Fetch the word at COLUMN, look it up in the MAP, and return its value.
300 Returns NULL_VAL if the column is null. MALFUNCTION is thrown if the
301 column contains an unknown word. */
303 svn_sqlite__column_token_null(svn_sqlite__stmt_t *stmt,
305 const svn_token_map_t *map,
308 /* Return the column as a hash of const char * => const svn_string_t *.
309 If the column is null, then set *PROPS to NULL. The
310 results will be allocated in RESULT_POOL, and any temporary allocations
311 will be made in SCRATCH_POOL. */
313 svn_sqlite__column_properties(apr_hash_t **props,
314 svn_sqlite__stmt_t *stmt,
316 apr_pool_t *result_pool,
317 apr_pool_t *scratch_pool);
319 /* Return the column as an array of depth-first ordered array of
320 svn_prop_inherited_item_t * structures. If the column is null, then
321 set *IPROPS to NULL. The results will be allocated in RESULT_POOL,
322 and any temporary allocations will be made in SCRATCH_POOL. */
324 svn_sqlite__column_iprops(apr_array_header_t **iprops,
325 svn_sqlite__stmt_t *stmt,
327 apr_pool_t *result_pool,
328 apr_pool_t *scratch_pool);
330 /* Return the column as a checksum. If the column is null, then NULL will
331 be stored into *CHECKSUM. The result will be allocated in RESULT_POOL. */
333 svn_sqlite__column_checksum(const svn_checksum_t **checksum,
334 svn_sqlite__stmt_t *stmt,
336 apr_pool_t *result_pool);
338 /* Return TRUE if the result of selecting the column is null,
341 svn_sqlite__column_is_null(svn_sqlite__stmt_t *stmt, int column);
343 /* Return the number of bytes the column uses in a text or blob representation.
344 0 for NULL columns. */
346 svn_sqlite__column_bytes(svn_sqlite__stmt_t *stmt, int column);
349 /* --------------------------------------------------------------------- */
351 #define SVN_SQLITE__INTEGER 1
352 #define SVN_SQLITE__FLOAT 2
353 #define SVN_SQLITE__TEXT 3
354 #define SVN_SQLITE__BLOB 4
355 #define SVN_SQLITE__NULL 5
359 svn_sqlite__value_type(svn_sqlite__value_t *val);
363 svn_sqlite__value_text(svn_sqlite__value_t *val);
366 /* --------------------------------------------------------------------- */
370 svn_sqlite__result_null(svn_sqlite__context_t *sctx);
373 svn_sqlite__result_int64(svn_sqlite__context_t *sctx, apr_int64_t val);
376 /* --------------------------------------------------------------------- */
379 /* Error-handling wrapper around sqlite3_finalize. */
381 svn_sqlite__finalize(svn_sqlite__stmt_t *stmt);
383 /* Reset STMT by calling sqlite3_reset(), and also clear any bindings to it.
385 Note: svn_sqlite__get_statement() calls this function automatically if
386 the requested statement has been used and has not yet been reset. */
388 svn_sqlite__reset(svn_sqlite__stmt_t *stmt);
391 /* Begin a transaction in DB. */
393 svn_sqlite__begin_transaction(svn_sqlite__db_t *db);
395 /* Like svn_sqlite__begin_transaction(), but takes out a 'RESERVED' lock
396 immediately, instead of using the default deferred locking scheme. */
398 svn_sqlite__begin_immediate_transaction(svn_sqlite__db_t *db);
400 /* Begin a savepoint in DB. */
402 svn_sqlite__begin_savepoint(svn_sqlite__db_t *db);
404 /* Commit the current transaction in DB if ERR is SVN_NO_ERROR, otherwise
405 * roll back the transaction. Return a composition of ERR and any error
406 * that may occur during the commit or roll-back. */
408 svn_sqlite__finish_transaction(svn_sqlite__db_t *db,
411 /* Release the current savepoint in DB if EXPR is SVN_NO_ERROR, otherwise
412 * roll back to the savepoint and then release it. Return a composition of
413 * ERR and any error that may occur during the release or roll-back. */
415 svn_sqlite__finish_savepoint(svn_sqlite__db_t *db,
418 /* Evaluate the expression EXPR within a transaction.
420 * Begin a transaction in DB; evaluate the expression EXPR, which would
421 * typically be a function call that does some work in DB; finally commit
422 * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
425 #define SVN_SQLITE__WITH_TXN(expr, db) \
427 svn_sqlite__db_t *svn_sqlite__db = (db); \
428 svn_error_t *svn_sqlite__err; \
430 SVN_ERR(svn_sqlite__begin_transaction(svn_sqlite__db)); \
431 svn_sqlite__err = (expr); \
432 SVN_ERR(svn_sqlite__finish_transaction(svn_sqlite__db, svn_sqlite__err)); \
435 /* Callback function to for use with svn_sqlite__with_transaction(). */
436 typedef svn_error_t *(*svn_sqlite__transaction_callback_t)(
437 void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool);
439 /* Helper function to handle SQLite transactions. All the work done inside
440 CB_FUNC will be wrapped in an SQLite transaction, which will be committed
441 if CB_FUNC does not return an error. If any error is returned from CB_FUNC,
442 the transaction will be rolled back. DB and CB_BATON will be passed to
443 CB_FUNC. SCRATCH_POOL will be passed to the callback (NULL is valid). */
445 svn_sqlite__with_transaction(svn_sqlite__db_t *db,
446 svn_sqlite__transaction_callback_t cb_func,
447 void *cb_baton, apr_pool_t *scratch_pool);
449 /* Like SVN_SQLITE__WITH_TXN(), but takes out a 'RESERVED' lock
450 immediately, instead of using the default deferred locking scheme. */
451 #define SVN_SQLITE__WITH_IMMEDIATE_TXN(expr, db) \
453 svn_sqlite__db_t *svn_sqlite__db = (db); \
454 svn_error_t *svn_sqlite__err; \
456 SVN_ERR(svn_sqlite__begin_immediate_transaction(svn_sqlite__db)); \
457 svn_sqlite__err = (expr); \
458 SVN_ERR(svn_sqlite__finish_transaction(svn_sqlite__db, svn_sqlite__err)); \
461 /* Like svn_sqlite__with_transaction(), but takes out a 'RESERVED' lock
462 immediately, instead of using the default deferred locking scheme. */
464 svn_sqlite__with_immediate_transaction(svn_sqlite__db_t *db,
465 svn_sqlite__transaction_callback_t cb_func,
467 apr_pool_t *scratch_pool);
469 /* Evaluate the expression EXPR within a 'savepoint'. Savepoints can be
472 * Begin a savepoint in DB; evaluate the expression EXPR, which would
473 * typically be a function call that does some work in DB; finally release
474 * the savepoint if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
475 * to the savepoint and then release it.
477 #define SVN_SQLITE__WITH_LOCK(expr, db) \
479 svn_sqlite__db_t *svn_sqlite__db = (db); \
480 svn_error_t *svn_sqlite__err; \
482 SVN_ERR(svn_sqlite__begin_savepoint(svn_sqlite__db)); \
483 svn_sqlite__err = (expr); \
484 SVN_ERR(svn_sqlite__finish_savepoint(svn_sqlite__db, svn_sqlite__err)); \
487 /* Helper function to handle several SQLite operations inside a shared lock.
488 This callback is similar to svn_sqlite__with_transaction(), but can be
489 nested (even with a transaction).
491 Using this function as a wrapper around a group of operations can give a
492 *huge* performance boost as the shared-read lock will be shared over
493 multiple statements, instead of being reobtained every time, which may
494 require disk and/or network io, depending on SQLite's locking strategy.
496 SCRATCH_POOL will be passed to the callback (NULL is valid).
498 ### Since we now require SQLite >= 3.6.18, this function has the effect of
499 always behaving like a defered transaction. Can it be combined with
500 svn_sqlite__with_transaction()?
503 svn_sqlite__with_lock(svn_sqlite__db_t *db,
504 svn_sqlite__transaction_callback_t cb_func,
506 apr_pool_t *scratch_pool);
509 /* Hotcopy an SQLite database from SRC_PATH to DST_PATH. */
511 svn_sqlite__hotcopy(const char *src_path,
512 const char *dst_path,
513 apr_pool_t *scratch_pool);
517 #endif /* __cplusplus */
519 #endif /* SVN_SQLITE_H */