]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/subversion/subversion/libsvn_subr/sqlite.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / subversion / subversion / libsvn_subr / sqlite.c
1 /* sqlite.c
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 #include <apr_pools.h>
24
25 #include "svn_types.h"
26 #include "svn_error.h"
27 #include "svn_pools.h"
28 #include "svn_io.h"
29 #include "svn_dirent_uri.h"
30 #include "svn_checksum.h"
31
32 #include "internal_statements.h"
33
34 #include "private/svn_sqlite.h"
35 #include "svn_private_config.h"
36 #include "private/svn_dep_compat.h"
37 #include "private/svn_atomic.h"
38 #include "private/svn_skel.h"
39 #include "private/svn_token.h"
40
41 #ifdef SQLITE3_DEBUG
42 #include "private/svn_debug.h"
43 #endif
44
45 #ifdef SVN_SQLITE_INLINE
46 /* Import the sqlite3 API vtable from sqlite3wrapper.c */
47 #  define SQLITE_OMIT_DEPRECATED
48 #  include <sqlite3ext.h>
49 extern const sqlite3_api_routines *const svn_sqlite3__api_funcs;
50 extern int (*const svn_sqlite3__api_initialize)(void);
51 extern int (*const svn_sqlite3__api_config)(int, ...);
52 #  define sqlite3_api svn_sqlite3__api_funcs
53 #  define sqlite3_initialize svn_sqlite3__api_initialize
54 #  define sqlite3_config svn_sqlite3__api_config
55 #else
56 #  include <sqlite3.h>
57 #endif
58
59 #if !SQLITE_VERSION_AT_LEAST(3,7,12)
60 #error SQLite is too old -- version 3.7.12 is the minimum required version
61 #endif
62
63 const char *
64 svn_sqlite__compiled_version(void)
65 {
66   static const char sqlite_version[] = SQLITE_VERSION;
67   return sqlite_version;
68 }
69
70 const char *
71 svn_sqlite__runtime_version(void)
72 {
73   return sqlite3_libversion();
74 }
75
76
77 INTERNAL_STATEMENTS_SQL_DECLARE_STATEMENTS(internal_statements);
78
79
80 #ifdef SQLITE3_DEBUG
81 /* An sqlite query execution callback. */
82 static void
83 sqlite_tracer(void *data, const char *sql)
84 {
85   /*  sqlite3 *db3 = data; */
86   SVN_DBG(("sql=\"%s\"\n", sql));
87 }
88 #endif
89
90 #ifdef SQLITE3_PROFILE
91 /* An sqlite execution timing callback. */
92 static void
93 sqlite_profiler(void *data, const char *sql, sqlite3_uint64 duration)
94 {
95   /*  sqlite3 *db3 = data; */
96   SVN_DBG(("[%.3f] sql=\"%s\"\n", 1e-9 * duration, sql));
97 }
98 #endif
99
100 struct svn_sqlite__db_t
101 {
102   sqlite3 *db3;
103   const char * const *statement_strings;
104   int nbr_statements;
105   svn_sqlite__stmt_t **prepared_stmts;
106   apr_pool_t *state_pool;
107 };
108
109 struct svn_sqlite__stmt_t
110 {
111   sqlite3_stmt *s3stmt;
112   svn_sqlite__db_t *db;
113   svn_boolean_t needs_reset;
114 };
115
116 struct svn_sqlite__context_t
117 {
118   sqlite3_context *context;
119 };
120
121 struct svn_sqlite__value_t
122 {
123   sqlite3_value *value;
124 };
125
126
127 /* Convert SQLite error codes to SVN. Evaluates X multiple times */
128 #define SQLITE_ERROR_CODE(x) ((x) == SQLITE_READONLY            \
129                               ? SVN_ERR_SQLITE_READONLY         \
130                               : ((x) == SQLITE_BUSY             \
131                                  ? SVN_ERR_SQLITE_BUSY          \
132                                  : ((x) == SQLITE_CONSTRAINT    \
133                                     ? SVN_ERR_SQLITE_CONSTRAINT \
134                                     : SVN_ERR_SQLITE_ERROR)))
135
136
137 /* SQLITE->SVN quick error wrap, much like SVN_ERR. */
138 #define SQLITE_ERR(x, db) do                                     \
139 {                                                                \
140   int sqlite_err__temp = (x);                                    \
141   if (sqlite_err__temp != SQLITE_OK)                             \
142     return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
143                              NULL, "sqlite[S%d]: %s",             \
144                              sqlite_err__temp,                    \
145                              sqlite3_errmsg((db)->db3));          \
146 } while (0)
147
148 #define SQLITE_ERR_MSG(x, msg) do                                \
149 {                                                                \
150   int sqlite_err__temp = (x);                                    \
151   if (sqlite_err__temp != SQLITE_OK)                             \
152     return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
153                              NULL, "sqlite[S%d]: %s",            \
154                              sqlite_err__temp, msg);             \
155 } while (0)
156
157
158 /* Time (in milliseconds) to wait for sqlite locks before giving up. */
159 #define BUSY_TIMEOUT 10000
160
161
162 /* Convenience wrapper around exec_sql2(). */
163 #define exec_sql(db, sql) exec_sql2((db), (sql), SQLITE_OK)
164
165 /* Run the statement SQL on DB, ignoring SQLITE_OK and IGNORED_ERR.
166    (Note: the IGNORED_ERR parameter itself is not ignored.) */
167 static svn_error_t *
168 exec_sql2(svn_sqlite__db_t *db, const char *sql, int ignored_err)
169 {
170   char *err_msg;
171   int sqlite_err = sqlite3_exec(db->db3, sql, NULL, NULL, &err_msg);
172
173   if (sqlite_err != SQLITE_OK && sqlite_err != ignored_err)
174     {
175       svn_error_t *err = svn_error_createf(SQLITE_ERROR_CODE(sqlite_err), NULL,
176                                            _("sqlite[S%d]: %s,"
177                                              " executing statement '%s'"),
178                                            sqlite_err, err_msg, sql);
179       sqlite3_free(err_msg);
180       return err;
181     }
182
183   return SVN_NO_ERROR;
184 }
185
186
187 static svn_error_t *
188 prepare_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
189                   const char *text, apr_pool_t *result_pool)
190 {
191   *stmt = apr_palloc(result_pool, sizeof(**stmt));
192   (*stmt)->db = db;
193   (*stmt)->needs_reset = FALSE;
194
195   SQLITE_ERR(sqlite3_prepare_v2(db->db3, text, -1, &(*stmt)->s3stmt, NULL), db);
196
197   return SVN_NO_ERROR;
198 }
199
200
201 svn_error_t *
202 svn_sqlite__exec_statements(svn_sqlite__db_t *db, int stmt_idx)
203 {
204   SVN_ERR_ASSERT(stmt_idx < db->nbr_statements);
205
206   return svn_error_trace(exec_sql(db, db->statement_strings[stmt_idx]));
207 }
208
209
210 svn_error_t *
211 svn_sqlite__get_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
212                           int stmt_idx)
213 {
214   SVN_ERR_ASSERT(stmt_idx < db->nbr_statements);
215
216   if (db->prepared_stmts[stmt_idx] == NULL)
217     SVN_ERR(prepare_statement(&db->prepared_stmts[stmt_idx], db,
218                               db->statement_strings[stmt_idx],
219                               db->state_pool));
220
221   *stmt = db->prepared_stmts[stmt_idx];
222
223   if ((*stmt)->needs_reset)
224     return svn_error_trace(svn_sqlite__reset(*stmt));
225
226   return SVN_NO_ERROR;
227 }
228
229 /* Like svn_sqlite__get_statement but gets an internal statement.
230
231    All internal statements that use this api are executed with step_done(),
232    so we don't need the fallback reset handling here or in the pool cleanup */
233 static svn_error_t *
234 get_internal_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
235                        int stmt_idx)
236 {
237   /* The internal statements are stored after the registered statements */
238   int prep_idx = db->nbr_statements + stmt_idx;
239   SVN_ERR_ASSERT(stmt_idx < STMT_INTERNAL_LAST);
240
241   if (db->prepared_stmts[prep_idx] == NULL)
242     SVN_ERR(prepare_statement(&db->prepared_stmts[prep_idx], db,
243                               internal_statements[stmt_idx],
244                               db->state_pool));
245
246   *stmt = db->prepared_stmts[prep_idx];
247
248   return SVN_NO_ERROR;
249 }
250
251
252 static svn_error_t *
253 step_with_expectation(svn_sqlite__stmt_t* stmt,
254                       svn_boolean_t expecting_row)
255 {
256   svn_boolean_t got_row;
257
258   SVN_ERR(svn_sqlite__step(&got_row, stmt));
259   if ((got_row && !expecting_row)
260       ||
261       (!got_row && expecting_row))
262     return svn_error_create(SVN_ERR_SQLITE_ERROR,
263                             svn_sqlite__reset(stmt),
264                             expecting_row
265                               ? _("sqlite: Expected database row missing")
266                               : _("sqlite: Extra database row found"));
267
268   return SVN_NO_ERROR;
269 }
270
271 svn_error_t *
272 svn_sqlite__step_done(svn_sqlite__stmt_t *stmt)
273 {
274   SVN_ERR(step_with_expectation(stmt, FALSE));
275   return svn_error_trace(svn_sqlite__reset(stmt));
276 }
277
278 svn_error_t *
279 svn_sqlite__step_row(svn_sqlite__stmt_t *stmt)
280 {
281   return svn_error_trace(step_with_expectation(stmt, TRUE));
282 }
283
284
285 svn_error_t *
286 svn_sqlite__step(svn_boolean_t *got_row, svn_sqlite__stmt_t *stmt)
287 {
288   int sqlite_result = sqlite3_step(stmt->s3stmt);
289
290   if (sqlite_result != SQLITE_DONE && sqlite_result != SQLITE_ROW)
291     {
292       svn_error_t *err1, *err2;
293
294       err1 = svn_error_createf(SQLITE_ERROR_CODE(sqlite_result), NULL,
295                                "sqlite[S%d]: %s",
296                                sqlite_result, sqlite3_errmsg(stmt->db->db3));
297       err2 = svn_sqlite__reset(stmt);
298       return svn_error_compose_create(err1, err2);
299     }
300
301   *got_row = (sqlite_result == SQLITE_ROW);
302   stmt->needs_reset = TRUE;
303
304   return SVN_NO_ERROR;
305 }
306
307 svn_error_t *
308 svn_sqlite__insert(apr_int64_t *row_id, svn_sqlite__stmt_t *stmt)
309 {
310   svn_boolean_t got_row;
311
312   SVN_ERR(svn_sqlite__step(&got_row, stmt));
313   if (row_id)
314     *row_id = sqlite3_last_insert_rowid(stmt->db->db3);
315
316   return svn_error_trace(svn_sqlite__reset(stmt));
317 }
318
319 svn_error_t *
320 svn_sqlite__update(int *affected_rows, svn_sqlite__stmt_t *stmt)
321 {
322   SVN_ERR(step_with_expectation(stmt, FALSE));
323
324   if (affected_rows)
325     *affected_rows = sqlite3_changes(stmt->db->db3);
326
327   return svn_error_trace(svn_sqlite__reset(stmt));
328 }
329
330
331 static svn_error_t *
332 vbindf(svn_sqlite__stmt_t *stmt, const char *fmt, va_list ap)
333 {
334   int count;
335
336   for (count = 1; *fmt; fmt++, count++)
337     {
338       const void *blob;
339       apr_size_t blob_size;
340       const svn_token_map_t *map;
341
342       switch (*fmt)
343         {
344           case 's':
345             SVN_ERR(svn_sqlite__bind_text(stmt, count,
346                                           va_arg(ap, const char *)));
347             break;
348
349           case 'd':
350             SVN_ERR(svn_sqlite__bind_int(stmt, count,
351                                          va_arg(ap, int)));
352             break;
353
354           case 'i':
355           case 'L':
356             SVN_ERR(svn_sqlite__bind_int64(stmt, count,
357                                            va_arg(ap, apr_int64_t)));
358             break;
359
360           case 'b':
361             blob = va_arg(ap, const void *);
362             blob_size = va_arg(ap, apr_size_t);
363             SVN_ERR(svn_sqlite__bind_blob(stmt, count, blob, blob_size));
364             break;
365
366           case 'r':
367             SVN_ERR(svn_sqlite__bind_revnum(stmt, count,
368                                             va_arg(ap, svn_revnum_t)));
369             break;
370
371           case 't':
372             map = va_arg(ap, const svn_token_map_t *);
373             SVN_ERR(svn_sqlite__bind_token(stmt, count, map, va_arg(ap, int)));
374             break;
375
376           case 'n':
377             /* Skip this column: no binding */
378             break;
379
380           default:
381             SVN_ERR_MALFUNCTION();
382         }
383     }
384
385   return SVN_NO_ERROR;
386 }
387
388 svn_error_t *
389 svn_sqlite__bindf(svn_sqlite__stmt_t *stmt, const char *fmt, ...)
390 {
391   svn_error_t *err;
392   va_list ap;
393
394   va_start(ap, fmt);
395   err = vbindf(stmt, fmt, ap);
396   va_end(ap);
397   return svn_error_trace(err);
398 }
399
400 svn_error_t *
401 svn_sqlite__bind_int(svn_sqlite__stmt_t *stmt,
402                      int slot,
403                      int val)
404 {
405   SQLITE_ERR(sqlite3_bind_int(stmt->s3stmt, slot, val), stmt->db);
406   return SVN_NO_ERROR;
407 }
408
409 svn_error_t *
410 svn_sqlite__bind_int64(svn_sqlite__stmt_t *stmt,
411                        int slot,
412                        apr_int64_t val)
413 {
414   SQLITE_ERR(sqlite3_bind_int64(stmt->s3stmt, slot, val), stmt->db);
415   return SVN_NO_ERROR;
416 }
417
418 svn_error_t *
419 svn_sqlite__bind_text(svn_sqlite__stmt_t *stmt,
420                       int slot,
421                       const char *val)
422 {
423   SQLITE_ERR(sqlite3_bind_text(stmt->s3stmt, slot, val, -1, SQLITE_TRANSIENT),
424              stmt->db);
425   return SVN_NO_ERROR;
426 }
427
428 svn_error_t *
429 svn_sqlite__bind_blob(svn_sqlite__stmt_t *stmt,
430                       int slot,
431                       const void *val,
432                       apr_size_t len)
433 {
434   SQLITE_ERR(sqlite3_bind_blob(stmt->s3stmt, slot, val, (int) len,
435                                SQLITE_TRANSIENT),
436              stmt->db);
437   return SVN_NO_ERROR;
438 }
439
440 svn_error_t *
441 svn_sqlite__bind_token(svn_sqlite__stmt_t *stmt,
442                        int slot,
443                        const svn_token_map_t *map,
444                        int value)
445 {
446   const char *word = svn_token__to_word(map, value);
447
448   SQLITE_ERR(sqlite3_bind_text(stmt->s3stmt, slot, word, -1, SQLITE_STATIC),
449              stmt->db);
450   return SVN_NO_ERROR;
451 }
452
453 svn_error_t *
454 svn_sqlite__bind_revnum(svn_sqlite__stmt_t *stmt,
455                         int slot,
456                         svn_revnum_t value)
457 {
458   if (SVN_IS_VALID_REVNUM(value))
459     SQLITE_ERR(sqlite3_bind_int64(stmt->s3stmt, slot,
460                                   (sqlite_int64)value), stmt->db);
461   else
462     SQLITE_ERR(sqlite3_bind_null(stmt->s3stmt, slot), stmt->db);
463
464   return SVN_NO_ERROR;
465 }
466
467 svn_error_t *
468 svn_sqlite__bind_properties(svn_sqlite__stmt_t *stmt,
469                             int slot,
470                             const apr_hash_t *props,
471                             apr_pool_t *scratch_pool)
472 {
473   svn_skel_t *skel;
474   svn_stringbuf_t *properties;
475
476   if (props == NULL)
477     return svn_error_trace(svn_sqlite__bind_blob(stmt, slot, NULL, 0));
478
479   SVN_ERR(svn_skel__unparse_proplist(&skel, props, scratch_pool));
480   properties = svn_skel__unparse(skel, scratch_pool);
481   return svn_error_trace(svn_sqlite__bind_blob(stmt,
482                                                slot,
483                                                properties->data,
484                                                properties->len));
485 }
486
487 svn_error_t *
488 svn_sqlite__bind_iprops(svn_sqlite__stmt_t *stmt,
489                         int slot,
490                         const apr_array_header_t *inherited_props,
491                         apr_pool_t *scratch_pool)
492 {
493   svn_skel_t *skel;
494   svn_stringbuf_t *properties;
495
496   if (inherited_props == NULL)
497     return svn_error_trace(svn_sqlite__bind_blob(stmt, slot, NULL, 0));
498
499   SVN_ERR(svn_skel__unparse_iproplist(&skel, inherited_props,
500                                       scratch_pool, scratch_pool));
501   properties = svn_skel__unparse(skel, scratch_pool);
502   return svn_error_trace(svn_sqlite__bind_blob(stmt,
503                                                slot,
504                                                properties->data,
505                                                properties->len));
506 }
507
508 svn_error_t *
509 svn_sqlite__bind_checksum(svn_sqlite__stmt_t *stmt,
510                           int slot,
511                           const svn_checksum_t *checksum,
512                           apr_pool_t *scratch_pool)
513 {
514   const char *csum_str;
515
516   if (checksum == NULL)
517     csum_str = NULL;
518   else
519     csum_str = svn_checksum_serialize(checksum, scratch_pool, scratch_pool);
520
521   return svn_error_trace(svn_sqlite__bind_text(stmt, slot, csum_str));
522 }
523
524
525 const void *
526 svn_sqlite__column_blob(svn_sqlite__stmt_t *stmt, int column,
527                         apr_size_t *len, apr_pool_t *result_pool)
528 {
529   const void *val = sqlite3_column_blob(stmt->s3stmt, column);
530   *len = sqlite3_column_bytes(stmt->s3stmt, column);
531
532   if (result_pool && val != NULL)
533     val = apr_pmemdup(result_pool, val, *len);
534
535   return val;
536 }
537
538 const char *
539 svn_sqlite__column_text(svn_sqlite__stmt_t *stmt, int column,
540                         apr_pool_t *result_pool)
541 {
542   /* cast from 'unsigned char' to regular 'char'  */
543   const char *result = (const char *)sqlite3_column_text(stmt->s3stmt, column);
544
545   if (result_pool && result != NULL)
546     result = apr_pstrdup(result_pool, result);
547
548   return result;
549 }
550
551 svn_revnum_t
552 svn_sqlite__column_revnum(svn_sqlite__stmt_t *stmt, int column)
553 {
554   if (svn_sqlite__column_is_null(stmt, column))
555     return SVN_INVALID_REVNUM;
556   return (svn_revnum_t) sqlite3_column_int64(stmt->s3stmt, column);
557 }
558
559 svn_boolean_t
560 svn_sqlite__column_boolean(svn_sqlite__stmt_t *stmt, int column)
561 {
562   return sqlite3_column_int64(stmt->s3stmt, column) != 0;
563 }
564
565 int
566 svn_sqlite__column_int(svn_sqlite__stmt_t *stmt, int column)
567 {
568   return sqlite3_column_int(stmt->s3stmt, column);
569 }
570
571 apr_int64_t
572 svn_sqlite__column_int64(svn_sqlite__stmt_t *stmt, int column)
573 {
574   return sqlite3_column_int64(stmt->s3stmt, column);
575 }
576
577 int
578 svn_sqlite__column_token(svn_sqlite__stmt_t *stmt,
579                          int column,
580                          const svn_token_map_t *map)
581 {
582   /* cast from 'unsigned char' to regular 'char'  */
583   const char *word = (const char *)sqlite3_column_text(stmt->s3stmt, column);
584
585   return svn_token__from_word_strict(map, word);
586 }
587
588 int
589 svn_sqlite__column_token_null(svn_sqlite__stmt_t *stmt,
590                               int column,
591                               const svn_token_map_t *map,
592                               int null_val)
593 {
594   /* cast from 'unsigned char' to regular 'char'  */
595   const char *word = (const char *)sqlite3_column_text(stmt->s3stmt, column);
596
597   if (!word)
598     return null_val;
599
600   return svn_token__from_word_strict(map, word);
601 }
602
603 svn_error_t *
604 svn_sqlite__column_properties(apr_hash_t **props,
605                               svn_sqlite__stmt_t *stmt,
606                               int column,
607                               apr_pool_t *result_pool,
608                               apr_pool_t *scratch_pool)
609 {
610   apr_size_t len;
611   const void *val;
612
613   /* svn_skel__parse_proplist copies everything needed to result_pool */
614   val = svn_sqlite__column_blob(stmt, column, &len, NULL);
615   if (val == NULL)
616     {
617       *props = NULL;
618       return SVN_NO_ERROR;
619     }
620
621   SVN_ERR(svn_skel__parse_proplist(props,
622                                    svn_skel__parse(val, len, scratch_pool),
623                                    result_pool));
624
625   return SVN_NO_ERROR;
626 }
627
628 svn_error_t *
629 svn_sqlite__column_iprops(apr_array_header_t **iprops,
630                           svn_sqlite__stmt_t *stmt,
631                           int column,
632                           apr_pool_t *result_pool,
633                           apr_pool_t *scratch_pool)
634 {
635   apr_size_t len;
636   const void *val;
637
638   /* svn_skel__parse_iprops copies everything needed to result_pool */
639   val = svn_sqlite__column_blob(stmt, column, &len, NULL);
640   if (val == NULL)
641     {
642       *iprops = NULL;
643       return SVN_NO_ERROR;
644     }
645
646   SVN_ERR(svn_skel__parse_iprops(iprops,
647                                  svn_skel__parse(val, len, scratch_pool),
648                                  result_pool));
649
650   return SVN_NO_ERROR;
651 }
652
653 svn_error_t *
654 svn_sqlite__column_checksum(const svn_checksum_t **checksum,
655                             svn_sqlite__stmt_t *stmt, int column,
656                             apr_pool_t *result_pool)
657 {
658   const char *digest = svn_sqlite__column_text(stmt, column, NULL);
659
660   if (digest == NULL)
661     *checksum = NULL;
662   else
663     SVN_ERR(svn_checksum_deserialize(checksum, digest,
664                                      result_pool, result_pool));
665
666   return SVN_NO_ERROR;
667 }
668
669 svn_boolean_t
670 svn_sqlite__column_is_null(svn_sqlite__stmt_t *stmt, int column)
671 {
672   return sqlite3_column_type(stmt->s3stmt, column) == SQLITE_NULL;
673 }
674
675 int
676 svn_sqlite__column_bytes(svn_sqlite__stmt_t *stmt, int column)
677 {
678   return sqlite3_column_bytes(stmt->s3stmt, column);
679 }
680
681 svn_error_t *
682 svn_sqlite__finalize(svn_sqlite__stmt_t *stmt)
683 {
684   SQLITE_ERR(sqlite3_finalize(stmt->s3stmt), stmt->db);
685   return SVN_NO_ERROR;
686 }
687
688 svn_error_t *
689 svn_sqlite__reset(svn_sqlite__stmt_t *stmt)
690 {
691   SQLITE_ERR(sqlite3_reset(stmt->s3stmt), stmt->db);
692   SQLITE_ERR(sqlite3_clear_bindings(stmt->s3stmt), stmt->db);
693   stmt->needs_reset = FALSE;
694   return SVN_NO_ERROR;
695 }
696
697
698 svn_error_t *
699 svn_sqlite__read_schema_version(int *version,
700                                 svn_sqlite__db_t *db,
701                                 apr_pool_t *scratch_pool)
702 {
703   svn_sqlite__stmt_t *stmt;
704
705   SVN_ERR(prepare_statement(&stmt, db, "PRAGMA user_version;", scratch_pool));
706   SVN_ERR(svn_sqlite__step_row(stmt));
707
708   *version = svn_sqlite__column_int(stmt, 0);
709
710   return svn_error_trace(svn_sqlite__finalize(stmt));
711 }
712
713
714 static volatile svn_atomic_t sqlite_init_state = 0;
715
716 /* If possible, verify that SQLite was compiled in a thread-safe
717    manner. */
718 /* Don't call this function directly!  Use svn_atomic__init_once(). */
719 static svn_error_t *
720 init_sqlite(void *baton, apr_pool_t *pool)
721 {
722   if (sqlite3_libversion_number() < SVN_SQLITE_MIN_VERSION_NUMBER)
723     {
724       return svn_error_createf(
725                     SVN_ERR_SQLITE_ERROR, NULL,
726                     _("SQLite compiled for %s, but running with %s"),
727                     SVN_SQLITE_MIN_VERSION, sqlite3_libversion());
728     }
729
730 #if APR_HAS_THREADS
731
732   /* SQLite 3.5 allows verification of its thread-safety at runtime.
733      Older versions are simply expected to have been configured with
734      --enable-threadsafe, which compiles with -DSQLITE_THREADSAFE=1
735      (or -DTHREADSAFE, for older versions). */
736   if (! sqlite3_threadsafe())
737     return svn_error_create(SVN_ERR_SQLITE_ERROR, NULL,
738                             _("SQLite is required to be compiled and run in "
739                               "thread-safe mode"));
740
741   /* If SQLite has been already initialized, sqlite3_config() returns
742      SQLITE_MISUSE. */
743   {
744     int err = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
745     if (err != SQLITE_OK && err != SQLITE_MISUSE)
746       return svn_error_createf(SQLITE_ERROR_CODE(err), NULL,
747                                _("Could not configure SQLite [S%d]"), err);
748   }
749   SQLITE_ERR_MSG(sqlite3_initialize(), _("Could not initialize SQLite"));
750
751 #endif /* APR_HAS_THRADS */
752
753   return SVN_NO_ERROR;
754 }
755
756 static svn_error_t *
757 internal_open(sqlite3 **db3, const char *path, svn_sqlite__mode_t mode,
758               apr_pool_t *scratch_pool)
759 {
760   {
761     int flags;
762
763     if (mode == svn_sqlite__mode_readonly)
764       flags = SQLITE_OPEN_READONLY;
765     else if (mode == svn_sqlite__mode_readwrite)
766       flags = SQLITE_OPEN_READWRITE;
767     else if (mode == svn_sqlite__mode_rwcreate)
768       flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
769     else
770       SVN_ERR_MALFUNCTION();
771
772     /* Turn off SQLite's mutexes. All svn objects are single-threaded,
773        so we can already guarantee that our use of the SQLite handle
774        will be serialized properly.
775
776        Note: in 3.6.x, we've already config'd SQLite into MULTITHREAD mode,
777        so this is probably redundant, but if we are running in a process where
778        somebody initialized SQLite before us it is needed anyway.  */
779     flags |= SQLITE_OPEN_NOMUTEX;
780
781 #if !defined(WIN32) && !defined(SVN_SQLITE_INLINE)
782     if (mode == svn_sqlite__mode_rwcreate)
783       {
784         svn_node_kind_t kind;
785
786         /* Create the file before SQLite to avoid any permissions
787            problems with an SQLite build that uses the default
788            SQLITE_DEFAULT_FILE_PERMISSIONS of 644 modified by umask.
789            We simply want umask permissions. */
790         SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
791         if (kind == svn_node_none)
792           SVN_ERR(svn_io_file_create(path, "", scratch_pool));
793       }
794 #endif
795
796     /* Open the database. Note that a handle is returned, even when an error
797        occurs (except for out-of-memory); thus, we can safely use it to
798        extract an error message and construct an svn_error_t. */
799     {
800       /* We'd like to use SQLITE_ERR here, but we can't since it would
801          just return an error and leave the database open.  So, we need to
802          do this manually. */
803       /* ### SQLITE_CANTOPEN */
804       int err_code = sqlite3_open_v2(path, db3, flags, NULL);
805       if (err_code != SQLITE_OK)
806         {
807           /* Save the error message before closing the SQLite handle. */
808           char *msg = apr_pstrdup(scratch_pool, sqlite3_errmsg(*db3));
809
810           /* We don't catch the error here, since we care more about the open
811              error than the close error at this point. */
812           sqlite3_close(*db3);
813
814           SQLITE_ERR_MSG(err_code, msg);
815         }
816     }
817   }
818
819   /* Retry until timeout when database is busy. */
820   SQLITE_ERR_MSG(sqlite3_busy_timeout(*db3, BUSY_TIMEOUT),
821                  sqlite3_errmsg(*db3));
822
823   return SVN_NO_ERROR;
824 }
825
826
827 /* APR cleanup function used to close the database when its pool is destroyed.
828    DATA should be the svn_sqlite__db_t handle for the database. */
829 static apr_status_t
830 close_apr(void *data)
831 {
832   svn_sqlite__db_t *db = data;
833   svn_error_t *err = SVN_NO_ERROR;
834   apr_status_t result;
835   int i;
836
837   /* Check to see if we've already closed this database. */
838   if (db->db3 == NULL)
839     return APR_SUCCESS;
840
841   /* Finalize any existing prepared statements. */
842   for (i = 0; i < db->nbr_statements; i++)
843     {
844       if (db->prepared_stmts[i])
845         {
846           if (db->prepared_stmts[i]->needs_reset)
847             {
848 #ifdef SVN_DEBUG
849               const char *stmt_text = db->statement_strings[i];
850               stmt_text = stmt_text; /* Provide value for debugger */
851
852               SVN_ERR_MALFUNCTION_NO_RETURN();
853 #else
854               err = svn_error_compose_create(
855                             err,
856                             svn_sqlite__reset(db->prepared_stmts[i]));
857 #endif
858             }
859           err = svn_error_compose_create(
860                         svn_sqlite__finalize(db->prepared_stmts[i]), err);
861         }
862     }
863   /* And finalize any used internal statements */
864   for (; i < db->nbr_statements + STMT_INTERNAL_LAST; i++)
865     {
866       if (db->prepared_stmts[i])
867         {
868           err = svn_error_compose_create(
869                         svn_sqlite__finalize(db->prepared_stmts[i]), err);
870         }
871     }
872
873   result = sqlite3_close(db->db3);
874
875   /* If there's a pre-existing error, return it. */
876   if (err)
877     {
878       result = err->apr_err;
879       svn_error_clear(err);
880       return result;
881     }
882
883   if (result != SQLITE_OK)
884     return SQLITE_ERROR_CODE(result); /* ### lossy */
885
886   db->db3 = NULL;
887
888   return APR_SUCCESS;
889 }
890
891
892 svn_error_t *
893 svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
894                  svn_sqlite__mode_t mode, const char * const statements[],
895                  int unused1, const char * const *unused2,
896                  apr_pool_t *result_pool, apr_pool_t *scratch_pool)
897 {
898   SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
899                                 init_sqlite, NULL, scratch_pool));
900
901   *db = apr_pcalloc(result_pool, sizeof(**db));
902
903   SVN_ERR(internal_open(&(*db)->db3, path, mode, scratch_pool));
904
905 #if SQLITE_VERSION_NUMBER >= 3008000 && SQLITE_VERSION_NUMBER < 3009000
906   /* disable SQLITE_ENABLE_STAT3/4 from 3.8.1 - 3.8.3 (but not 3.8.3.1+)
907    * to prevent using it when it's buggy.
908    * See: https://www.sqlite.org/src/info/4c86b126f2 */
909   if (sqlite3_libversion_number() > 3008000 &&
910       sqlite3_libversion_number() < 3008004 &&
911       strcmp(sqlite3_sourceid(),"2014-02-11")<0)
912     {
913       sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, (*db)->db3, 0x800);
914     }
915 #endif
916
917 #ifdef SQLITE3_DEBUG
918   sqlite3_trace((*db)->db3, sqlite_tracer, (*db)->db3);
919 #endif
920 #ifdef SQLITE3_PROFILE
921   sqlite3_profile((*db)->db3, sqlite_profiler, (*db)->db3);
922 #endif
923
924   /* ### simplify this. remnants of some old SQLite compat code.  */
925   {
926     int ignored_err = SQLITE_OK;
927
928     SVN_ERR(exec_sql2(*db, "PRAGMA case_sensitive_like=1;", ignored_err));
929   }
930
931   SVN_ERR(exec_sql(*db,
932               /* Disable synchronization to disable the explicit disk flushes
933                  that make Sqlite up to 50 times slower; especially on small
934                  transactions.
935
936                  This removes some stability guarantees on specific hardware
937                  and power failures, but still guarantees atomic commits on
938                  application crashes. With our dependency on external data
939                  like pristine files (Wc) and revision files (repository),
940                  we can't keep up these additional guarantees anyway.
941
942                  ### Maybe switch to NORMAL(1) when we use larger transaction
943                      scopes */
944               "PRAGMA synchronous=OFF;"
945               /* Enable recursive triggers so that a user trigger will fire
946                  in the deletion phase of an INSERT OR REPLACE statement.
947                  Requires SQLite >= 3.6.18  */
948               "PRAGMA recursive_triggers=ON;"
949               /* Enforce current Sqlite default behavior. Some distributions
950                  might change the Sqlite defaults without realizing how this
951                  affects application(read: Subversion) performance/behavior. */
952               "PRAGMA foreign_keys=OFF;"      /* SQLITE_DEFAULT_FOREIGN_KEYS*/
953               "PRAGMA locking_mode = NORMAL;" /* SQLITE_DEFAULT_LOCKING_MODE */
954               ));
955
956 #if defined(SVN_DEBUG)
957   /* When running in debug mode, enable the checking of foreign key
958      constraints.  This has possible performance implications, so we don't
959      bother to do it for production...for now. */
960   SVN_ERR(exec_sql(*db, "PRAGMA foreign_keys=ON;"));
961 #endif
962
963 #ifdef SVN_SQLITE_REVERSE_UNORDERED_SELECTS
964   /* When enabled, this PRAGMA causes SELECT statements without an ORDER BY
965      clause to emit their results in the reverse order of what they normally
966      would.  This can help detecting invalid assumptions about the result
967      order.*/
968   SVN_ERR(exec_sql(*db, "PRAGMA reverse_unordered_selects=ON;"));
969 #endif
970
971   /* Store temporary tables in RAM instead of in temporary files, but don't
972      fail on this if this option is disabled in the sqlite compilation by
973      setting SQLITE_TEMP_STORE to 0 (always to disk) */
974   svn_error_clear(exec_sql(*db, "PRAGMA temp_store = MEMORY;"));
975
976   /* Store the provided statements. */
977   if (statements)
978     {
979       (*db)->statement_strings = statements;
980       (*db)->nbr_statements = 0;
981       while (*statements != NULL)
982         {
983           statements++;
984           (*db)->nbr_statements++;
985         }
986
987       (*db)->prepared_stmts = apr_pcalloc(
988                                   result_pool,
989                                   ((*db)->nbr_statements + STMT_INTERNAL_LAST)
990                                                 * sizeof(svn_sqlite__stmt_t *));
991     }
992   else
993     {
994       (*db)->nbr_statements = 0;
995       (*db)->prepared_stmts = apr_pcalloc(result_pool,
996                                           (0 + STMT_INTERNAL_LAST)
997                                                 * sizeof(svn_sqlite__stmt_t *));
998     }
999
1000   (*db)->state_pool = result_pool;
1001   apr_pool_cleanup_register(result_pool, *db, close_apr, apr_pool_cleanup_null);
1002
1003   return SVN_NO_ERROR;
1004 }
1005
1006 svn_error_t *
1007 svn_sqlite__close(svn_sqlite__db_t *db)
1008 {
1009   apr_status_t result = apr_pool_cleanup_run(db->state_pool, db, close_apr);
1010
1011   if (result == APR_SUCCESS)
1012     return SVN_NO_ERROR;
1013
1014   return svn_error_wrap_apr(result, NULL);
1015 }
1016
1017 static svn_error_t *
1018 reset_all_statements(svn_sqlite__db_t *db,
1019                      svn_error_t *error_to_wrap)
1020 {
1021   int i;
1022   svn_error_t *err;
1023
1024   /* ### Should we reorder the errors in this specific case
1025      ### to avoid returning the normal error as top level error? */
1026
1027   err = svn_error_compose_create(error_to_wrap,
1028                    svn_error_create(SVN_ERR_SQLITE_RESETTING_FOR_ROLLBACK,
1029                                     NULL, NULL));
1030
1031   for (i = 0; i < db->nbr_statements; i++)
1032     if (db->prepared_stmts[i] && db->prepared_stmts[i]->needs_reset)
1033       err = svn_error_compose_create(err,
1034                                 svn_sqlite__reset(db->prepared_stmts[i]));
1035
1036   return err;
1037 }
1038
1039 svn_error_t *
1040 svn_sqlite__begin_transaction(svn_sqlite__db_t *db)
1041 {
1042   svn_sqlite__stmt_t *stmt;
1043
1044   SVN_ERR(get_internal_statement(&stmt, db,
1045                                  STMT_INTERNAL_BEGIN_TRANSACTION));
1046   SVN_ERR(svn_sqlite__step_done(stmt));
1047   return SVN_NO_ERROR;
1048 }
1049
1050 svn_error_t *
1051 svn_sqlite__begin_immediate_transaction(svn_sqlite__db_t *db)
1052 {
1053   svn_sqlite__stmt_t *stmt;
1054
1055   SVN_ERR(get_internal_statement(&stmt, db,
1056                                  STMT_INTERNAL_BEGIN_IMMEDIATE_TRANSACTION));
1057   SVN_ERR(svn_sqlite__step_done(stmt));
1058   return SVN_NO_ERROR;
1059 }
1060
1061 svn_error_t *
1062 svn_sqlite__begin_savepoint(svn_sqlite__db_t *db)
1063 {
1064   svn_sqlite__stmt_t *stmt;
1065
1066   SVN_ERR(get_internal_statement(&stmt, db,
1067                                  STMT_INTERNAL_SAVEPOINT_SVN));
1068   SVN_ERR(svn_sqlite__step_done(stmt));
1069   return SVN_NO_ERROR;
1070 }
1071
1072 svn_error_t *
1073 svn_sqlite__finish_transaction(svn_sqlite__db_t *db,
1074                                svn_error_t *err)
1075 {
1076   svn_sqlite__stmt_t *stmt;
1077
1078   /* Commit or rollback the sqlite transaction. */
1079   if (err)
1080     {
1081       svn_error_t *err2;
1082
1083       err2 = get_internal_statement(&stmt, db,
1084                                     STMT_INTERNAL_ROLLBACK_TRANSACTION);
1085       if (!err2)
1086         err2 = svn_sqlite__step_done(stmt);
1087
1088       if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
1089         {
1090           /* ### Houston, we have a problem!
1091
1092              We are trying to rollback but we can't because some
1093              statements are still busy. This leaves the database
1094              unusable for future transactions as the current transaction
1095              is still open.
1096
1097              As we are returning the actual error as the most relevant
1098              error in the chain, our caller might assume that it can
1099              retry/compensate on this error (e.g. SVN_WC_LOCKED), while
1100              in fact the SQLite database is unusable until the statements
1101              started within this transaction are reset and the transaction
1102              aborted.
1103
1104              We try to compensate by resetting all prepared but unreset
1105              statements; but we leave the busy error in the chain anyway to
1106              help diagnosing the original error and help in finding where
1107              a reset statement is missing. */
1108
1109           err2 = reset_all_statements(db, err2);
1110           err2 = svn_error_compose_create(
1111                       svn_sqlite__step_done(stmt),
1112                       err2);
1113         }
1114
1115       return svn_error_compose_create(err,
1116                                       err2);
1117     }
1118
1119   SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_COMMIT_TRANSACTION));
1120   return svn_error_trace(svn_sqlite__step_done(stmt));
1121 }
1122
1123 svn_error_t *
1124 svn_sqlite__finish_savepoint(svn_sqlite__db_t *db,
1125                              svn_error_t *err)
1126 {
1127   svn_sqlite__stmt_t *stmt;
1128
1129   if (err)
1130     {
1131       svn_error_t *err2;
1132
1133       err2 = get_internal_statement(&stmt, db,
1134                                     STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN);
1135
1136       if (!err2)
1137         err2 = svn_sqlite__step_done(stmt);
1138
1139       if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
1140         {
1141           /* Ok, we have a major problem. Some statement is still open, which
1142              makes it impossible to release this savepoint.
1143
1144              ### See huge comment in svn_sqlite__finish_transaction for
1145                  further details */
1146
1147           err2 = reset_all_statements(db, err2);
1148           err2 = svn_error_compose_create(svn_sqlite__step_done(stmt), err2);
1149         }
1150
1151       err = svn_error_compose_create(err, err2);
1152       err2 = get_internal_statement(&stmt, db,
1153                                     STMT_INTERNAL_RELEASE_SAVEPOINT_SVN);
1154
1155       if (!err2)
1156         err2 = svn_sqlite__step_done(stmt);
1157
1158       return svn_error_trace(svn_error_compose_create(err, err2));
1159     }
1160
1161   SVN_ERR(get_internal_statement(&stmt, db,
1162                                  STMT_INTERNAL_RELEASE_SAVEPOINT_SVN));
1163
1164   return svn_error_trace(svn_sqlite__step_done(stmt));
1165 }
1166
1167 svn_error_t *
1168 svn_sqlite__with_transaction(svn_sqlite__db_t *db,
1169                              svn_sqlite__transaction_callback_t cb_func,
1170                              void *cb_baton,
1171                              apr_pool_t *scratch_pool /* NULL allowed */)
1172 {
1173   SVN_SQLITE__WITH_TXN(cb_func(cb_baton, db, scratch_pool), db);
1174   return SVN_NO_ERROR;
1175 }
1176
1177 svn_error_t *
1178 svn_sqlite__with_immediate_transaction(
1179   svn_sqlite__db_t *db,
1180   svn_sqlite__transaction_callback_t cb_func,
1181   void *cb_baton,
1182   apr_pool_t *scratch_pool /* NULL allowed */)
1183 {
1184   SVN_SQLITE__WITH_IMMEDIATE_TXN(cb_func(cb_baton, db, scratch_pool), db);
1185   return SVN_NO_ERROR;
1186 }
1187
1188 svn_error_t *
1189 svn_sqlite__with_lock(svn_sqlite__db_t *db,
1190                       svn_sqlite__transaction_callback_t cb_func,
1191                       void *cb_baton,
1192                       apr_pool_t *scratch_pool /* NULL allowed */)
1193 {
1194   SVN_SQLITE__WITH_LOCK(cb_func(cb_baton, db, scratch_pool), db);
1195   return SVN_NO_ERROR;
1196 }
1197
1198 svn_error_t *
1199 svn_sqlite__hotcopy(const char *src_path,
1200                     const char *dst_path,
1201                     apr_pool_t *scratch_pool)
1202 {
1203   svn_sqlite__db_t *src_db;
1204
1205   SVN_ERR(svn_sqlite__open(&src_db, src_path, svn_sqlite__mode_readonly,
1206                            NULL, 0, NULL,
1207                            scratch_pool, scratch_pool));
1208
1209   {
1210     svn_sqlite__db_t *dst_db;
1211     sqlite3_backup *backup;
1212     int rc1, rc2;
1213
1214     SVN_ERR(svn_sqlite__open(&dst_db, dst_path, svn_sqlite__mode_rwcreate,
1215                              NULL, 0, NULL, scratch_pool, scratch_pool));
1216     backup = sqlite3_backup_init(dst_db->db3, "main", src_db->db3, "main");
1217     if (!backup)
1218       return svn_error_createf(SVN_ERR_SQLITE_ERROR, NULL,
1219                                _("SQLite hotcopy failed for %s"), src_path);
1220     do
1221       {
1222         /* Pages are usually 1024 byte (SQLite docs). On my laptop
1223            copying gets faster as the number of pages is increased up
1224            to about 64, beyond that speed levels off.  Lets put the
1225            number of pages an order of magnitude higher, this is still
1226            likely to be a fraction of large databases. */
1227         rc1 = sqlite3_backup_step(backup, 1024);
1228
1229         /* Should we sleep on SQLITE_OK?  That would make copying a
1230            large database take much longer.  When we do sleep how,
1231            long should we sleep?  Should the sleep get longer if we
1232            keep getting BUSY/LOCKED?  I have no real reason for
1233            choosing 25. */
1234         if (rc1 == SQLITE_BUSY || rc1 == SQLITE_LOCKED)
1235           sqlite3_sleep(25);
1236       }
1237     while (rc1 == SQLITE_OK || rc1 == SQLITE_BUSY || rc1 == SQLITE_LOCKED);
1238     rc2 = sqlite3_backup_finish(backup);
1239     if (rc1 != SQLITE_DONE)
1240       SQLITE_ERR(rc1, dst_db);
1241     SQLITE_ERR(rc2, dst_db);
1242     SVN_ERR(svn_sqlite__close(dst_db));
1243   }
1244
1245   SVN_ERR(svn_sqlite__close(src_db));
1246
1247   return SVN_NO_ERROR;
1248 }
1249
1250 struct function_wrapper_baton_t
1251 {
1252   svn_sqlite__func_t func;
1253   void *baton;
1254
1255   apr_pool_t *scratch_pool;
1256 };
1257
1258 static void
1259 wrapped_func(sqlite3_context *context,
1260              int argc,
1261              sqlite3_value *values[])
1262 {
1263   struct function_wrapper_baton_t *fwb = sqlite3_user_data(context);
1264   svn_sqlite__context_t sctx;
1265   svn_sqlite__value_t **local_vals =
1266                             apr_palloc(fwb->scratch_pool,
1267                                        sizeof(svn_sqlite__value_t *) * argc);
1268   svn_error_t *err;
1269   int i;
1270
1271   sctx.context = context;
1272
1273   for (i = 0; i < argc; i++)
1274     {
1275       local_vals[i] = apr_palloc(fwb->scratch_pool, sizeof(*local_vals[i]));
1276       local_vals[i]->value = values[i];
1277     }
1278
1279   err = fwb->func(&sctx, argc, local_vals, fwb->scratch_pool);
1280   svn_pool_clear(fwb->scratch_pool);
1281
1282   if (err)
1283     {
1284       char buf[256];
1285       sqlite3_result_error(context,
1286                            svn_err_best_message(err, buf, sizeof(buf)),
1287                            -1);
1288       svn_error_clear(err);
1289     }
1290 }
1291
1292 svn_error_t *
1293 svn_sqlite__create_scalar_function(svn_sqlite__db_t *db,
1294                                    const char *func_name,
1295                                    int argc,
1296                                    svn_sqlite__func_t func,
1297                                    void *baton)
1298 {
1299   struct function_wrapper_baton_t *fwb = apr_pcalloc(db->state_pool,
1300                                                      sizeof(*fwb));
1301
1302   fwb->scratch_pool = svn_pool_create(db->state_pool);
1303   fwb->func = func;
1304   fwb->baton = baton;
1305
1306   SQLITE_ERR(sqlite3_create_function(db->db3, func_name, argc, SQLITE_ANY,
1307                                      fwb, wrapped_func, NULL, NULL),
1308              db);
1309
1310   return SVN_NO_ERROR;
1311 }
1312
1313 int
1314 svn_sqlite__value_type(svn_sqlite__value_t *val)
1315 {
1316   return sqlite3_value_type(val->value);
1317 }
1318
1319 const char *
1320 svn_sqlite__value_text(svn_sqlite__value_t *val)
1321 {
1322   return (const char *) sqlite3_value_text(val->value);
1323 }
1324
1325 void
1326 svn_sqlite__result_null(svn_sqlite__context_t *sctx)
1327 {
1328   sqlite3_result_null(sctx->context);
1329 }
1330
1331 void
1332 svn_sqlite__result_int64(svn_sqlite__context_t *sctx, apr_int64_t val)
1333 {
1334   sqlite3_result_int64(sctx->context, val);
1335 }