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
35struct apr_dbd_transaction_t {
36    int mode;
37    int errnum;
38    apr_dbd_t *handle;
39};
40
41struct 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
48typedef struct {
49    char *name;
50    char *value;
51    int size;
52    int type;
53} apr_dbd_column_t;
54
55struct 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
63struct 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
74struct 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
84static 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
178static 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
206static 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
215static 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
242static 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
254static 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
333static const char *dbd_sqlite3_error(apr_dbd_t *sql, int n)
334{
335    return sqlite3_errmsg(sql->conn);
336}
337
338static 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
361static 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
396static apr_status_t free_mem(void *data)
397{
398    sqlite3_free(data);
399    return APR_SUCCESS;
400}
401
402static 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
411static 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
446static 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
480static 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
510static 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
529static 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
560static 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
581static 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
660static 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
690static 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
710static 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
741static 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
762static 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
779static 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
798static 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
806static 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
815static 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
840static 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
854static 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
860static int dbd_sqlite3_select_db(apr_pool_t *pool, apr_dbd_t *handle,
861                                 const char *name)
862{
863    return APR_ENOTIMPL;
864}
865
866static void *dbd_sqlite3_native(apr_dbd_t *handle)
867{
868    return handle->conn;
869}
870
871static int dbd_sqlite3_num_cols(apr_dbd_results_t *res)
872{
873    return res->sz;
874}
875
876static int dbd_sqlite3_num_tuples(apr_dbd_results_t *res)
877{
878    return res->tuples;
879}
880
881APU_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
915