diff options
author | Arno Töll <debian@toell.net> | 2012-01-08 22:53:17 +0100 |
---|---|---|
committer | Arno Töll <debian@toell.net> | 2012-01-08 22:53:17 +0100 |
commit | e072a2dd866b7cb9f14319b80326a4e7fd16fcdf (patch) | |
tree | a49dfc56d94a26011fe157835ff6cbe14edbd8a9 /srclib/apr-util/dbd/apr_dbd_sqlite3.c | |
parent | 0890390c00801651d08d3794e13b31a5dabbf5ef (diff) | |
download | apache2-e072a2dd866b7cb9f14319b80326a4e7fd16fcdf.tar.gz |
Imported Upstream version 2.3.16-beta
Diffstat (limited to 'srclib/apr-util/dbd/apr_dbd_sqlite3.c')
-rw-r--r-- | srclib/apr-util/dbd/apr_dbd_sqlite3.c | 916 |
1 files changed, 0 insertions, 916 deletions
diff --git a/srclib/apr-util/dbd/apr_dbd_sqlite3.c b/srclib/apr-util/dbd/apr_dbd_sqlite3.c deleted file mode 100644 index 02b2c02d..00000000 --- a/srclib/apr-util/dbd/apr_dbd_sqlite3.c +++ /dev/null @@ -1,916 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apu.h" - -#if APU_HAVE_SQLITE3 - -#include <ctype.h> -#include <stdlib.h> - -#include <sqlite3.h> - -#include "apr_strings.h" -#include "apr_time.h" -#include "apr_buckets.h" - -#include "apr_dbd_internal.h" - -#define MAX_RETRY_COUNT 15 -#define MAX_RETRY_SLEEP 100000 - -struct apr_dbd_transaction_t { - int mode; - int errnum; - apr_dbd_t *handle; -}; - -struct apr_dbd_t { - sqlite3 *conn; - apr_dbd_transaction_t *trans; - apr_pool_t *pool; - apr_dbd_prepared_t *prep; -}; - -typedef struct { - char *name; - char *value; - int size; - int type; -} apr_dbd_column_t; - -struct apr_dbd_row_t { - apr_dbd_results_t *res; - apr_dbd_column_t **columns; - apr_dbd_row_t *next_row; - int columnCount; - int rownum; -}; - -struct apr_dbd_results_t { - int random; - sqlite3 *handle; - sqlite3_stmt *stmt; - apr_dbd_row_t *next_row; - size_t sz; - int tuples; - char **col_names; - apr_pool_t *pool; -}; - -struct apr_dbd_prepared_t { - sqlite3_stmt *stmt; - apr_dbd_prepared_t *next; - int nargs; - int nvals; - apr_dbd_type_e *types; -}; - -#define dbd_sqlite3_is_success(x) (((x) == SQLITE_DONE) || ((x) == SQLITE_OK)) - -static int dbd_sqlite3_select_internal(apr_pool_t *pool, - apr_dbd_t *sql, - apr_dbd_results_t **results, - sqlite3_stmt *stmt, int seek) -{ - int ret, retry_count = 0, column_count; - size_t i, num_tuples = 0; - int increment = 0; - apr_dbd_row_t *row = NULL; - apr_dbd_row_t *lastrow = NULL; - apr_dbd_column_t *column; - char *hold = NULL; - - column_count = sqlite3_column_count(stmt); - if (!*results) { - *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); - } - (*results)->stmt = stmt; - (*results)->sz = column_count; - (*results)->random = seek; - (*results)->next_row = 0; - (*results)->tuples = 0; - (*results)->col_names = apr_pcalloc(pool, column_count * sizeof(char *)); - (*results)->pool = pool; - do { - ret = sqlite3_step(stmt); - if (ret == SQLITE_BUSY) { - if (retry_count++ > MAX_RETRY_COUNT) { - ret = SQLITE_ERROR; - } else { - apr_dbd_mutex_unlock(); - apr_sleep(MAX_RETRY_SLEEP); - apr_dbd_mutex_lock(); - } - } else if (ret == SQLITE_ROW) { - int length; - apr_dbd_column_t *col; - row = apr_palloc(pool, sizeof(apr_dbd_row_t)); - row->res = *results; - increment = sizeof(apr_dbd_column_t *); - length = increment * (*results)->sz; - row->columns = apr_palloc(pool, length); - row->columnCount = column_count; - for (i = 0; i < (*results)->sz; i++) { - column = apr_palloc(pool, sizeof(apr_dbd_column_t)); - row->columns[i] = column; - /* copy column name once only */ - if ((*results)->col_names[i] == NULL) { - (*results)->col_names[i] = - apr_pstrdup(pool, sqlite3_column_name(stmt, i)); - } - column->name = (*results)->col_names[i]; - column->size = sqlite3_column_bytes(stmt, i); - column->type = sqlite3_column_type(stmt, i); - column->value = NULL; - switch (column->type) { - case SQLITE_FLOAT: - case SQLITE_INTEGER: - case SQLITE_TEXT: - hold = (char *) sqlite3_column_text(stmt, i); - if (hold) { - column->value = apr_pstrmemdup(pool, hold, - column->size); - } - break; - case SQLITE_BLOB: - hold = (char *) sqlite3_column_blob(stmt, i); - if (hold) { - column->value = apr_pstrmemdup(pool, hold, - column->size); - } - break; - case SQLITE_NULL: - break; - } - col = row->columns[i]; - } - row->rownum = num_tuples++; - row->next_row = 0; - (*results)->tuples = num_tuples; - if ((*results)->next_row == 0) { - (*results)->next_row = row; - } - if (lastrow != 0) { - lastrow->next_row = row; - } - lastrow = row; - } - } while (ret == SQLITE_ROW || ret == SQLITE_BUSY); - - if (dbd_sqlite3_is_success(ret)) { - ret = 0; - } - return ret; -} - -static int dbd_sqlite3_select(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **results, const char *query, - int seek) -{ - sqlite3_stmt *stmt = NULL; - const char *tail = NULL; - int ret; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - apr_dbd_mutex_lock(); - - ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail); - if (dbd_sqlite3_is_success(ret)) { - ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek); - } - sqlite3_finalize(stmt); - - apr_dbd_mutex_unlock(); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static const char *dbd_sqlite3_get_name(const apr_dbd_results_t *res, int n) -{ - if ((n < 0) || ((size_t)n >= res->sz)) { - return NULL; - } - - return res->col_names[n]; -} - -static int dbd_sqlite3_get_row(apr_pool_t *pool, apr_dbd_results_t *res, - apr_dbd_row_t **rowp, int rownum) -{ - int i = 0; - - if (rownum == -1) { - *rowp = res->next_row; - if (*rowp == 0) - return -1; - res->next_row = (*rowp)->next_row; - return 0; - } - if (rownum > res->tuples) { - return -1; - } - rownum--; - *rowp = res->next_row; - for (; *rowp != 0; i++, *rowp = (*rowp)->next_row) { - if (i == rownum) { - return 0; - } - } - - return -1; - -} - -static const char *dbd_sqlite3_get_entry(const apr_dbd_row_t *row, int n) -{ - apr_dbd_column_t *column; - const char *value; - if ((n < 0) || (n >= row->columnCount)) { - return NULL; - } - column = row->columns[n]; - value = column->value; - return value; -} - -static apr_status_t dbd_sqlite3_datum_get(const apr_dbd_row_t *row, int n, - apr_dbd_type_e type, void *data) -{ - if ((n < 0) || ((size_t)n >= row->res->sz)) { - return APR_EGENERAL; - } - - if (row->columns[n]->type == SQLITE_NULL) { - return APR_ENOENT; - } - - switch (type) { - case APR_DBD_TYPE_TINY: - *(char*)data = atoi(row->columns[n]->value); - break; - case APR_DBD_TYPE_UTINY: - *(unsigned char*)data = atoi(row->columns[n]->value); - break; - case APR_DBD_TYPE_SHORT: - *(short*)data = atoi(row->columns[n]->value); - break; - case APR_DBD_TYPE_USHORT: - *(unsigned short*)data = atoi(row->columns[n]->value); - break; - case APR_DBD_TYPE_INT: - *(int*)data = atoi(row->columns[n]->value); - break; - case APR_DBD_TYPE_UINT: - *(unsigned int*)data = atoi(row->columns[n]->value); - break; - case APR_DBD_TYPE_LONG: - *(long*)data = atol(row->columns[n]->value); - break; - case APR_DBD_TYPE_ULONG: - *(unsigned long*)data = atol(row->columns[n]->value); - break; - case APR_DBD_TYPE_LONGLONG: - *(apr_int64_t*)data = apr_atoi64(row->columns[n]->value); - break; - case APR_DBD_TYPE_ULONGLONG: - *(apr_uint64_t*)data = apr_atoi64(row->columns[n]->value); - break; - case APR_DBD_TYPE_FLOAT: - *(float*)data = (float)atof(row->columns[n]->value); - break; - case APR_DBD_TYPE_DOUBLE: - *(double*)data = atof(row->columns[n]->value); - break; - case APR_DBD_TYPE_STRING: - case APR_DBD_TYPE_TEXT: - case APR_DBD_TYPE_TIME: - case APR_DBD_TYPE_DATE: - case APR_DBD_TYPE_DATETIME: - case APR_DBD_TYPE_TIMESTAMP: - case APR_DBD_TYPE_ZTIMESTAMP: - *(char**)data = row->columns[n]->value; - break; - case APR_DBD_TYPE_BLOB: - case APR_DBD_TYPE_CLOB: - { - apr_bucket *e; - apr_bucket_brigade *b = (apr_bucket_brigade*)data; - - e = apr_bucket_pool_create(row->columns[n]->value, - row->columns[n]->size, - row->res->pool, b->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(b, e); - } - break; - case APR_DBD_TYPE_NULL: - *(void**)data = NULL; - break; - default: - return APR_EGENERAL; - } - - return APR_SUCCESS; -} - -static const char *dbd_sqlite3_error(apr_dbd_t *sql, int n) -{ - return sqlite3_errmsg(sql->conn); -} - -static int dbd_sqlite3_query_internal(apr_dbd_t *sql, sqlite3_stmt *stmt, - int *nrows) -{ - int ret = -1, retry_count = 0; - - while(retry_count++ <= MAX_RETRY_COUNT) { - ret = sqlite3_step(stmt); - if (ret != SQLITE_BUSY) - break; - - apr_dbd_mutex_unlock(); - apr_sleep(MAX_RETRY_SLEEP); - apr_dbd_mutex_lock(); - } - - *nrows = sqlite3_changes(sql->conn); - - if (dbd_sqlite3_is_success(ret)) { - ret = 0; - } - return ret; -} - -static int dbd_sqlite3_query(apr_dbd_t *sql, int *nrows, const char *query) -{ - sqlite3_stmt *stmt = NULL; - const char *tail = NULL; - int ret = -1, length = 0; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - length = strlen(query); - apr_dbd_mutex_lock(); - - do { - ret = sqlite3_prepare(sql->conn, query, length, &stmt, &tail); - if (ret != SQLITE_OK) { - sqlite3_finalize(stmt); - break; - } - - ret = dbd_sqlite3_query_internal(sql, stmt, nrows); - - sqlite3_finalize(stmt); - length -= (tail - query); - query = tail; - } while (length > 0); - - apr_dbd_mutex_unlock(); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static apr_status_t free_mem(void *data) -{ - sqlite3_free(data); - return APR_SUCCESS; -} - -static const char *dbd_sqlite3_escape(apr_pool_t *pool, const char *arg, - apr_dbd_t *sql) -{ - char *ret = sqlite3_mprintf("%q", arg); - apr_pool_cleanup_register(pool, ret, free_mem, - apr_pool_cleanup_null); - return ret; -} - -static int 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) -{ - sqlite3_stmt *stmt; - const char *tail = NULL; - int ret; - - apr_dbd_mutex_lock(); - - ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail); - if (ret == SQLITE_OK) { - apr_dbd_prepared_t *prep; - - prep = apr_pcalloc(sql->pool, sizeof(*prep)); - prep->stmt = stmt; - prep->next = sql->prep; - prep->nargs = nargs; - prep->nvals = nvals; - prep->types = types; - - /* link new statement to the handle */ - sql->prep = prep; - - *statement = prep; - } else { - sqlite3_finalize(stmt); - } - - apr_dbd_mutex_unlock(); - - return ret; -} - -static void dbd_sqlite3_bind(apr_dbd_prepared_t *statement, const char **values) -{ - sqlite3_stmt *stmt = statement->stmt; - int i, j; - - for (i = 0, j = 0; i < statement->nargs; i++, j++) { - if (values[j] == NULL) { - sqlite3_bind_null(stmt, i + 1); - } - else { - switch (statement->types[i]) { - case APR_DBD_TYPE_BLOB: - case APR_DBD_TYPE_CLOB: - { - char *data = (char *)values[j]; - int size = atoi((char*)values[++j]); - - /* skip table and column */ - j += 2; - - sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC); - } - break; - default: - sqlite3_bind_text(stmt, i + 1, values[j], - strlen(values[j]), SQLITE_STATIC); - break; - } - } - } - - return; -} - -static int dbd_sqlite3_pquery(apr_pool_t *pool, apr_dbd_t *sql, - int *nrows, apr_dbd_prepared_t *statement, - const char **values) -{ - sqlite3_stmt *stmt = statement->stmt; - int ret = -1; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - apr_dbd_mutex_lock(); - - ret = sqlite3_reset(stmt); - if (ret == SQLITE_OK) { - dbd_sqlite3_bind(statement, values); - - ret = dbd_sqlite3_query_internal(sql, stmt, nrows); - - sqlite3_reset(stmt); - } - - apr_dbd_mutex_unlock(); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_sqlite3_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows, - apr_dbd_prepared_t *statement, va_list args) -{ - const char **values; - int i; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - values = apr_palloc(pool, sizeof(*values) * statement->nvals); - - for (i = 0; i < statement->nvals; i++) { - values[i] = va_arg(args, const char*); - } - - return dbd_sqlite3_pquery(pool, sql, nrows, statement, values); -} - -static int 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) -{ - sqlite3_stmt *stmt = statement->stmt; - int ret; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - apr_dbd_mutex_lock(); - - ret = sqlite3_reset(stmt); - if (ret == SQLITE_OK) { - dbd_sqlite3_bind(statement, values); - - ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek); - - sqlite3_reset(stmt); - } - - apr_dbd_mutex_unlock(); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int 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) -{ - const char **values; - int i; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - values = apr_palloc(pool, sizeof(*values) * statement->nvals); - - for (i = 0; i < statement->nvals; i++) { - values[i] = va_arg(args, const char*); - } - - return dbd_sqlite3_pselect(pool, sql, results, statement, seek, values); -} - -static void dbd_sqlite3_bbind(apr_dbd_prepared_t * statement, - const void **values) -{ - sqlite3_stmt *stmt = statement->stmt; - int i, j; - apr_dbd_type_e type; - - for (i = 0, j = 0; i < statement->nargs; i++, j++) { - type = (values[j] == NULL ? APR_DBD_TYPE_NULL : statement->types[i]); - - switch (type) { - case APR_DBD_TYPE_TINY: - sqlite3_bind_int(stmt, i + 1, *(char*)values[j]); - break; - case APR_DBD_TYPE_UTINY: - sqlite3_bind_int(stmt, i + 1, *(unsigned char*)values[j]); - break; - case APR_DBD_TYPE_SHORT: - sqlite3_bind_int(stmt, i + 1, *(short*)values[j]); - break; - case APR_DBD_TYPE_USHORT: - sqlite3_bind_int(stmt, i + 1, *(unsigned short*)values[j]); - break; - case APR_DBD_TYPE_INT: - sqlite3_bind_int(stmt, i + 1, *(int*)values[j]); - break; - case APR_DBD_TYPE_UINT: - sqlite3_bind_int(stmt, i + 1, *(unsigned int*)values[j]); - break; - case APR_DBD_TYPE_LONG: - sqlite3_bind_int64(stmt, i + 1, *(long*)values[j]); - break; - case APR_DBD_TYPE_ULONG: - sqlite3_bind_int64(stmt, i + 1, *(unsigned long*)values[j]); - break; - case APR_DBD_TYPE_LONGLONG: - sqlite3_bind_int64(stmt, i + 1, *(apr_int64_t*)values[j]); - break; - case APR_DBD_TYPE_ULONGLONG: - sqlite3_bind_int64(stmt, i + 1, *(apr_uint64_t*)values[j]); - break; - case APR_DBD_TYPE_FLOAT: - sqlite3_bind_double(stmt, i + 1, *(float*)values[j]); - break; - case APR_DBD_TYPE_DOUBLE: - sqlite3_bind_double(stmt, i + 1, *(double*)values[j]); - break; - case APR_DBD_TYPE_STRING: - case APR_DBD_TYPE_TEXT: - case APR_DBD_TYPE_TIME: - case APR_DBD_TYPE_DATE: - case APR_DBD_TYPE_DATETIME: - case APR_DBD_TYPE_TIMESTAMP: - case APR_DBD_TYPE_ZTIMESTAMP: - sqlite3_bind_text(stmt, i + 1, values[j], strlen(values[j]), - SQLITE_STATIC); - break; - case APR_DBD_TYPE_BLOB: - case APR_DBD_TYPE_CLOB: - { - char *data = (char*)values[j]; - apr_size_t size = *(apr_size_t*)values[++j]; - - sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC); - - /* skip table and column */ - j += 2; - } - break; - case APR_DBD_TYPE_NULL: - default: - sqlite3_bind_null(stmt, i + 1); - break; - } - } - - return; -} - -static int dbd_sqlite3_pbquery(apr_pool_t * pool, apr_dbd_t * sql, - int *nrows, apr_dbd_prepared_t * statement, - const void **values) -{ - sqlite3_stmt *stmt = statement->stmt; - int ret = -1; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - apr_dbd_mutex_lock(); - - ret = sqlite3_reset(stmt); - if (ret == SQLITE_OK) { - dbd_sqlite3_bbind(statement, values); - - ret = dbd_sqlite3_query_internal(sql, stmt, nrows); - - sqlite3_reset(stmt); - } - - apr_dbd_mutex_unlock(); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_sqlite3_pvbquery(apr_pool_t * pool, apr_dbd_t * sql, - int *nrows, apr_dbd_prepared_t * statement, - va_list args) -{ - const void **values; - int i; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - values = apr_palloc(pool, sizeof(*values) * statement->nvals); - - for (i = 0; i < statement->nvals; i++) { - values[i] = va_arg(args, const void*); - } - - return dbd_sqlite3_pbquery(pool, sql, nrows, statement, values); -} - -static int 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) -{ - sqlite3_stmt *stmt = statement->stmt; - int ret; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - apr_dbd_mutex_lock(); - - ret = sqlite3_reset(stmt); - if (ret == SQLITE_OK) { - dbd_sqlite3_bbind(statement, values); - - ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek); - - sqlite3_reset(stmt); - } - - apr_dbd_mutex_unlock(); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int 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) -{ - const void **values; - int i; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - values = apr_palloc(pool, sizeof(*values) * statement->nvals); - - for (i = 0; i < statement->nvals; i++) { - values[i] = va_arg(args, const void*); - } - - return dbd_sqlite3_pbselect(pool, sql, results, statement, seek, values); -} - -static int dbd_sqlite3_start_transaction(apr_pool_t *pool, - apr_dbd_t *handle, - apr_dbd_transaction_t **trans) -{ - int ret = 0; - int nrows = 0; - - ret = dbd_sqlite3_query(handle, &nrows, "BEGIN IMMEDIATE"); - if (!*trans) { - *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t)); - (*trans)->handle = handle; - handle->trans = *trans; - } - - return ret; -} - -static int dbd_sqlite3_end_transaction(apr_dbd_transaction_t *trans) -{ - int ret = -1; /* ending transaction that was never started is an error */ - int nrows = 0; - - if (trans) { - /* rollback on error or explicit rollback request */ - if (trans->errnum || TXN_DO_ROLLBACK(trans)) { - trans->errnum = 0; - ret = dbd_sqlite3_query(trans->handle, &nrows, "ROLLBACK"); - } else { - ret = dbd_sqlite3_query(trans->handle, &nrows, "COMMIT"); - } - trans->handle->trans = NULL; - } - - return ret; -} - -static int dbd_sqlite3_transaction_mode_get(apr_dbd_transaction_t *trans) -{ - if (!trans) - return APR_DBD_TRANSACTION_COMMIT; - - return trans->mode; -} - -static int dbd_sqlite3_transaction_mode_set(apr_dbd_transaction_t *trans, - int mode) -{ - if (!trans) - return APR_DBD_TRANSACTION_COMMIT; - - return trans->mode = (mode & TXN_MODE_BITS); -} - -static apr_dbd_t *dbd_sqlite3_open(apr_pool_t *pool, const char *params, - const char **error) -{ - apr_dbd_t *sql = NULL; - sqlite3 *conn = NULL; - int sqlres; - if (!params) - return NULL; - sqlres = sqlite3_open(params, &conn); - if (sqlres != SQLITE_OK) { - if (error) { - *error = apr_pstrdup(pool, sqlite3_errmsg(conn)); - } - sqlite3_close(conn); - return NULL; - } - /* should we register rand or power functions to the sqlite VM? */ - sql = apr_pcalloc(pool, sizeof(*sql)); - sql->conn = conn; - sql->pool = pool; - sql->trans = NULL; - - return sql; -} - -static apr_status_t dbd_sqlite3_close(apr_dbd_t *handle) -{ - apr_dbd_prepared_t *prep = handle->prep; - - /* finalize all prepared statements, or we'll get SQLITE_BUSY on close */ - while (prep) { - sqlite3_finalize(prep->stmt); - prep = prep->next; - } - - sqlite3_close(handle->conn); - return APR_SUCCESS; -} - -static apr_status_t dbd_sqlite3_check_conn(apr_pool_t *pool, - apr_dbd_t *handle) -{ - return (handle->conn != NULL) ? APR_SUCCESS : APR_EGENERAL; -} - -static int dbd_sqlite3_select_db(apr_pool_t *pool, apr_dbd_t *handle, - const char *name) -{ - return APR_ENOTIMPL; -} - -static void *dbd_sqlite3_native(apr_dbd_t *handle) -{ - return handle->conn; -} - -static int dbd_sqlite3_num_cols(apr_dbd_results_t *res) -{ - return res->sz; -} - -static int dbd_sqlite3_num_tuples(apr_dbd_results_t *res) -{ - return res->tuples; -} - -APU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite3_driver = { - "sqlite3", - NULL, - dbd_sqlite3_native, - dbd_sqlite3_open, - dbd_sqlite3_check_conn, - dbd_sqlite3_close, - dbd_sqlite3_select_db, - dbd_sqlite3_start_transaction, - dbd_sqlite3_end_transaction, - dbd_sqlite3_query, - dbd_sqlite3_select, - dbd_sqlite3_num_cols, - dbd_sqlite3_num_tuples, - dbd_sqlite3_get_row, - dbd_sqlite3_get_entry, - dbd_sqlite3_error, - dbd_sqlite3_escape, - dbd_sqlite3_prepare, - dbd_sqlite3_pvquery, - dbd_sqlite3_pvselect, - dbd_sqlite3_pquery, - dbd_sqlite3_pselect, - dbd_sqlite3_get_name, - dbd_sqlite3_transaction_mode_get, - dbd_sqlite3_transaction_mode_set, - "?", - dbd_sqlite3_pvbquery, - dbd_sqlite3_pvbselect, - dbd_sqlite3_pbquery, - dbd_sqlite3_pbselect, - dbd_sqlite3_datum_get -}; -#endif |