Apache HTTPD
apr_dbd_sqlite2.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_SQLITE2
20
21#include <ctype.h>
22#include <stdlib.h>
23
24#include <sqlite.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
33 int mode;
34 int errnum;
36};
37
38struct apr_dbd_t {
39 sqlite *conn;
40 char *errmsg;
42};
43
44struct apr_dbd_results_t {
45 int random;
47 char **res;
48 size_t ntuples;
49 size_t sz;
50 size_t index;
52};
53
54struct apr_dbd_row_t {
55 int n;
56 char **data;
58};
59
60struct apr_dbd_prepared_t {
61 const char *name;
62 int prepared;
63};
64
65#define FREE_ERROR_MSG(dbd) \
66 do { \
67 if(dbd && dbd->errmsg) { \
68 free(dbd->errmsg); \
69 dbd->errmsg = NULL; \
70 } \
71 } while(0);
72
73static apr_status_t free_table(void *data)
74{
76 return APR_SUCCESS;
77}
78
80 apr_dbd_results_t ** results, const char *query,
81 int seek)
82{
83 char **result;
84 int ret = 0;
85 int tuples = 0;
86 int fields = 0;
87
88 if (sql->trans && sql->trans->errnum) {
89 return sql->trans->errnum;
90 }
91
93
95 &sql->errmsg);
96
97 if (ret == SQLITE_OK) {
98 if (!*results) {
99 *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
100 }
101
102 (*results)->res = result;
103 (*results)->ntuples = tuples;
104 (*results)->sz = fields;
105 (*results)->random = seek;
106 (*results)->pool = pool;
107
108 if (tuples > 0)
111
112 ret = 0;
113 }
114 else {
115 if (TXN_NOTICE_ERRORS(sql->trans)) {
116 sql->trans->errnum = ret;
117 }
118 }
119
120 return ret;
121}
122
123static const char *dbd_sqlite_get_name(const apr_dbd_results_t *res, int n)
124{
125 if ((n < 0) || (n >= res->sz)) {
126 return NULL;
127 }
128
129 return res->res[n];
130}
131
133 apr_dbd_row_t ** rowp, int rownum)
134{
136 int sequential = ((rownum >= 0) && res->random) ? 0 : 1;
137
138 if (row == NULL) {
139 row = apr_palloc(pool, sizeof(apr_dbd_row_t));
140 *rowp = row;
141 row->res = res;
142 row->n = sequential ? 0 : rownum - 1;
143 }
144 else {
145 if (sequential) {
146 ++row->n;
147 }
148 else {
149 row->n = rownum - 1;
150 }
151 }
152
153 if (row->n >= res->ntuples) {
154 *rowp = NULL;
156 res->res = NULL;
157 return -1;
158 }
159
160 /* Pointer magic explanation:
161 * The sqlite result is an array such that the first res->sz elements are
162 * the column names and each tuple follows afterwards
163 * ex: (from the sqlite2 documentation)
164 SELECT employee_name, login, host FROM users WHERE login LIKE * 'd%';
165
166 nrow = 2
167 ncolumn = 3
168 result[0] = "employee_name"
169 result[1] = "login"
170 result[2] = "host"
171 result[3] = "dummy"
172 result[4] = "No such user"
173 result[5] = 0
174 result[6] = "D. Richard Hipp"
175 result[7] = "drh"
176 result[8] = "zadok"
177 */
178
179 row->data = res->res + res->sz + (res->sz * row->n);
180
181 return 0;
182}
183
184static const char *dbd_sqlite_get_entry(const apr_dbd_row_t * row, int n)
185{
186 if ((n < 0) || (n >= row->res->sz)) {
187 return NULL;
188 }
189
190 return row->data[n];
191}
192
194 apr_dbd_type_e type, void *data)
195{
196 if ((n < 0) || (n >= row->res->sz)) {
197 return APR_EGENERAL;
198 }
199
200 if (row->data[n] == NULL) {
201 return APR_ENOENT;
202 }
203
204 switch (type) {
206 *(char*)data = atoi(row->data[n]);
207 break;
209 *(unsigned char*)data = atoi(row->data[n]);
210 break;
212 *(short*)data = atoi(row->data[n]);
213 break;
215 *(unsigned short*)data = atoi(row->data[n]);
216 break;
217 case APR_DBD_TYPE_INT:
218 *(int*)data = atoi(row->data[n]);
219 break;
221 *(unsigned int*)data = atoi(row->data[n]);
222 break;
224 *(long*)data = atol(row->data[n]);
225 break;
227 *(unsigned long*)data = atol(row->data[n]);
228 break;
230 *(apr_int64_t*)data = apr_atoi64(row->data[n]);
231 break;
233 *(apr_uint64_t*)data = apr_atoi64(row->data[n]);
234 break;
236 *(float*)data = atof(row->data[n]);
237 break;
239 *(double*)data = atof(row->data[n]);
240 break;
248 *(char**)data = row->data[n];
249 break;
252 {
253 apr_bucket *e;
255
256 e = apr_bucket_pool_create(row->data[n],strlen(row->data[n]),
257 row->res->pool, b->bucket_alloc);
259 }
260 break;
262 *(void**)data = NULL;
263 break;
264 default:
265 return APR_EGENERAL;
266 }
267
268 return APR_SUCCESS;
269}
270
271static const char *dbd_sqlite_error(apr_dbd_t * sql, int n)
272{
273 return sql->errmsg;
274}
275
276static int dbd_sqlite_query(apr_dbd_t * sql, int *nrows, const char *query)
277{
278 char **result;
279 int ret;
280 int tuples = 0;
281 int fields = 0;
282
283 if (sql->trans && sql->trans->errnum) {
284 return sql->trans->errnum;
285 }
286
288
289 ret =
291 &sql->errmsg);
292 if (ret == SQLITE_OK) {
293 *nrows = sqlite_changes(sql->conn);
294
295 if (tuples > 0)
296 free(result);
297
298 ret = 0;
299 }
300
301 if (TXN_NOTICE_ERRORS(sql->trans)) {
302 sql->trans->errnum = ret;
303 }
304
305 return ret;
306}
307
308static apr_status_t free_mem(void *data)
309{
311 return APR_SUCCESS;
312}
313
314static const char *dbd_sqlite_escape(apr_pool_t * pool, const char *arg,
315 apr_dbd_t * sql)
316{
317 char *ret = sqlite_mprintf("%q", arg);
319 return ret;
320}
321
323 const char *query, const char *label,
324 int nargs, int nvals, apr_dbd_type_e *types,
326{
327 return APR_ENOTIMPL;
328}
329
332 const char **values)
333{
334 return APR_ENOTIMPL;
335}
336
340{
341 return APR_ENOTIMPL;
342}
343
345 apr_dbd_results_t ** results,
347 int seek, const char **values)
348{
349 return APR_ENOTIMPL;
350}
351
353 apr_dbd_results_t ** results,
356{
357 return APR_ENOTIMPL;
358}
359
362 const void **values)
363{
364 return APR_ENOTIMPL;
365}
366
370{
371 return APR_ENOTIMPL;
372}
373
375 apr_dbd_results_t ** results,
377 int seek, const void **values)
378{
379 return APR_ENOTIMPL;
380}
381
383 apr_dbd_results_t ** results,
386{
387 return APR_ENOTIMPL;
388}
389
392{
393 int ret, rows;
394
395 ret = dbd_sqlite_query(handle, &rows, "BEGIN TRANSACTION");
396 if (ret == 0) {
397 if (!*trans) {
399 }
400 (*trans)->handle = handle;
401 handle->trans = *trans;
402 }
403 else {
404 ret = -1;
405 }
406 return ret;
407}
408
410{
411 int rows;
412 int ret = -1; /* no transaction is an error cond */
413
414 if (trans) {
415 /* rollback on error or explicit rollback request */
416 if (trans->errnum || TXN_DO_ROLLBACK(trans)) {
417 trans->errnum = 0;
418 ret =
419 dbd_sqlite_query(trans->handle, &rows,
420 "ROLLBACK TRANSACTION");
421 }
422 else {
423 ret =
424 dbd_sqlite_query(trans->handle, &rows, "COMMIT TRANSACTION");
425 }
426 trans->handle->trans = NULL;
427 }
428
429 return ret;
430}
431
433{
434 if (!trans)
436
437 return trans->mode;
438}
439
441 int mode)
442{
443 if (!trans)
445
446 return trans->mode = (mode & TXN_MODE_BITS);
447}
448
449static apr_status_t error_free(void *data)
450{
451 free(data);
452 return APR_SUCCESS;
453}
454
455static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_,
456 const char **error)
457{
458 apr_dbd_t *sql;
459 sqlite *conn = NULL;
460 char *perm;
461 int iperms = 600;
462 char* params = apr_pstrdup(pool, params_);
463 /* params = "[filename]:[permissions]"
464 * example: "shopping.db:600"
465 */
466
467 perm = strstr(params, ":");
468 if (perm) {
469 *(perm++) = '\x00'; /* split the filename and permissions */
470
471 if (strlen(perm) > 0)
472 iperms = atoi(perm);
473 }
474
475 if (error) {
476 *error = NULL;
477
478 conn = sqlite_open(params, iperms, (char **)error);
479
480 if (*error) {
483 }
484 }
485 else {
486 conn = sqlite_open(params, iperms, NULL);
487 }
488
489 sql = apr_pcalloc(pool, sizeof(*sql));
490 sql->conn = conn;
491
492 return sql;
493}
494
496{
497 if (handle->conn) {
498 sqlite_close(handle->conn);
499 handle->conn = NULL;
500 }
501 return APR_SUCCESS;
502}
503
506{
507 if (handle->conn == NULL)
508 return -1;
509 return APR_SUCCESS;
510}
511
513 const char *name)
514{
515 return APR_ENOTIMPL;
516}
517
518static void *dbd_sqlite_native(apr_dbd_t * handle)
519{
520 return handle->conn;
521}
522
524{
525 return res->sz;
526}
527
529{
530 return res->ntuples;
531}
532
534 "sqlite2",
535 NULL,
559 NULL,
565};
566#endif
int n
Definition ap_regex.h:278
APR-UTIL Buckets/Bucket Brigades.
char * strstr(char *s1, char *s2)
#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
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
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
int type
const char apr_int32_t apr_fileperms_t perm
apr_array_header_t ** result
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
static const char *const trans[040]
Definition sed1.c:28
char * name
apr_pool_t * pool
Definition apr_tables.h:64