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
#define MAX_RETRY_COUNT 15
32
#define MAX_RETRY_SLEEP 100000
34
struct apr_dbd_transaction_t {
41
apr_dbd_transaction_t *trans;
42
apr_thread_mutex_t *mutex;
53
struct apr_dbd_row_t {
54
apr_dbd_results_t *res;
55
apr_dbd_column_t **columns;
56
apr_dbd_row_t *next_row;
61
struct apr_dbd_results_t {
65
apr_dbd_row_t *next_row;
71
struct apr_dbd_prepared_t {
76
#define dbd_sqlite3_is_success(x) (((x) == SQLITE_DONE ) \
77
|| ((x) == SQLITE_OK ))
79
static int dbd_sqlite3_select(apr_pool_t * pool, apr_dbd_t * sql, apr_dbd_results_t ** results, const char *query, int seek)
81
sqlite3_stmt *stmt = NULL;
82
const char *tail = NULL;
83
int i, ret, retry_count = 0;
84
size_t num_tuples = 0;
86
apr_dbd_row_t *row = NULL;
87
apr_dbd_row_t *lastrow = NULL;
88
apr_dbd_column_t *column;
92
if (sql->trans && sql->trans->errnum) {
93
return sql->trans->errnum;
96
apr_thread_mutex_lock(sql->mutex);
98
ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
99
if (!dbd_sqlite3_is_success(ret)) {
100
apr_thread_mutex_unlock(sql->mutex);
104
column_count = sqlite3_column_count(stmt);
106
*results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
108
(*results)->stmt = stmt;
109
(*results)->sz = column_count;
110
(*results)->random = seek;
111
(*results)->next_row = 0;
112
(*results)->tuples = 0;
113
(*results)->col_names = apr_pcalloc(pool,
114
column_count * sizeof(char *));
116
ret = sqlite3_step((*results)->stmt);
117
if (ret == SQLITE_BUSY) {
118
if (retry_count++ > MAX_RETRY_COUNT) {
121
apr_thread_mutex_unlock(sql->mutex);
122
apr_sleep(MAX_RETRY_SLEEP);
123
apr_thread_mutex_lock(sql->mutex);
125
} else if (ret == SQLITE_ROW) {
127
apr_dbd_column_t *col;
128
row = apr_palloc(pool, sizeof(apr_dbd_row_t));
130
row->res->stmt = (*results)->stmt;
131
increment = sizeof(apr_dbd_column_t *);
132
length = increment * (*results)->sz;
133
row->columns = apr_palloc(pool, length);
134
row->columnCount = column_count;
135
for (i = 0; i < (*results)->sz; i++) {
136
column = apr_palloc(pool, sizeof(apr_dbd_column_t));
137
row->columns[i] = column;
138
/* copy column name once only */
139
if ((*results)->col_names[i] == NULL) {
140
(*results)->col_names[i] =
142
sqlite3_column_name((*results)->stmt, i));
144
column->name = (*results)->col_names[i];
145
column->size = sqlite3_column_bytes((*results)->stmt, i);
146
column->type = sqlite3_column_type((*results)->stmt, i);
147
column->value = NULL;
148
switch (column->type) {
153
hold = (char *) sqlite3_column_text((*results)->stmt, i);
155
column->value = apr_palloc(pool, column->size + 1);
156
strncpy(column->value, hold, column->size + 1);
164
col = row->columns[i];
166
row->rownum = num_tuples++;
168
(*results)->tuples = num_tuples;
169
if ((*results)->next_row == 0) {
170
(*results)->next_row = row;
173
lastrow->next_row = row;
176
} else if (ret == SQLITE_DONE) {
179
} while (ret == SQLITE_ROW || ret == SQLITE_BUSY);
181
ret = sqlite3_finalize(stmt);
182
apr_thread_mutex_unlock(sql->mutex);
185
sql->trans->errnum = ret;
190
static int dbd_sqlite3_get_row(apr_pool_t *pool, apr_dbd_results_t *res,
191
apr_dbd_row_t **rowp, int rownum)
196
*rowp = res->next_row;
199
res->next_row = (*rowp)->next_row;
202
if (rownum > res->tuples) {
206
*rowp = res->next_row;
207
for (; *rowp != 0; i++, *rowp = (*rowp)->next_row) {
217
static const char *dbd_sqlite3_get_entry(const apr_dbd_row_t *row, int n)
219
apr_dbd_column_t *column;
221
if ((n < 0) || (n >= row->columnCount)) {
224
column = row->columns[n];
225
value = column->value;
229
static const char *dbd_sqlite3_error(apr_dbd_t *sql, int n)
231
return sqlite3_errmsg(sql->conn);
234
static int dbd_sqlite3_query(apr_dbd_t *sql, int *nrows, const char *query)
236
sqlite3_stmt *stmt = NULL;
237
const char *tail = NULL;
238
int ret = -1, length = 0;
240
if (sql->trans && sql->trans->errnum) {
241
return sql->trans->errnum;
244
length = strlen(query);
245
apr_thread_mutex_lock(sql->mutex);
248
ret = sqlite3_prepare(sql->conn, query, length, &stmt, &tail);
249
if (ret != SQLITE_OK) {
250
sqlite3_finalize(stmt);
253
ret = sqlite3_step(stmt);
254
*nrows = sqlite3_changes(sql->conn);
255
sqlite3_finalize(stmt);
256
length -= (tail - query);
258
} while (length > 0);
260
if (dbd_sqlite3_is_success(ret)) {
263
apr_thread_mutex_unlock(sql->mutex);
265
sql->trans->errnum = ret;
270
static const char *dbd_sqlite3_escape(apr_pool_t *pool, const char *arg,
273
char *ret = sqlite3_mprintf("%q", arg);
274
apr_pool_cleanup_register(pool, ret, (void *) sqlite3_free,
275
apr_pool_cleanup_null);
279
static int dbd_sqlite3_prepare(apr_pool_t *pool, apr_dbd_t *sql,
280
const char *query, const char *label,
281
apr_dbd_prepared_t **statement)
286
static int dbd_sqlite3_pquery(apr_pool_t *pool, apr_dbd_t *sql,
287
int *nrows, apr_dbd_prepared_t *statement,
288
int nargs, const char **values)
293
static int dbd_sqlite3_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows,
294
apr_dbd_prepared_t *statement, va_list args)
299
static int dbd_sqlite3_pselect(apr_pool_t *pool, apr_dbd_t *sql,
300
apr_dbd_results_t **results,
301
apr_dbd_prepared_t *statement, int seek,
302
int nargs, const char **values)
307
static int dbd_sqlite3_pvselect(apr_pool_t *pool, apr_dbd_t *sql,
308
apr_dbd_results_t **results,
309
apr_dbd_prepared_t *statement, int seek,
315
static int dbd_sqlite3_start_transaction(apr_pool_t *pool,
317
apr_dbd_transaction_t **trans)
322
ret = dbd_sqlite3_query(handle, &nrows, "BEGIN TRANSACTION;");
324
*trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
325
(*trans)->handle = handle;
326
handle->trans = *trans;
332
static int dbd_sqlite3_end_transaction(apr_dbd_transaction_t *trans)
338
ret = dbd_sqlite3_query(trans->handle, &nrows, "END TRANSACTION;");
341
ret = dbd_sqlite3_query(trans->handle, &nrows, "ROLLBACK;");
343
ret = dbd_sqlite3_query(trans->handle, &nrows, "COMMIT;");
345
trans->handle->trans = NULL;
351
static apr_dbd_t *dbd_sqlite3_open(apr_pool_t *pool, const char *params)
353
apr_dbd_t *sql = NULL;
354
sqlite3 *conn = NULL;
359
sqlres = sqlite3_open(params, &conn);
360
if (sqlres != SQLITE_OK) {
364
/* should we register rand or power functions to the sqlite VM? */
365
sql = apr_pcalloc(pool, sizeof(*sql));
370
res = apr_thread_mutex_create(&sql->mutex, APR_THREAD_MUTEX_DEFAULT,
372
if (res != APR_SUCCESS) {
379
static apr_status_t dbd_sqlite3_close(apr_dbd_t *handle)
381
sqlite3_close(handle->conn);
382
apr_thread_mutex_destroy(handle->mutex);
386
static apr_status_t dbd_sqlite3_check_conn(apr_pool_t *pool,
389
return (handle->conn != NULL) ? APR_SUCCESS : APR_EGENERAL;
392
static int dbd_sqlite3_select_db(apr_pool_t *pool, apr_dbd_t *handle,
398
static void *dbd_sqlite3_native(apr_dbd_t *handle)
403
static int dbd_sqlite3_num_cols(apr_dbd_results_t *res)
408
static int dbd_sqlite3_num_tuples(apr_dbd_results_t *res)
413
APU_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite3_driver = {
418
dbd_sqlite3_check_conn,
420
dbd_sqlite3_select_db,
421
dbd_sqlite3_start_transaction,
422
dbd_sqlite3_end_transaction,
425
dbd_sqlite3_num_cols,
426
dbd_sqlite3_num_tuples,
428
dbd_sqlite3_get_entry,
433
dbd_sqlite3_pvselect,