]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/include/private/svn_sqlite.h
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / include / private / svn_sqlite.h
1 /* svn_sqlite.h
2  *
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  *    under the License.
20  * ====================================================================
21  */
22
23
24 #ifndef SVN_SQLITE_H
25 #define SVN_SQLITE_H
26
27 #include <apr_pools.h>
28
29 #include "svn_types.h"
30 #include "svn_checksum.h"
31 #include "svn_error.h"
32
33 #include "private/svn_token.h"  /* for svn_token_map_t  */
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif /* __cplusplus */
38
39
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
42    numbers here. */
43
44 /* Return the value that SQLITE_VERSION had at compile time. */
45 const char *svn_sqlite__compiled_version(void);
46
47 /* Return the value of sqlite3_libversion() at run time. */
48 const char *svn_sqlite__runtime_version(void);
49
50
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;
55
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 */
60 } svn_sqlite__mode_t;
61
62 /* The type used for callback functions. */
63 typedef svn_error_t *(*svn_sqlite__func_t)(svn_sqlite__context_t *sctx,
64                                            int argc,
65                                            svn_sqlite__value_t *values[],
66                                            void *baton);
67
68
69 /* Step the given statement; if it returns SQLITE_DONE, reset the statement.
70    Otherwise, raise an SVN error.  */
71 svn_error_t *
72 svn_sqlite__step_done(svn_sqlite__stmt_t *stmt);
73
74 /* Step the given statement; raise an SVN error (and reset the
75    statement) if it doesn't return SQLITE_ROW. */
76 svn_error_t *
77 svn_sqlite__step_row(svn_sqlite__stmt_t *stmt);
78
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.
82 */
83 svn_error_t *
84 svn_sqlite__step(svn_boolean_t *got_row, svn_sqlite__stmt_t *stmt);
85
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. */
89 svn_error_t *
90 svn_sqlite__insert(apr_int64_t *row_id, svn_sqlite__stmt_t *stmt);
91
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. */
96 svn_error_t *
97 svn_sqlite__update(int *affected_rows, svn_sqlite__stmt_t *stmt);
98
99 /* Return in *VERSION the version of the schema in DB. Use SCRATCH_POOL
100    for temporary allocations.  */
101 svn_error_t *
102 svn_sqlite__read_schema_version(int *version,
103                                 svn_sqlite__db_t *db,
104                                 apr_pool_t *scratch_pool);
105
106
107
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.
112
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
116    as RESULT_POOL.
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.
119
120    TIMEOUT defines the SQLite busy timeout, values <= 0 cause a Subversion
121    default to be used.
122
123    The statements will be finalized and the SQLite database will be closed
124    when RESULT_POOL is cleaned up. */
125 svn_error_t *
126 svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
127                  svn_sqlite__mode_t mode, const char * const statements[],
128                  int latest_schema, const char * const *upgrade_sql,
129                  apr_int32_t timeout,
130                  apr_pool_t *result_pool, apr_pool_t *scratch_pool);
131
132 /* Explicitly close the connection in DB. */
133 svn_error_t *
134 svn_sqlite__close(svn_sqlite__db_t *db);
135
136 /* Add a custom function to be used with this database connection.  The data
137    in BATON should live at least as long as the connection in DB.
138
139    Pass TRUE if the result of the function is constant within a statement with
140    a specific set of argument values and FALSE if not (or when in doubt). When
141    TRUE newer Sqlite versions use this knowledge for query optimizations. */
142 svn_error_t *
143 svn_sqlite__create_scalar_function(svn_sqlite__db_t *db,
144                                    const char *func_name,
145                                    int argc,
146                                    svn_boolean_t deterministic,
147                                    svn_sqlite__func_t func,
148                                    void *baton);
149
150 /* Execute the (multiple) statements in the STATEMENTS[STMT_IDX] string.  */
151 svn_error_t *
152 svn_sqlite__exec_statements(svn_sqlite__db_t *db, int stmt_idx);
153
154 /* Return the statement in *STMT which has been prepared from the
155    STATEMENTS[STMT_IDX] string, where STATEMENTS is the array that was
156    passed to svn_sqlite__open().  This statement is allocated in the same
157    pool as the DB, and will be cleaned up when DB is closed. */
158 svn_error_t *
159 svn_sqlite__get_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
160                           int stmt_idx);
161
162
163 /* ---------------------------------------------------------------------
164
165    BINDING VALUES
166
167 */
168
169 /* Bind values to SQL parameters in STMT, according to FMT.  FMT may contain:
170
171    Spec  Argument type             Item type
172    ----  -----------------         ---------
173    n     <none, absent>            Column assignment skip
174    d     int                       Number
175    L     apr_int64_t               Number
176    i     apr_int64_t               Number (deprecated format spec)
177    s     const char *              String
178    b     const void *              Blob data
179          apr_size_t                Blob length
180    r     svn_revnum_t              Revision number
181    t     const svn_token_map_t *   Token mapping table
182          int                       Token value
183
184   Each character in FMT maps to one SQL parameter, and one or two function
185   parameters, in the order they appear.
186 */
187 svn_error_t *
188 svn_sqlite__bindf(svn_sqlite__stmt_t *stmt, const char *fmt, ...);
189
190 /* Error-handling wrapper around sqlite3_bind_int. */
191 svn_error_t *
192 svn_sqlite__bind_int(svn_sqlite__stmt_t *stmt, int slot, int val);
193
194 /* Error-handling wrapper around sqlite3_bind_int64. */
195 svn_error_t *
196 svn_sqlite__bind_int64(svn_sqlite__stmt_t *stmt, int slot,
197                        apr_int64_t val);
198
199 /* Error-handling wrapper around sqlite3_bind_text. VAL cannot contain
200    zero bytes; we always pass SQLITE_TRANSIENT. */
201 svn_error_t *
202 svn_sqlite__bind_text(svn_sqlite__stmt_t *stmt, int slot,
203                       const char *val);
204
205 /* Error-handling wrapper around sqlite3_bind_blob. */
206 svn_error_t *
207 svn_sqlite__bind_blob(svn_sqlite__stmt_t *stmt,
208                       int slot,
209                       const void *val,
210                       apr_size_t len);
211
212 /* Look up VALUE in MAP, and bind the resulting token word at SLOT.  */
213 svn_error_t *
214 svn_sqlite__bind_token(svn_sqlite__stmt_t *stmt,
215                        int slot,
216                        const svn_token_map_t *map,
217                        int value);
218
219 /* Bind the value to SLOT, unless SVN_IS_VALID_REVNUM(value) is false,
220    in which case it binds NULL.  */
221 svn_error_t *
222 svn_sqlite__bind_revnum(svn_sqlite__stmt_t *stmt, int slot,
223                         svn_revnum_t value);
224
225 /* Bind a set of properties to the given slot. If PROPS is NULL, then no
226    binding will occur. PROPS will be stored as a serialized skel. */
227 svn_error_t *
228 svn_sqlite__bind_properties(svn_sqlite__stmt_t *stmt,
229                             int slot,
230                             const apr_hash_t *props,
231                             apr_pool_t *scratch_pool);
232
233 /* Bind a set of inherited properties to the given slot. If INHERITED_PROPS
234    is NULL, then no binding will occur. INHERITED_PROPS will be stored as a
235    serialized skel. */
236 svn_error_t *
237 svn_sqlite__bind_iprops(svn_sqlite__stmt_t *stmt,
238                         int slot,
239                         const apr_array_header_t *inherited_props,
240                         apr_pool_t *scratch_pool);
241
242 /* Bind a checksum's value to the given slot. If CHECKSUM is NULL, then no
243    binding will occur. */
244 svn_error_t *
245 svn_sqlite__bind_checksum(svn_sqlite__stmt_t *stmt,
246                           int slot,
247                           const svn_checksum_t *checksum,
248                           apr_pool_t *scratch_pool);
249
250
251 /* ---------------------------------------------------------------------
252
253    FETCHING VALUES
254
255 */
256
257 /* Wrapper around sqlite3_column_blob and sqlite3_column_bytes. The return
258    value will be NULL if the column is null.
259
260    If RESULT_POOL is not NULL, allocate the return value (if any) in it.
261    If RESULT_POOL is NULL, the return value will be valid until an
262    invocation of svn_sqlite__column_* performs a data type conversion (as
263    described in the SQLite documentation) or the statement is stepped or
264    reset or finalized. */
265 const void *
266 svn_sqlite__column_blob(svn_sqlite__stmt_t *stmt, int column,
267                         apr_size_t *len, apr_pool_t *result_pool);
268
269 /* Wrapper around sqlite3_column_text. If the column is null, then the
270    return value will be NULL.
271
272    If RESULT_POOL is not NULL, allocate the return value (if any) in it.
273    If RESULT_POOL is NULL, the return value will be valid until an
274    invocation of svn_sqlite__column_* performs a data type conversion (as
275    described in the SQLite documentation) or the statement is stepped or
276    reset or finalized. */
277 const char *
278 svn_sqlite__column_text(svn_sqlite__stmt_t *stmt, int column,
279                         apr_pool_t *result_pool);
280
281 /* Wrapper around sqlite3_column_int64. If the column is null, then the
282    return value will be SVN_INVALID_REVNUM. */
283 svn_revnum_t
284 svn_sqlite__column_revnum(svn_sqlite__stmt_t *stmt, int column);
285
286 /* Wrapper around sqlite3_column_int64. If the column is null, then the
287    return value will be FALSE. */
288 svn_boolean_t
289 svn_sqlite__column_boolean(svn_sqlite__stmt_t *stmt, int column);
290
291 /* Wrapper around sqlite3_column_int. If the column is null, then the
292    return value will be 0. */
293 int
294 svn_sqlite__column_int(svn_sqlite__stmt_t *stmt, int column);
295
296 /* Wrapper around sqlite3_column_int64. If the column is null, then the
297    return value will be 0. */
298 apr_int64_t
299 svn_sqlite__column_int64(svn_sqlite__stmt_t *stmt, int column);
300
301 /* Fetch the word at COLUMN, look it up in the MAP, and return its value.
302    MALFUNCTION is thrown if the column is null or contains an unknown word.  */
303 int
304 svn_sqlite__column_token(svn_sqlite__stmt_t *stmt,
305                          int column,
306                          const svn_token_map_t *map);
307
308 /* Fetch the word at COLUMN, look it up in the MAP, and return its value.
309    Returns NULL_VAL if the column is null. MALFUNCTION is thrown if the
310    column contains an unknown word.  */
311 int
312 svn_sqlite__column_token_null(svn_sqlite__stmt_t *stmt,
313                               int column,
314                               const svn_token_map_t *map,
315                               int null_val);
316
317 /* Return the column as a hash of const char * => const svn_string_t *.
318    If the column is null, then set *PROPS to NULL. The
319    results will be allocated in RESULT_POOL, and any temporary allocations
320    will be made in SCRATCH_POOL. */
321 svn_error_t *
322 svn_sqlite__column_properties(apr_hash_t **props,
323                               svn_sqlite__stmt_t *stmt,
324                               int column,
325                               apr_pool_t *result_pool,
326                               apr_pool_t *scratch_pool);
327
328 /* Return the column as an array of depth-first ordered array of
329    svn_prop_inherited_item_t * structures.  If the column is null, then
330    set *IPROPS to NULL. The results will be allocated in RESULT_POOL,
331    and any temporary allocations will be made in SCRATCH_POOL. */
332 svn_error_t *
333 svn_sqlite__column_iprops(apr_array_header_t **iprops,
334                           svn_sqlite__stmt_t *stmt,
335                           int column,
336                           apr_pool_t *result_pool,
337                           apr_pool_t *scratch_pool);
338
339 /* Return the column as a checksum. If the column is null, then NULL will
340    be stored into *CHECKSUM. The result will be allocated in RESULT_POOL. */
341 svn_error_t *
342 svn_sqlite__column_checksum(const svn_checksum_t **checksum,
343                             svn_sqlite__stmt_t *stmt,
344                             int column,
345                             apr_pool_t *result_pool);
346
347 /* Return TRUE if the result of selecting the column is null,
348    FALSE otherwise */
349 svn_boolean_t
350 svn_sqlite__column_is_null(svn_sqlite__stmt_t *stmt, int column);
351
352 /* Return the number of bytes the column uses in a text or blob representation.
353    0 for NULL columns. */
354 int
355 svn_sqlite__column_bytes(svn_sqlite__stmt_t *stmt, int column);
356
357 /* When Subversion is compiled in maintainer mode: enables the sqlite error
358    logging to SVN_DBG_OUTPUT. */
359 void
360 svn_sqlite__dbg_enable_errorlog(void);
361
362
363 /* --------------------------------------------------------------------- */
364
365 #define SVN_SQLITE__INTEGER  1
366 #define SVN_SQLITE__FLOAT    2
367 #define SVN_SQLITE__TEXT     3
368 #define SVN_SQLITE__BLOB     4
369 #define SVN_SQLITE__NULL     5
370
371 /* */
372 int
373 svn_sqlite__value_type(svn_sqlite__value_t *val);
374
375 /* */
376 const char *
377 svn_sqlite__value_text(svn_sqlite__value_t *val);
378
379
380 /* --------------------------------------------------------------------- */
381
382 /* */
383 void
384 svn_sqlite__result_null(svn_sqlite__context_t *sctx);
385
386 void
387 svn_sqlite__result_int64(svn_sqlite__context_t *sctx, apr_int64_t val);
388
389 void
390 svn_sqlite__result_error(svn_sqlite__context_t *sctx, const char *msg, int num);
391
392
393 /* --------------------------------------------------------------------- */
394
395
396 /* Error-handling wrapper around sqlite3_finalize. */
397 svn_error_t *
398 svn_sqlite__finalize(svn_sqlite__stmt_t *stmt);
399
400 /* Reset STMT by calling sqlite3_reset(), and also clear any bindings to it.
401
402    Note: svn_sqlite__get_statement() calls this function automatically if
403    the requested statement has been used and has not yet been reset. */
404 svn_error_t *
405 svn_sqlite__reset(svn_sqlite__stmt_t *stmt);
406
407
408 /* Begin a transaction in DB. */
409 svn_error_t *
410 svn_sqlite__begin_transaction(svn_sqlite__db_t *db);
411
412 /* Like svn_sqlite__begin_transaction(), but takes out a 'RESERVED' lock
413    immediately, instead of using the default deferred locking scheme. */
414 svn_error_t *
415 svn_sqlite__begin_immediate_transaction(svn_sqlite__db_t *db);
416
417 /* Begin a savepoint in DB. */
418 svn_error_t *
419 svn_sqlite__begin_savepoint(svn_sqlite__db_t *db);
420
421 /* Commit the current transaction in DB if ERR is SVN_NO_ERROR, otherwise
422  * roll back the transaction.  Return a composition of ERR and any error
423  * that may occur during the commit or roll-back. */
424 svn_error_t *
425 svn_sqlite__finish_transaction(svn_sqlite__db_t *db,
426                                svn_error_t *err);
427
428 /* Release the current savepoint in DB if EXPR is SVN_NO_ERROR, otherwise
429  * roll back to the savepoint and then release it.  Return a composition of
430  * ERR and any error that may occur during the release or roll-back. */
431 svn_error_t *
432 svn_sqlite__finish_savepoint(svn_sqlite__db_t *db,
433                              svn_error_t *err);
434
435 /* Evaluate the expression EXPR within a transaction.
436  *
437  * Begin a transaction in DB; evaluate the expression EXPR, which would
438  * typically be a function call that does some work in DB; finally commit
439  * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
440  * the transaction.
441  */
442 #define SVN_SQLITE__WITH_TXN(expr, db)                                        \
443   do {                                                                        \
444     svn_sqlite__db_t *svn_sqlite__db = (db);                                  \
445     svn_error_t *svn_sqlite__err;                                             \
446                                                                               \
447     SVN_ERR(svn_sqlite__begin_transaction(svn_sqlite__db));                   \
448     svn_sqlite__err = (expr);                                                 \
449     SVN_ERR(svn_sqlite__finish_transaction(svn_sqlite__db, svn_sqlite__err)); \
450   } while (0)
451
452 /* Callback function to for use with svn_sqlite__with_transaction(). */
453 typedef svn_error_t *(*svn_sqlite__transaction_callback_t)(
454   void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool);
455
456 /* Helper function to handle SQLite transactions.  All the work done inside
457    CB_FUNC will be wrapped in an SQLite transaction, which will be committed
458    if CB_FUNC does not return an error.  If any error is returned from CB_FUNC,
459    the transaction will be rolled back.  DB and CB_BATON will be passed to
460    CB_FUNC. SCRATCH_POOL will be passed to the callback (NULL is valid). */
461 svn_error_t *
462 svn_sqlite__with_transaction(svn_sqlite__db_t *db,
463                              svn_sqlite__transaction_callback_t cb_func,
464                              void *cb_baton, apr_pool_t *scratch_pool);
465
466 /* Like SVN_SQLITE__WITH_TXN(), but takes out a 'RESERVED' lock
467    immediately, instead of using the default deferred locking scheme. */
468 #define SVN_SQLITE__WITH_IMMEDIATE_TXN(expr, db)                              \
469   do {                                                                        \
470     svn_sqlite__db_t *svn_sqlite__db = (db);                                  \
471     svn_error_t *svn_sqlite__err;                                             \
472                                                                               \
473     SVN_ERR(svn_sqlite__begin_immediate_transaction(svn_sqlite__db));         \
474     svn_sqlite__err = (expr);                                                 \
475     SVN_ERR(svn_sqlite__finish_transaction(svn_sqlite__db, svn_sqlite__err)); \
476   } while (0)
477
478 /* Like svn_sqlite__with_transaction(), but takes out a 'RESERVED' lock
479    immediately, instead of using the default deferred locking scheme. */
480 svn_error_t *
481 svn_sqlite__with_immediate_transaction(svn_sqlite__db_t *db,
482                                        svn_sqlite__transaction_callback_t cb_func,
483                                        void *cb_baton,
484                                        apr_pool_t *scratch_pool);
485
486 /* Evaluate the expression EXPR within a 'savepoint'.  Savepoints can be
487  * nested.
488  *
489  * Begin a savepoint in DB; evaluate the expression EXPR, which would
490  * typically be a function call that does some work in DB; finally release
491  * the savepoint if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
492  * to the savepoint and then release it.
493  */
494 #define SVN_SQLITE__WITH_LOCK(expr, db)                                       \
495   do {                                                                        \
496     svn_sqlite__db_t *svn_sqlite__db = (db);                                  \
497     svn_error_t *svn_sqlite__err;                                             \
498                                                                               \
499     SVN_ERR(svn_sqlite__begin_savepoint(svn_sqlite__db));                     \
500     svn_sqlite__err = (expr);                                                 \
501     SVN_ERR(svn_sqlite__finish_savepoint(svn_sqlite__db, svn_sqlite__err));   \
502   } while (0)
503
504 /* Evaluate the expression EXPR1..EXPR4 within a 'savepoint'.  Savepoints can
505  * be nested.
506  *
507  * Begin a savepoint in DB; evaluate the expression EXPR1, which would
508  * typically be a function call that does some work in DB; if no error occurred,
509  * run EXPR2; if no error occurred EXPR3; ... and finally release
510  * the savepoint if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
511  * to the savepoint and then release it.
512  */
513 #define SVN_SQLITE__WITH_LOCK4(expr1, expr2, expr3, expr4, db)                \
514   do {                                                                        \
515     svn_sqlite__db_t *svn_sqlite__db = (db);                                  \
516     svn_error_t *svn_sqlite__err;                                             \
517                                                                               \
518     SVN_ERR(svn_sqlite__begin_savepoint(svn_sqlite__db));                     \
519     svn_sqlite__err = (expr1);                                                \
520     if (!svn_sqlite__err)                                                     \
521       svn_sqlite__err = (expr2);                                              \
522     if (!svn_sqlite__err)                                                     \
523       svn_sqlite__err = (expr3);                                              \
524     if (!svn_sqlite__err)                                                     \
525       svn_sqlite__err = (expr4);                                              \
526     SVN_ERR(svn_sqlite__finish_savepoint(svn_sqlite__db, svn_sqlite__err));   \
527   } while (0)
528
529
530 /* Helper function to handle several SQLite operations inside a shared lock.
531    This callback is similar to svn_sqlite__with_transaction(), but can be
532    nested (even with a transaction).
533
534    Using this function as a wrapper around a group of operations can give a
535    *huge* performance boost as the shared-read lock will be shared over
536    multiple statements, instead of being reobtained every time, which may
537    require disk and/or network io, depending on SQLite's locking strategy.
538
539    SCRATCH_POOL will be passed to the callback (NULL is valid).
540
541    ### Since we now require SQLite >= 3.6.18, this function has the effect of
542        always behaving like a deferred transaction.  Can it be combined with
543        svn_sqlite__with_transaction()?
544  */
545 svn_error_t *
546 svn_sqlite__with_lock(svn_sqlite__db_t *db,
547                       svn_sqlite__transaction_callback_t cb_func,
548                       void *cb_baton,
549                       apr_pool_t *scratch_pool);
550
551
552 /* Hotcopy an SQLite database from SRC_PATH to DST_PATH. */
553 svn_error_t *
554 svn_sqlite__hotcopy(const char *src_path,
555                     const char *dst_path,
556                     apr_pool_t *scratch_pool);
557
558 #ifdef __cplusplus
559 }
560 #endif /* __cplusplus */
561
562 #endif /* SVN_SQLITE_H */