1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
26
#include "apr_strings.h"
29
#include "apr_dbd_internal.h"
31
struct apr_dbd_transaction_t {
39
apr_dbd_transaction_t *trans;
42
struct apr_dbd_results_t {
51
struct apr_dbd_row_t {
54
apr_dbd_results_t *res;
57
struct apr_dbd_prepared_t {
62
#define FREE_ERROR_MSG(dbd) \
64
if(dbd && dbd->errmsg) { \
71
static int dbd_sqlite_select(apr_pool_t * pool, apr_dbd_t * sql,
72
apr_dbd_results_t ** results, const char *query,
80
if (sql->trans && sql->trans->errnum) {
81
return sql->trans->errnum;
86
ret = sqlite_get_table(sql->conn, query, &result, &tuples, &fields,
89
if (ret == SQLITE_OK) {
91
*results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
94
(*results)->res = result;
96
(*results)->ntuples = tuples;
99
(*results)->ntuples = -1;
101
(*results)->sz = fields;
102
(*results)->random = seek;
105
apr_pool_cleanup_register(pool, result, (void *) free,
106
apr_pool_cleanup_null);
111
sql->trans->errnum = ret;
117
static int dbd_sqlite_get_row(apr_pool_t * pool, apr_dbd_results_t * res,
118
apr_dbd_row_t ** rowp, int rownum)
120
apr_dbd_row_t *row = *rowp;
121
int sequential = ((rownum >= 0) && res->random) ? 0 : 1;
124
row = apr_palloc(pool, sizeof(apr_dbd_row_t));
127
row->n = sequential ? 0 : rownum - 1;
138
if (row->n >= res->ntuples) {
140
apr_pool_cleanup_kill(pool, res->res, (void *) free);
145
/* Pointer magic explanation:
146
* The sqlite result is an array such that the first res->sz elements are
147
* the column names and each tuple follows afterwards
148
* ex: (from the sqlite2 documentation)
149
SELECT employee_name, login, host FROM users WHERE login LIKE * 'd%';
153
result[0] = "employee_name"
157
result[4] = "No such user"
159
result[6] = "D. Richard Hipp"
164
row->data = res->res + res->sz + (res->sz * row->n);
169
static const char *dbd_sqlite_get_entry(const apr_dbd_row_t * row, int n)
171
if ((n < 0) || (n >= row->res->sz)) {
178
static const char *dbd_sqlite_error(apr_dbd_t * sql, int n)
183
static int dbd_sqlite_query(apr_dbd_t * sql, int *nrows, const char *query)
190
if (sql->trans && sql->trans->errnum) {
191
return sql->trans->errnum;
197
sqlite_get_table(sql->conn, query, &result, &tuples, &fields,
199
if (ret == SQLITE_OK) {
200
*nrows = sqlite_changes(sql->conn);
209
sql->trans->errnum = ret;
215
static const char *dbd_sqlite_escape(apr_pool_t * pool, const char *arg,
218
char *ret = sqlite_mprintf("%q", arg);
219
apr_pool_cleanup_register(pool, ret, (void *) sqlite_freemem,
220
apr_pool_cleanup_null);
224
static int dbd_sqlite_prepare(apr_pool_t * pool, apr_dbd_t * sql,
225
const char *query, const char *label,
226
apr_dbd_prepared_t ** statement)
231
static int dbd_sqlite_pquery(apr_pool_t * pool, apr_dbd_t * sql,
232
int *nrows, apr_dbd_prepared_t * statement,
233
int nargs, const char **values)
238
static int dbd_sqlite_pvquery(apr_pool_t * pool, apr_dbd_t * sql,
239
int *nrows, apr_dbd_prepared_t * statement,
245
static int dbd_sqlite_pselect(apr_pool_t * pool, apr_dbd_t * sql,
246
apr_dbd_results_t ** results,
247
apr_dbd_prepared_t * statement,
248
int seek, int nargs, const char **values)
253
static int dbd_sqlite_pvselect(apr_pool_t * pool, apr_dbd_t * sql,
254
apr_dbd_results_t ** results,
255
apr_dbd_prepared_t * statement, int seek,
261
static int dbd_sqlite_start_transaction(apr_pool_t * pool, apr_dbd_t * handle,
262
apr_dbd_transaction_t ** trans)
266
ret = dbd_sqlite_query(handle, &rows, "BEGIN TRANSACTION");
269
*trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
271
(*trans)->handle = handle;
272
handle->trans = *trans;
280
static int dbd_sqlite_end_transaction(apr_dbd_transaction_t * trans)
283
int ret = -1; /* no transaction is an error cond */
289
dbd_sqlite_query(trans->handle, &rows,
290
"ROLLBACK TRANSACTION");
294
dbd_sqlite_query(trans->handle, &rows, "COMMIT TRANSACTION");
296
trans->handle->trans = NULL;
302
static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_)
306
char *filename, *perm;
308
char* params = apr_pstrdup(pool, params_);
309
/* params = "[filename]:[permissions]"
310
* example: "shopping.db:600"
313
perm = strstr(params, ":");
315
*(perm++) = '\x00'; /* split the filename and permissions */
317
if (strlen(perm) > 0)
321
conn = sqlite_open(params, iperms, NULL);
323
sql = apr_pcalloc(pool, sizeof(*sql));
329
static apr_status_t dbd_sqlite_close(apr_dbd_t * handle)
332
sqlite_close(handle->conn);
338
static apr_status_t dbd_sqlite_check_conn(apr_pool_t * pool,
341
if (handle->conn == NULL)
346
static int dbd_sqlite_select_db(apr_pool_t * pool, apr_dbd_t * handle,
352
static void *dbd_sqlite_native(apr_dbd_t * handle)
357
static int dbd_sqlite_num_cols(apr_dbd_results_t * res)
362
static int dbd_sqlite_num_tuples(apr_dbd_results_t * res)
367
APU_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite2_driver = {
372
dbd_sqlite_check_conn,
374
dbd_sqlite_select_db,
375
dbd_sqlite_start_transaction,
376
dbd_sqlite_end_transaction,
380
dbd_sqlite_num_tuples,
382
dbd_sqlite_get_entry,