Apache HTTPD
apr_dbd_sqlite3.c
Go to the documentation of this file.
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
36 int mode;
37 int errnum;
39};
40
41struct apr_dbd_t {
42 sqlite3 *conn;
46};
47
48typedef struct {
49 char *name;
50 char *value;
51 int size;
52 int type;
54
55struct apr_dbd_row_t {
59 int columnCount;
60 int rownum;
61};
62
63struct apr_dbd_results_t {
64 int random;
68 size_t sz;
69 int tuples;
70 char **col_names;
72};
73
74struct apr_dbd_prepared_t {
77 int nargs;
78 int nvals;
80};
81
82#define dbd_sqlite3_is_success(x) (((x) == SQLITE_DONE) || ((x) == SQLITE_OK))
83
86 apr_dbd_results_t **results,
88{
90 size_t i, num_tuples = 0;
91 int increment = 0;
95 char *hold = NULL;
96
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 {
110 if (ret == SQLITE_BUSY) {
113 } else {
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++) {
128 row->columns[i] = column;
129 /* copy column name once only */
130 if ((*results)->col_names[i] == NULL) {
131 (*results)->col_names[i] =
133 }
134 column->name = (*results)->col_names[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
173 ret = 0;
174 }
175 return ret;
176}
177
179 apr_dbd_results_t **results, const char *query,
180 int seek)
181{
183 const char *tail = NULL;
184 int ret;
185
186 if (sql->trans && sql->trans->errnum) {
187 return sql->trans->errnum;
188 }
189
191
192 ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
195 }
197
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
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{
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
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) {
267 *(char*)data = atoi(row->columns[n]->value);
268 break;
270 *(unsigned char*)data = atoi(row->columns[n]->value);
271 break;
273 *(short*)data = atoi(row->columns[n]->value);
274 break;
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;
282 *(unsigned int*)data = atoi(row->columns[n]->value);
283 break;
285 *(long*)data = atol(row->columns[n]->value);
286 break;
288 *(unsigned long*)data = atol(row->columns[n]->value);
289 break;
291 *(apr_int64_t*)data = apr_atoi64(row->columns[n]->value);
292 break;
294 *(apr_uint64_t*)data = apr_atoi64(row->columns[n]->value);
295 break;
297 *(float*)data = (float)atof(row->columns[n]->value);
298 break;
300 *(double*)data = atof(row->columns[n]->value);
301 break;
309 *(char**)data = row->columns[n]->value;
310 break;
313 {
314 apr_bucket *e;
316
317 e = apr_bucket_pool_create(row->columns[n]->value,
318 row->columns[n]->size,
319 row->res->pool, b->bucket_alloc);
321 }
322 break;
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
339 int *nrows)
340{
341 int ret = -1, retry_count = 0;
342
343 while(retry_count++ <= MAX_RETRY_COUNT) {
345 if (ret != SQLITE_BUSY)
346 break;
347
351 }
352
353 *nrows = sqlite3_changes(sql->conn);
354
356 ret = 0;
357 }
358 return ret;
359}
360
361static int dbd_sqlite3_query(apr_dbd_t *sql, int *nrows, const char *query)
362{
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);
373
374 do {
375 ret = sqlite3_prepare(sql->conn, query, length, &stmt, &tail);
376 if (ret != SQLITE_OK) {
378 break;
379 }
380
382
384 length -= (tail - query);
385 query = tail;
386 } while (length > 0);
387
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{
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);
408 return ret;
409}
410
412 const char *query, const char *label,
413 int nargs, int nvals, apr_dbd_type_e *types,
415{
417 const char *tail = NULL;
418 int ret;
419
421
422 ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
423 if (ret == SQLITE_OK) {
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 {
439 }
440
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) {
454 }
455 else {
456 switch (statement->types[i]) {
459 {
460 char *data = (char *)values[j];
461 int size = atoi((char*)values[++j]);
462
463 /* skip table and column */
464 j += 2;
465
467 }
468 break;
469 default:
471 strlen(values[j]), SQLITE_STATIC);
472 break;
473 }
474 }
475 }
476
477 return;
478}
479
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
492
494 if (ret == SQLITE_OK) {
496
498
500 }
501
503
504 if (TXN_NOTICE_ERRORS(sql->trans)) {
505 sql->trans->errnum = ret;
506 }
507 return ret;
508}
509
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
527}
528
530 apr_dbd_results_t **results,
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
542
544 if (ret == SQLITE_OK) {
546
548
550 }
551
553
554 if (TXN_NOTICE_ERRORS(sql->trans)) {
555 sql->trans->errnum = ret;
556 }
557 return ret;
558}
559
561 apr_dbd_results_t **results,
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
582 const void **values)
583{
584 sqlite3_stmt *stmt = statement->stmt;
585 int i, j;
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) {
593 sqlite3_bind_int(stmt, i + 1, *(char*)values[j]);
594 break;
596 sqlite3_bind_int(stmt, i + 1, *(unsigned char*)values[j]);
597 break;
599 sqlite3_bind_int(stmt, i + 1, *(short*)values[j]);
600 break;
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;
608 sqlite3_bind_int(stmt, i + 1, *(unsigned int*)values[j]);
609 break;
611 sqlite3_bind_int64(stmt, i + 1, *(long*)values[j]);
612 break;
614 sqlite3_bind_int64(stmt, i + 1, *(unsigned long*)values[j]);
615 break;
618 break;
621 break;
623 sqlite3_bind_double(stmt, i + 1, *(float*)values[j]);
624 break;
626 sqlite3_bind_double(stmt, i + 1, *(double*)values[j]);
627 break;
635 sqlite3_bind_text(stmt, i + 1, values[j], strlen(values[j]),
637 break;
640 {
641 char *data = (char*)values[j];
643
645
646 /* skip table and column */
647 j += 2;
648 }
649 break;
651 default:
653 break;
654 }
655 }
656
657 return;
658}
659
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
672
674 if (ret == SQLITE_OK) {
676
678
680 }
681
683
684 if (TXN_NOTICE_ERRORS(sql->trans)) {
685 sql->trans->errnum = ret;
686 }
687 return ret;
688}
689
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
708}
709
711 apr_dbd_results_t ** results,
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
723
725 if (ret == SQLITE_OK) {
727
729
731 }
732
734
735 if (TXN_NOTICE_ERRORS(sql->trans)) {
736 sql->trans->errnum = ret;
737 }
738 return ret;
739}
740
742 apr_dbd_results_t ** results,
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
765{
766 int ret = 0;
767 int nrows = 0;
768
769 ret = dbd_sqlite3_query(handle, &nrows, "BEGIN IMMEDIATE");
770 if (!*trans) {
772 (*trans)->handle = handle;
773 handle->trans = *trans;
774 }
775
776 return ret;
777}
778
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
799{
800 if (!trans)
802
803 return trans->mode;
804}
805
807 int mode)
808{
809 if (!trans)
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) {
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
841{
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
856{
857 return (handle->conn != NULL) ? APR_SUCCESS : APR_EGENERAL;
858}
859
861 const char *name)
862{
863 return APR_ENOTIMPL;
864}
865
867{
868 return handle->conn;
869}
870
872{
873 return res->sz;
874}
875
877{
878 return res->tuples;
879}
880
882 "sqlite3",
883 NULL,
907 "?",
913};
914#endif
int n
Definition ap_regex.h:278
APR-UTIL Buckets/Bucket Brigades.
#define TXN_NOTICE_ERRORS(t)
#define TXN_MODE_BITS
#define TXN_DO_ROLLBACK(t)
APR Strings library.
APR Time Library.
void const char * arg
Definition http_vhost.h:63
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_ENOENT
Definition apr_errno.h:662
#define APR_BRIGADE_INSERT_TAIL(b, e)
apr_bucket * e
int apr_off_t * length
apr_pool_t apr_dbd_t const char * query
Definition apr_dbd.h:396
apr_dbd_type_e
Definition apr_dbd.h:55
apr_pool_t const char apr_dbd_t const char ** error
Definition apr_dbd.h:143
struct apr_dbd_prepared_t apr_dbd_prepared_t
Definition apr_dbd.h:87
apr_pool_t apr_dbd_t const char const char * label
Definition apr_dbd.h:397
apr_pool_t apr_dbd_t apr_dbd_results_t ** res
Definition apr_dbd.h:287
struct apr_dbd_t apr_dbd_t
Definition apr_dbd.h:83
apr_dbd_t int const char * statement
Definition apr_dbd.h:272
apr_dbd_transaction_t int mode
Definition apr_dbd.h:261
struct apr_dbd_results_t apr_dbd_results_t
Definition apr_dbd.h:85
apr_pool_t const char apr_dbd_t ** handle
Definition apr_dbd.h:142
apr_dbd_t int errnum
Definition apr_dbd.h:353
apr_pool_t apr_dbd_results_t apr_dbd_row_t int rownum
Definition apr_dbd.h:321
apr_pool_t apr_dbd_t int apr_dbd_prepared_t int nargs
Definition apr_dbd.h:414
struct apr_dbd_transaction_t apr_dbd_transaction_t
Definition apr_dbd.h:84
apr_pool_t apr_dbd_results_t apr_dbd_row_t ** row
Definition apr_dbd.h:320
apr_pool_t const char * params
Definition apr_dbd.h:141
apr_dbd_t int * nrows
Definition apr_dbd.h:272
struct apr_dbd_row_t apr_dbd_row_t
Definition apr_dbd.h:86
#define APR_DBD_TRANSACTION_COMMIT
Definition apr_dbd.h:239
@ APR_DBD_TYPE_SHORT
Definition apr_dbd.h:59
@ APR_DBD_TYPE_FLOAT
Definition apr_dbd.h:67
@ APR_DBD_TYPE_TIME
Definition apr_dbd.h:71
@ APR_DBD_TYPE_ULONG
Definition apr_dbd.h:64
@ APR_DBD_TYPE_STRING
Definition apr_dbd.h:69
@ APR_DBD_TYPE_INT
Definition apr_dbd.h:61
@ APR_DBD_TYPE_UINT
Definition apr_dbd.h:62
@ APR_DBD_TYPE_TIMESTAMP
Definition apr_dbd.h:74
@ APR_DBD_TYPE_BLOB
Definition apr_dbd.h:76
@ APR_DBD_TYPE_NULL
Definition apr_dbd.h:78
@ APR_DBD_TYPE_DATETIME
Definition apr_dbd.h:73
@ APR_DBD_TYPE_DOUBLE
Definition apr_dbd.h:68
@ APR_DBD_TYPE_LONGLONG
Definition apr_dbd.h:65
@ APR_DBD_TYPE_UTINY
Definition apr_dbd.h:58
@ APR_DBD_TYPE_DATE
Definition apr_dbd.h:72
@ APR_DBD_TYPE_TINY
Definition apr_dbd.h:57
@ APR_DBD_TYPE_ULONGLONG
Definition apr_dbd.h:66
@ APR_DBD_TYPE_LONG
Definition apr_dbd.h:63
@ APR_DBD_TYPE_CLOB
Definition apr_dbd.h:77
@ APR_DBD_TYPE_TEXT
Definition apr_dbd.h:70
@ APR_DBD_TYPE_ZTIMESTAMP
Definition apr_dbd.h:75
@ APR_DBD_TYPE_USHORT
Definition apr_dbd.h:60
const char apr_hash_t ** values
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
int type
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
void * random
Definition apr_random.h:99
const char const char *const * args
static const char *const types[]
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
static apr_status_t prep(apr_sdbm_t **pdb, const char *dirname, const char *pagname, apr_int32_t flags, apr_fileperms_t perms, apr_pool_t *p)
Definition sdbm.c:86
static const char *const trans[040]
Definition sed1.c:28
char * name