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
dbd_sqlite3_select_internal(apr_pool_t * pool,apr_dbd_t * sql,apr_dbd_results_t ** results,sqlite3_stmt * stmt,int seek)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
dbd_sqlite3_select(apr_pool_t * pool,apr_dbd_t * sql,apr_dbd_results_t ** results,const char * query,int seek)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
dbd_sqlite3_get_name(const apr_dbd_results_t * res,int n)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
dbd_sqlite3_get_row(apr_pool_t * pool,apr_dbd_results_t * res,apr_dbd_row_t ** rowp,int rownum)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
dbd_sqlite3_get_entry(const apr_dbd_row_t * row,int n)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
dbd_sqlite3_datum_get(const apr_dbd_row_t * row,int n,apr_dbd_type_e type,void * data)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
dbd_sqlite3_error(apr_dbd_t * sql,int n)333 static const char *dbd_sqlite3_error(apr_dbd_t *sql, int n)
334 {
335 return sqlite3_errmsg(sql->conn);
336 }
337
dbd_sqlite3_query_internal(apr_dbd_t * sql,sqlite3_stmt * stmt,int * nrows)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
dbd_sqlite3_query(apr_dbd_t * sql,int * nrows,const char * query)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
free_mem(void * data)396 static apr_status_t free_mem(void *data)
397 {
398 sqlite3_free(data);
399 return APR_SUCCESS;
400 }
401
dbd_sqlite3_escape(apr_pool_t * pool,const char * arg,apr_dbd_t * sql)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
dbd_sqlite3_prepare(apr_pool_t * pool,apr_dbd_t * sql,const char * query,const char * label,int nargs,int nvals,apr_dbd_type_e * types,apr_dbd_prepared_t ** statement)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
dbd_sqlite3_bind(apr_dbd_prepared_t * statement,const char ** values)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
dbd_sqlite3_pquery(apr_pool_t * pool,apr_dbd_t * sql,int * nrows,apr_dbd_prepared_t * statement,const char ** values)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
dbd_sqlite3_pvquery(apr_pool_t * pool,apr_dbd_t * sql,int * nrows,apr_dbd_prepared_t * statement,va_list args)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
dbd_sqlite3_pselect(apr_pool_t * pool,apr_dbd_t * sql,apr_dbd_results_t ** results,apr_dbd_prepared_t * statement,int seek,const char ** values)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
dbd_sqlite3_pvselect(apr_pool_t * pool,apr_dbd_t * sql,apr_dbd_results_t ** results,apr_dbd_prepared_t * statement,int seek,va_list args)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
dbd_sqlite3_bbind(apr_dbd_prepared_t * statement,const void ** values)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
dbd_sqlite3_pbquery(apr_pool_t * pool,apr_dbd_t * sql,int * nrows,apr_dbd_prepared_t * statement,const void ** values)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
dbd_sqlite3_pvbquery(apr_pool_t * pool,apr_dbd_t * sql,int * nrows,apr_dbd_prepared_t * statement,va_list args)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
dbd_sqlite3_pbselect(apr_pool_t * pool,apr_dbd_t * sql,apr_dbd_results_t ** results,apr_dbd_prepared_t * statement,int seek,const void ** values)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
dbd_sqlite3_pvbselect(apr_pool_t * pool,apr_dbd_t * sql,apr_dbd_results_t ** results,apr_dbd_prepared_t * statement,int seek,va_list args)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
dbd_sqlite3_start_transaction(apr_pool_t * pool,apr_dbd_t * handle,apr_dbd_transaction_t ** trans)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
dbd_sqlite3_end_transaction(apr_dbd_transaction_t * trans)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
dbd_sqlite3_transaction_mode_get(apr_dbd_transaction_t * trans)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
dbd_sqlite3_transaction_mode_set(apr_dbd_transaction_t * trans,int mode)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
dbd_sqlite3_open(apr_pool_t * pool,const char * params,const char ** error)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
dbd_sqlite3_close(apr_dbd_t * handle)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
dbd_sqlite3_check_conn(apr_pool_t * pool,apr_dbd_t * handle)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
dbd_sqlite3_select_db(apr_pool_t * pool,apr_dbd_t * handle,const char * name)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
dbd_sqlite3_native(apr_dbd_t * handle)866 static void *dbd_sqlite3_native(apr_dbd_t *handle)
867 {
868 return handle->conn;
869 }
870
dbd_sqlite3_num_cols(apr_dbd_results_t * res)871 static int dbd_sqlite3_num_cols(apr_dbd_results_t *res)
872 {
873 return res->sz;
874 }
875
dbd_sqlite3_num_tuples(apr_dbd_results_t * res)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
915