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