]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/apr-util/dbd/apr_dbd_sqlite3.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / apr-util / dbd / apr_dbd_sqlite3.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "apu.h"
18
19 #if APU_HAVE_SQLITE3
20
21 #include <ctype.h>
22 #include <stdlib.h>
23
24 #include <sqlite3.h>
25
26 #include "apr_strings.h"
27 #include "apr_time.h"
28 #include "apr_buckets.h"
29
30 #include "apr_dbd_internal.h"
31
32 #define MAX_RETRY_COUNT 15
33 #define MAX_RETRY_SLEEP 100000
34
35 struct apr_dbd_transaction_t {
36     int mode;
37     int errnum;
38     apr_dbd_t *handle;
39 };
40
41 struct apr_dbd_t {
42     sqlite3 *conn;
43     apr_dbd_transaction_t *trans;
44     apr_pool_t *pool;
45     apr_dbd_prepared_t *prep;
46 };
47
48 typedef struct {
49     char *name;
50     char *value;
51     int size;
52     int type;
53 } apr_dbd_column_t;
54
55 struct apr_dbd_row_t {
56     apr_dbd_results_t *res;
57     apr_dbd_column_t **columns;
58     apr_dbd_row_t *next_row;
59     int columnCount;
60     int rownum;
61 };
62
63 struct apr_dbd_results_t {
64     int random;
65     sqlite3 *handle;
66     sqlite3_stmt *stmt;
67     apr_dbd_row_t *next_row;
68     size_t sz;
69     int tuples;
70     char **col_names;
71     apr_pool_t *pool;
72 };
73
74 struct apr_dbd_prepared_t {
75     sqlite3_stmt *stmt;
76     apr_dbd_prepared_t *next;
77     int nargs;
78     int nvals;
79     apr_dbd_type_e *types;
80 };
81
82 #define dbd_sqlite3_is_success(x) (((x) == SQLITE_DONE) || ((x) == SQLITE_OK))
83
84 static int dbd_sqlite3_select_internal(apr_pool_t *pool,
85                                        apr_dbd_t *sql,
86                                        apr_dbd_results_t **results,
87                                        sqlite3_stmt *stmt, int seek)
88 {
89     int ret, retry_count = 0, column_count;
90     size_t i, num_tuples = 0;
91     int increment = 0;
92     apr_dbd_row_t *row = NULL;
93     apr_dbd_row_t *lastrow = NULL;
94     apr_dbd_column_t *column;
95     char *hold = NULL;
96
97     column_count = sqlite3_column_count(stmt);
98     if (!*results) {
99         *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
100     }
101     (*results)->stmt = stmt;
102     (*results)->sz = column_count;
103     (*results)->random = seek;
104     (*results)->next_row = 0;
105     (*results)->tuples = 0;
106     (*results)->col_names = apr_pcalloc(pool, column_count * sizeof(char *));
107     (*results)->pool = pool;
108     do {
109         ret = sqlite3_step(stmt);
110         if (ret == SQLITE_BUSY) {
111             if (retry_count++ > MAX_RETRY_COUNT) {
112                 ret = SQLITE_ERROR;
113             } else {
114                 apr_dbd_mutex_unlock();
115                 apr_sleep(MAX_RETRY_SLEEP);
116                 apr_dbd_mutex_lock();
117             }
118         } else if (ret == SQLITE_ROW) {
119             int length;
120             row = apr_palloc(pool, sizeof(apr_dbd_row_t));
121             row->res = *results;
122             increment = sizeof(apr_dbd_column_t *);
123             length = increment * (*results)->sz;
124             row->columns = apr_palloc(pool, length);
125             row->columnCount = column_count;
126             for (i = 0; i < (*results)->sz; i++) {
127                 column = apr_palloc(pool, sizeof(apr_dbd_column_t));
128                 row->columns[i] = column;
129                 /* copy column name once only */
130                 if ((*results)->col_names[i] == NULL) {
131                     (*results)->col_names[i] =
132                         apr_pstrdup(pool, sqlite3_column_name(stmt, i));
133                 }
134                 column->name = (*results)->col_names[i];
135                 column->size = sqlite3_column_bytes(stmt, i);
136                 column->type = sqlite3_column_type(stmt, i);
137                 column->value = NULL;
138                 switch (column->type) {
139                 case SQLITE_FLOAT:
140                 case SQLITE_INTEGER:
141                 case SQLITE_TEXT:
142                     hold = (char *) sqlite3_column_text(stmt, i);
143                     if (hold) {
144                         column->value = apr_pstrmemdup(pool, hold,
145                                                        column->size);
146                     }
147                     break;
148                 case SQLITE_BLOB:
149                     hold = (char *) sqlite3_column_blob(stmt, i);
150                     if (hold) {
151                         column->value = apr_pstrmemdup(pool, hold,
152                                                        column->size);
153                     }
154                     break;
155                 case SQLITE_NULL:
156                     break;
157                 }
158             }
159             row->rownum = num_tuples++;
160             row->next_row = 0;
161             (*results)->tuples = num_tuples;
162             if ((*results)->next_row == 0) {
163                 (*results)->next_row = row;
164             }
165             if (lastrow != 0) {
166                 lastrow->next_row = row;
167             }
168             lastrow = row;
169         }
170     } while (ret == SQLITE_ROW || ret == SQLITE_BUSY);
171
172     if (dbd_sqlite3_is_success(ret)) {
173         ret = 0;
174     }
175     return ret;
176 }
177
178 static int dbd_sqlite3_select(apr_pool_t *pool, apr_dbd_t *sql,
179                               apr_dbd_results_t **results, const char *query,
180                               int seek)
181 {
182     sqlite3_stmt *stmt = NULL;
183     const char *tail = NULL;
184     int ret;
185
186     if (sql->trans && sql->trans->errnum) {
187         return sql->trans->errnum;
188     }
189
190     apr_dbd_mutex_lock();
191
192     ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
193     if (dbd_sqlite3_is_success(ret)) {
194         ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek);
195     }
196     sqlite3_finalize(stmt);
197
198     apr_dbd_mutex_unlock();
199
200     if (TXN_NOTICE_ERRORS(sql->trans)) {
201         sql->trans->errnum = ret;
202     }
203     return ret;
204 }
205
206 static const char *dbd_sqlite3_get_name(const apr_dbd_results_t *res, int n)
207 {
208     if ((n < 0) || ((size_t)n >= res->sz)) {
209         return NULL;
210     }
211
212     return res->col_names[n];
213 }
214
215 static int dbd_sqlite3_get_row(apr_pool_t *pool, apr_dbd_results_t *res,
216                                apr_dbd_row_t **rowp, int rownum)
217 {
218     int i = 0;
219
220     if (rownum == -1) {
221         *rowp = res->next_row;
222         if (*rowp == 0)
223             return -1;
224         res->next_row = (*rowp)->next_row;
225         return 0;
226     }
227     if (rownum > res->tuples) {
228         return -1;
229     }
230     rownum--;
231     *rowp = res->next_row;
232     for (; *rowp != 0; i++, *rowp = (*rowp)->next_row) {
233         if (i == rownum) {
234             return 0;
235         }
236     }
237
238     return -1;
239
240 }
241
242 static const char *dbd_sqlite3_get_entry(const apr_dbd_row_t *row, int n)
243 {
244     apr_dbd_column_t *column;
245     const char *value;
246     if ((n < 0) || (n >= row->columnCount)) {
247         return NULL;
248     }
249     column = row->columns[n];
250     value = column->value;
251     return value;
252 }
253
254 static apr_status_t dbd_sqlite3_datum_get(const apr_dbd_row_t *row, int n,
255                                           apr_dbd_type_e type, void *data)
256 {
257     if ((n < 0) || ((size_t)n >= row->res->sz)) {
258       return APR_EGENERAL;
259     }
260
261     if (row->columns[n]->type == SQLITE_NULL) {
262         return APR_ENOENT;
263     }
264
265     switch (type) {
266     case APR_DBD_TYPE_TINY:
267         *(char*)data = atoi(row->columns[n]->value);
268         break;
269     case APR_DBD_TYPE_UTINY:
270         *(unsigned char*)data = atoi(row->columns[n]->value);
271         break;
272     case APR_DBD_TYPE_SHORT:
273         *(short*)data = atoi(row->columns[n]->value);
274         break;
275     case APR_DBD_TYPE_USHORT:
276         *(unsigned short*)data = atoi(row->columns[n]->value);
277         break;
278     case APR_DBD_TYPE_INT:
279         *(int*)data = atoi(row->columns[n]->value);
280         break;
281     case APR_DBD_TYPE_UINT:
282         *(unsigned int*)data = atoi(row->columns[n]->value);
283         break;
284     case APR_DBD_TYPE_LONG:
285         *(long*)data = atol(row->columns[n]->value);
286         break;
287     case APR_DBD_TYPE_ULONG:
288         *(unsigned long*)data = atol(row->columns[n]->value);
289         break;
290     case APR_DBD_TYPE_LONGLONG:
291         *(apr_int64_t*)data = apr_atoi64(row->columns[n]->value);
292         break;
293     case APR_DBD_TYPE_ULONGLONG:
294         *(apr_uint64_t*)data = apr_atoi64(row->columns[n]->value);
295         break;
296     case APR_DBD_TYPE_FLOAT:
297         *(float*)data = (float)atof(row->columns[n]->value);
298         break;
299     case APR_DBD_TYPE_DOUBLE:
300         *(double*)data = atof(row->columns[n]->value);
301         break;
302     case APR_DBD_TYPE_STRING:
303     case APR_DBD_TYPE_TEXT:
304     case APR_DBD_TYPE_TIME:
305     case APR_DBD_TYPE_DATE:
306     case APR_DBD_TYPE_DATETIME:
307     case APR_DBD_TYPE_TIMESTAMP:
308     case APR_DBD_TYPE_ZTIMESTAMP:
309         *(char**)data = row->columns[n]->value;
310         break;
311     case APR_DBD_TYPE_BLOB:
312     case APR_DBD_TYPE_CLOB:
313         {
314         apr_bucket *e;
315         apr_bucket_brigade *b = (apr_bucket_brigade*)data;
316
317         e = apr_bucket_pool_create(row->columns[n]->value,
318                                    row->columns[n]->size,
319                                    row->res->pool, b->bucket_alloc);
320         APR_BRIGADE_INSERT_TAIL(b, e);
321         }
322         break;
323     case APR_DBD_TYPE_NULL:
324         *(void**)data = NULL;
325         break;
326     default:
327         return APR_EGENERAL;
328     }
329
330     return APR_SUCCESS;
331 }
332
333 static const char *dbd_sqlite3_error(apr_dbd_t *sql, int n)
334 {
335     return sqlite3_errmsg(sql->conn);
336 }
337
338 static int dbd_sqlite3_query_internal(apr_dbd_t *sql, sqlite3_stmt *stmt,
339                                       int *nrows)
340 {
341     int ret = -1, retry_count = 0;
342
343     while(retry_count++ <= MAX_RETRY_COUNT) {
344         ret = sqlite3_step(stmt);
345         if (ret != SQLITE_BUSY)
346             break;
347
348         apr_dbd_mutex_unlock();
349         apr_sleep(MAX_RETRY_SLEEP);
350         apr_dbd_mutex_lock();
351     }
352
353     *nrows = sqlite3_changes(sql->conn);
354
355     if (dbd_sqlite3_is_success(ret)) {
356         ret = 0;
357     }
358     return ret;
359 }
360
361 static int dbd_sqlite3_query(apr_dbd_t *sql, int *nrows, const char *query)
362 {
363     sqlite3_stmt *stmt = NULL;
364     const char *tail = NULL;
365     int ret = -1, length = 0;
366
367     if (sql->trans && sql->trans->errnum) {
368         return sql->trans->errnum;
369     }
370
371     length = strlen(query);
372     apr_dbd_mutex_lock();
373
374     do {
375         ret = sqlite3_prepare(sql->conn, query, length, &stmt, &tail);
376         if (ret != SQLITE_OK) {
377             sqlite3_finalize(stmt);
378             break;
379         }
380
381         ret = dbd_sqlite3_query_internal(sql, stmt, nrows);
382
383         sqlite3_finalize(stmt);
384         length -= (tail - query);
385         query = tail;
386     } while (length > 0);
387
388     apr_dbd_mutex_unlock();
389
390     if (TXN_NOTICE_ERRORS(sql->trans)) {
391         sql->trans->errnum = ret;
392     }
393     return ret;
394 }
395
396 static apr_status_t free_mem(void *data)
397 {
398     sqlite3_free(data);
399     return APR_SUCCESS;
400 }
401
402 static const char *dbd_sqlite3_escape(apr_pool_t *pool, const char *arg,
403                                       apr_dbd_t *sql)
404 {
405     char *ret = sqlite3_mprintf("%q", arg);
406     apr_pool_cleanup_register(pool, ret, free_mem,
407                               apr_pool_cleanup_null);
408     return ret;
409 }
410
411 static int dbd_sqlite3_prepare(apr_pool_t *pool, apr_dbd_t *sql,
412                                const char *query, const char *label,
413                                int nargs, int nvals, apr_dbd_type_e *types,
414                                apr_dbd_prepared_t **statement)
415 {
416     sqlite3_stmt *stmt;
417     const char *tail = NULL;
418     int ret;
419
420     apr_dbd_mutex_lock();
421
422     ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
423     if (ret == SQLITE_OK) {
424         apr_dbd_prepared_t *prep; 
425
426         prep = apr_pcalloc(sql->pool, sizeof(*prep));
427         prep->stmt = stmt;
428         prep->next = sql->prep;
429         prep->nargs = nargs;
430         prep->nvals = nvals;
431         prep->types = types;
432
433         /* link new statement to the handle */
434         sql->prep = prep;
435
436         *statement = prep;
437     } else {
438         sqlite3_finalize(stmt);
439     }
440    
441     apr_dbd_mutex_unlock();
442
443     return ret;
444 }
445
446 static void dbd_sqlite3_bind(apr_dbd_prepared_t *statement, const char **values)
447 {
448     sqlite3_stmt *stmt = statement->stmt;
449     int i, j;
450
451     for (i = 0, j = 0; i < statement->nargs; i++, j++) {
452         if (values[j] == NULL) {
453             sqlite3_bind_null(stmt, i + 1);
454         }
455         else {
456             switch (statement->types[i]) {
457             case APR_DBD_TYPE_BLOB:
458             case APR_DBD_TYPE_CLOB:
459                 {
460                 char *data = (char *)values[j];
461                 int size = atoi((char*)values[++j]);
462
463                 /* skip table and column */
464                 j += 2;
465
466                 sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC);
467                 }
468                 break;
469             default:
470                 sqlite3_bind_text(stmt, i + 1, values[j],
471                                   strlen(values[j]), SQLITE_STATIC);
472                 break;
473             }
474         }
475     }
476
477     return;
478 }
479
480 static int dbd_sqlite3_pquery(apr_pool_t *pool, apr_dbd_t *sql,
481                               int *nrows, apr_dbd_prepared_t *statement,
482                               const char **values)
483 {
484     sqlite3_stmt *stmt = statement->stmt;
485     int ret = -1;
486
487     if (sql->trans && sql->trans->errnum) {
488         return sql->trans->errnum;
489     }
490
491     apr_dbd_mutex_lock();
492
493     ret = sqlite3_reset(stmt);
494     if (ret == SQLITE_OK) {
495         dbd_sqlite3_bind(statement, values);
496
497         ret = dbd_sqlite3_query_internal(sql, stmt, nrows);
498
499         sqlite3_reset(stmt);
500     }
501
502     apr_dbd_mutex_unlock();
503
504     if (TXN_NOTICE_ERRORS(sql->trans)) {
505         sql->trans->errnum = ret;
506     }
507     return ret;
508 }
509
510 static int dbd_sqlite3_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows,
511                                apr_dbd_prepared_t *statement, va_list args)
512 {
513     const char **values;
514     int i;
515
516     if (sql->trans && sql->trans->errnum) {
517         return sql->trans->errnum;
518     }
519
520     values = apr_palloc(pool, sizeof(*values) * statement->nvals);
521
522     for (i = 0; i < statement->nvals; i++) {
523         values[i] = va_arg(args, const char*);
524     }
525
526     return dbd_sqlite3_pquery(pool, sql, nrows, statement, values);
527 }
528
529 static int dbd_sqlite3_pselect(apr_pool_t *pool, apr_dbd_t *sql,
530                                apr_dbd_results_t **results,
531                                apr_dbd_prepared_t *statement, int seek,
532                                const char **values)
533 {
534     sqlite3_stmt *stmt = statement->stmt;
535     int ret;
536
537     if (sql->trans && sql->trans->errnum) {
538         return sql->trans->errnum;
539     }
540
541     apr_dbd_mutex_lock();
542
543     ret = sqlite3_reset(stmt);
544     if (ret == SQLITE_OK) {
545         dbd_sqlite3_bind(statement, values);
546
547         ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek);
548
549         sqlite3_reset(stmt);
550     }
551
552     apr_dbd_mutex_unlock();
553
554     if (TXN_NOTICE_ERRORS(sql->trans)) {
555         sql->trans->errnum = ret;
556     }
557     return ret;
558 }
559
560 static int dbd_sqlite3_pvselect(apr_pool_t *pool, apr_dbd_t *sql,
561                                 apr_dbd_results_t **results,
562                                 apr_dbd_prepared_t *statement, int seek,
563                                 va_list args)
564 {
565     const char **values;
566     int i;
567
568     if (sql->trans && sql->trans->errnum) {
569         return sql->trans->errnum;
570     }
571
572     values = apr_palloc(pool, sizeof(*values) * statement->nvals);
573
574     for (i = 0; i < statement->nvals; i++) {
575         values[i] = va_arg(args, const char*);
576     }
577
578     return dbd_sqlite3_pselect(pool, sql, results, statement, seek, values);
579 }
580
581 static void dbd_sqlite3_bbind(apr_dbd_prepared_t * statement,
582                               const void **values)
583 {
584     sqlite3_stmt *stmt = statement->stmt;
585     int i, j;
586     apr_dbd_type_e type;
587
588     for (i = 0, j = 0; i < statement->nargs; i++, j++) {
589         type = (values[j] == NULL ? APR_DBD_TYPE_NULL : statement->types[i]);
590
591         switch (type) {
592         case APR_DBD_TYPE_TINY:
593             sqlite3_bind_int(stmt, i + 1, *(char*)values[j]);
594             break;
595         case APR_DBD_TYPE_UTINY:
596             sqlite3_bind_int(stmt, i + 1, *(unsigned char*)values[j]);
597             break;
598         case APR_DBD_TYPE_SHORT:
599             sqlite3_bind_int(stmt, i + 1, *(short*)values[j]);
600             break;
601         case APR_DBD_TYPE_USHORT:
602             sqlite3_bind_int(stmt, i + 1, *(unsigned short*)values[j]);
603             break;
604         case APR_DBD_TYPE_INT:
605             sqlite3_bind_int(stmt, i + 1, *(int*)values[j]);
606             break;
607         case APR_DBD_TYPE_UINT:
608             sqlite3_bind_int(stmt, i + 1, *(unsigned int*)values[j]);
609             break;
610         case APR_DBD_TYPE_LONG:
611             sqlite3_bind_int64(stmt, i + 1, *(long*)values[j]);
612             break;
613         case APR_DBD_TYPE_ULONG:
614             sqlite3_bind_int64(stmt, i + 1, *(unsigned long*)values[j]);
615             break;
616         case APR_DBD_TYPE_LONGLONG:
617             sqlite3_bind_int64(stmt, i + 1, *(apr_int64_t*)values[j]);
618             break;
619         case APR_DBD_TYPE_ULONGLONG:
620             sqlite3_bind_int64(stmt, i + 1, *(apr_uint64_t*)values[j]);
621             break;
622         case APR_DBD_TYPE_FLOAT:
623             sqlite3_bind_double(stmt, i + 1, *(float*)values[j]);
624             break;
625         case APR_DBD_TYPE_DOUBLE:
626             sqlite3_bind_double(stmt, i + 1, *(double*)values[j]);
627             break;
628         case APR_DBD_TYPE_STRING:
629         case APR_DBD_TYPE_TEXT:
630         case APR_DBD_TYPE_TIME:
631         case APR_DBD_TYPE_DATE:
632         case APR_DBD_TYPE_DATETIME:
633         case APR_DBD_TYPE_TIMESTAMP:
634         case APR_DBD_TYPE_ZTIMESTAMP:
635             sqlite3_bind_text(stmt, i + 1, values[j], strlen(values[j]),
636                               SQLITE_STATIC);
637             break;
638         case APR_DBD_TYPE_BLOB:
639         case APR_DBD_TYPE_CLOB:
640             {
641             char *data = (char*)values[j];
642             apr_size_t size = *(apr_size_t*)values[++j];
643
644             sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC);
645
646             /* skip table and column */
647             j += 2;
648             }
649             break;
650         case APR_DBD_TYPE_NULL:
651         default:
652             sqlite3_bind_null(stmt, i + 1);
653             break;
654         }
655     }
656
657     return;
658 }
659
660 static int dbd_sqlite3_pbquery(apr_pool_t * pool, apr_dbd_t * sql,
661                                int *nrows, apr_dbd_prepared_t * statement,
662                                const void **values)
663 {
664     sqlite3_stmt *stmt = statement->stmt;
665     int ret = -1;
666
667     if (sql->trans && sql->trans->errnum) {
668         return sql->trans->errnum;
669     }
670
671     apr_dbd_mutex_lock();
672
673     ret = sqlite3_reset(stmt);
674     if (ret == SQLITE_OK) {
675         dbd_sqlite3_bbind(statement, values);
676
677         ret = dbd_sqlite3_query_internal(sql, stmt, nrows);
678
679         sqlite3_reset(stmt);
680     }
681
682     apr_dbd_mutex_unlock();
683
684     if (TXN_NOTICE_ERRORS(sql->trans)) {
685         sql->trans->errnum = ret;
686     }
687     return ret;
688 }
689
690 static int dbd_sqlite3_pvbquery(apr_pool_t * pool, apr_dbd_t * sql,
691                                 int *nrows, apr_dbd_prepared_t * statement,
692                                 va_list args)
693 {
694     const void **values;
695     int i;
696
697     if (sql->trans && sql->trans->errnum) {
698         return sql->trans->errnum;
699     }
700
701     values = apr_palloc(pool, sizeof(*values) * statement->nvals);
702
703     for (i = 0; i < statement->nvals; i++) {
704         values[i] = va_arg(args, const void*);
705     }
706
707     return dbd_sqlite3_pbquery(pool, sql, nrows, statement, values);
708 }
709
710 static int dbd_sqlite3_pbselect(apr_pool_t * pool, apr_dbd_t * sql,
711                                 apr_dbd_results_t ** results,
712                                 apr_dbd_prepared_t * statement,
713                                 int seek, const void **values)
714 {
715     sqlite3_stmt *stmt = statement->stmt;
716     int ret;
717
718     if (sql->trans && sql->trans->errnum) {
719         return sql->trans->errnum;
720     }
721
722     apr_dbd_mutex_lock();
723
724     ret = sqlite3_reset(stmt);
725     if (ret == SQLITE_OK) {
726         dbd_sqlite3_bbind(statement, values);
727
728         ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek);
729
730         sqlite3_reset(stmt);
731     }
732
733     apr_dbd_mutex_unlock();
734
735     if (TXN_NOTICE_ERRORS(sql->trans)) {
736         sql->trans->errnum = ret;
737     }
738     return ret;
739 }
740
741 static int dbd_sqlite3_pvbselect(apr_pool_t * pool, apr_dbd_t * sql,
742                                  apr_dbd_results_t ** results,
743                                  apr_dbd_prepared_t * statement, int seek,
744                                  va_list args)
745 {
746     const void **values;
747     int i;
748
749     if (sql->trans && sql->trans->errnum) {
750         return sql->trans->errnum;
751     }
752
753     values = apr_palloc(pool, sizeof(*values) * statement->nvals);
754
755     for (i = 0; i < statement->nvals; i++) {
756         values[i] = va_arg(args, const void*);
757     }
758
759     return dbd_sqlite3_pbselect(pool, sql, results, statement, seek, values);
760 }
761
762 static int dbd_sqlite3_start_transaction(apr_pool_t *pool,
763                                          apr_dbd_t *handle,
764                                          apr_dbd_transaction_t **trans)
765 {
766     int ret = 0;
767     int nrows = 0;
768
769     ret = dbd_sqlite3_query(handle, &nrows, "BEGIN IMMEDIATE");
770     if (!*trans) {
771         *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
772         (*trans)->handle = handle;
773         handle->trans = *trans;
774     }
775
776     return ret;
777 }
778
779 static int dbd_sqlite3_end_transaction(apr_dbd_transaction_t *trans)
780 {
781     int ret = -1; /* ending transaction that was never started is an error */
782     int nrows = 0;
783
784     if (trans) {
785         /* rollback on error or explicit rollback request */
786         if (trans->errnum || TXN_DO_ROLLBACK(trans)) {
787             trans->errnum = 0;
788             ret = dbd_sqlite3_query(trans->handle, &nrows, "ROLLBACK");
789         } else {
790             ret = dbd_sqlite3_query(trans->handle, &nrows, "COMMIT");
791         }
792         trans->handle->trans = NULL;
793     }
794
795     return ret;
796 }
797
798 static int dbd_sqlite3_transaction_mode_get(apr_dbd_transaction_t *trans)
799 {
800     if (!trans)
801         return APR_DBD_TRANSACTION_COMMIT;
802
803     return trans->mode;
804 }
805
806 static int dbd_sqlite3_transaction_mode_set(apr_dbd_transaction_t *trans,
807                                             int mode)
808 {
809     if (!trans)
810         return APR_DBD_TRANSACTION_COMMIT;
811
812     return trans->mode = (mode & TXN_MODE_BITS);
813 }
814
815 static apr_dbd_t *dbd_sqlite3_open(apr_pool_t *pool, const char *params,
816                                    const char **error)
817 {
818     apr_dbd_t *sql = NULL;
819     sqlite3 *conn = NULL;
820     int sqlres;
821     if (!params)
822         return NULL;
823     sqlres = sqlite3_open(params, &conn);
824     if (sqlres != SQLITE_OK) {
825         if (error) {
826             *error = apr_pstrdup(pool, sqlite3_errmsg(conn));
827         }
828         sqlite3_close(conn);
829         return NULL;
830     }
831     /* should we register rand or power functions to the sqlite VM? */
832     sql = apr_pcalloc(pool, sizeof(*sql));
833     sql->conn = conn;
834     sql->pool = pool;
835     sql->trans = NULL;
836
837     return sql;
838 }
839
840 static apr_status_t dbd_sqlite3_close(apr_dbd_t *handle)
841 {
842     apr_dbd_prepared_t *prep = handle->prep;
843
844     /* finalize all prepared statements, or we'll get SQLITE_BUSY on close */
845     while (prep) {
846         sqlite3_finalize(prep->stmt);
847         prep = prep->next;
848     }
849
850     sqlite3_close(handle->conn);
851     return APR_SUCCESS;
852 }
853
854 static apr_status_t dbd_sqlite3_check_conn(apr_pool_t *pool,
855                                            apr_dbd_t *handle)
856 {
857     return (handle->conn != NULL) ? APR_SUCCESS : APR_EGENERAL;
858 }
859
860 static int dbd_sqlite3_select_db(apr_pool_t *pool, apr_dbd_t *handle,
861                                  const char *name)
862 {
863     return APR_ENOTIMPL;
864 }
865
866 static void *dbd_sqlite3_native(apr_dbd_t *handle)
867 {
868     return handle->conn;
869 }
870
871 static int dbd_sqlite3_num_cols(apr_dbd_results_t *res)
872 {
873     return res->sz;
874 }
875
876 static int dbd_sqlite3_num_tuples(apr_dbd_results_t *res)
877 {
878     return res->tuples;
879 }
880
881 APU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite3_driver = {
882     "sqlite3",
883     NULL,
884     dbd_sqlite3_native,
885     dbd_sqlite3_open,
886     dbd_sqlite3_check_conn,
887     dbd_sqlite3_close,
888     dbd_sqlite3_select_db,
889     dbd_sqlite3_start_transaction,
890     dbd_sqlite3_end_transaction,
891     dbd_sqlite3_query,
892     dbd_sqlite3_select,
893     dbd_sqlite3_num_cols,
894     dbd_sqlite3_num_tuples,
895     dbd_sqlite3_get_row,
896     dbd_sqlite3_get_entry,
897     dbd_sqlite3_error,
898     dbd_sqlite3_escape,
899     dbd_sqlite3_prepare,
900     dbd_sqlite3_pvquery,
901     dbd_sqlite3_pvselect,
902     dbd_sqlite3_pquery,
903     dbd_sqlite3_pselect,
904     dbd_sqlite3_get_name,
905     dbd_sqlite3_transaction_mode_get,
906     dbd_sqlite3_transaction_mode_set,
907     "?",
908     dbd_sqlite3_pvbquery,
909     dbd_sqlite3_pvbselect,
910     dbd_sqlite3_pbquery,
911     dbd_sqlite3_pbselect,
912     dbd_sqlite3_datum_get
913 };
914 #endif