diff options
Diffstat (limited to 'srclib/apr-util/dbd/apr_dbd_sqlite2.c')
-rw-r--r-- | srclib/apr-util/dbd/apr_dbd_sqlite2.c | 186 |
1 files changed, 178 insertions, 8 deletions
diff --git a/srclib/apr-util/dbd/apr_dbd_sqlite2.c b/srclib/apr-util/dbd/apr_dbd_sqlite2.c index 6907be7b..132ccc4c 100644 --- a/srclib/apr-util/dbd/apr_dbd_sqlite2.c +++ b/srclib/apr-util/dbd/apr_dbd_sqlite2.c @@ -25,10 +25,12 @@ #include "apr_strings.h" #include "apr_time.h" +#include "apr_buckets.h" #include "apr_dbd_internal.h" struct apr_dbd_transaction_t { + int mode; int errnum; apr_dbd_t *handle; }; @@ -46,6 +48,7 @@ struct apr_dbd_results_t { size_t ntuples; size_t sz; size_t index; + apr_pool_t *pool; }; struct apr_dbd_row_t { @@ -100,6 +103,7 @@ static int dbd_sqlite_select(apr_pool_t * pool, apr_dbd_t * sql, (*results)->ntuples = tuples; (*results)->sz = fields; (*results)->random = seek; + (*results)->pool = pool; if (tuples > 0) apr_pool_cleanup_register(pool, result, free_table, @@ -108,12 +112,23 @@ static int dbd_sqlite_select(apr_pool_t * pool, apr_dbd_t * sql, ret = 0; } else { - sql->trans->errnum = ret; + if (TXN_NOTICE_ERRORS(sql->trans)) { + sql->trans->errnum = ret; + } } return ret; } +static const char *dbd_sqlite_get_name(const apr_dbd_results_t *res, int n) +{ + if ((n < 0) || (n >= res->sz)) { + return NULL; + } + + return res->res[n]; +} + static int dbd_sqlite_get_row(apr_pool_t * pool, apr_dbd_results_t * res, apr_dbd_row_t ** rowp, int rownum) { @@ -175,6 +190,84 @@ static const char *dbd_sqlite_get_entry(const apr_dbd_row_t * row, int n) return row->data[n]; } +static apr_status_t dbd_sqlite_datum_get(const apr_dbd_row_t *row, int n, + apr_dbd_type_e type, void *data) +{ + if ((n < 0) || (n >= row->res->sz)) { + return APR_EGENERAL; + } + + if (row->data[n] == NULL) { + return APR_ENOENT; + } + + switch (type) { + case APR_DBD_TYPE_TINY: + *(char*)data = atoi(row->data[n]); + break; + case APR_DBD_TYPE_UTINY: + *(unsigned char*)data = atoi(row->data[n]); + break; + case APR_DBD_TYPE_SHORT: + *(short*)data = atoi(row->data[n]); + break; + case APR_DBD_TYPE_USHORT: + *(unsigned short*)data = atoi(row->data[n]); + break; + case APR_DBD_TYPE_INT: + *(int*)data = atoi(row->data[n]); + break; + case APR_DBD_TYPE_UINT: + *(unsigned int*)data = atoi(row->data[n]); + break; + case APR_DBD_TYPE_LONG: + *(long*)data = atol(row->data[n]); + break; + case APR_DBD_TYPE_ULONG: + *(unsigned long*)data = atol(row->data[n]); + break; + case APR_DBD_TYPE_LONGLONG: + *(apr_int64_t*)data = apr_atoi64(row->data[n]); + break; + case APR_DBD_TYPE_ULONGLONG: + *(apr_uint64_t*)data = apr_atoi64(row->data[n]); + break; + case APR_DBD_TYPE_FLOAT: + *(float*)data = atof(row->data[n]); + break; + case APR_DBD_TYPE_DOUBLE: + *(double*)data = atof(row->data[n]); + 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->data[n]; + 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->data[n],strlen(row->data[n]), + 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_sqlite_error(apr_dbd_t * sql, int n) { return sql->errmsg; @@ -205,7 +298,7 @@ static int dbd_sqlite_query(apr_dbd_t * sql, int *nrows, const char *query) ret = 0; } - if (sql->trans) { + if (TXN_NOTICE_ERRORS(sql->trans)) { sql->trans->errnum = ret; } @@ -228,6 +321,7 @@ static const char *dbd_sqlite_escape(apr_pool_t * pool, const char *arg, static int dbd_sqlite_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) { return APR_ENOTIMPL; @@ -235,7 +329,7 @@ static int dbd_sqlite_prepare(apr_pool_t * pool, apr_dbd_t * sql, static int dbd_sqlite_pquery(apr_pool_t * pool, apr_dbd_t * sql, int *nrows, apr_dbd_prepared_t * statement, - int nargs, const char **values) + const char **values) { return APR_ENOTIMPL; } @@ -250,7 +344,7 @@ static int dbd_sqlite_pvquery(apr_pool_t * pool, apr_dbd_t * sql, static int dbd_sqlite_pselect(apr_pool_t * pool, apr_dbd_t * sql, apr_dbd_results_t ** results, apr_dbd_prepared_t * statement, - int seek, int nargs, const char **values) + int seek, const char **values) { return APR_ENOTIMPL; } @@ -263,6 +357,36 @@ static int dbd_sqlite_pvselect(apr_pool_t * pool, apr_dbd_t * sql, return APR_ENOTIMPL; } +static int dbd_sqlite_pbquery(apr_pool_t * pool, apr_dbd_t * sql, + int *nrows, apr_dbd_prepared_t * statement, + const void **values) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_pvbquery(apr_pool_t * pool, apr_dbd_t * sql, + int *nrows, apr_dbd_prepared_t * statement, + va_list args) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_pbselect(apr_pool_t * pool, apr_dbd_t * sql, + apr_dbd_results_t ** results, + apr_dbd_prepared_t * statement, + int seek, const void **values) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_pvbselect(apr_pool_t * pool, apr_dbd_t * sql, + apr_dbd_results_t ** results, + apr_dbd_prepared_t * statement, int seek, + va_list args) +{ + return APR_ENOTIMPL; +} + static int dbd_sqlite_start_transaction(apr_pool_t * pool, apr_dbd_t * handle, apr_dbd_transaction_t ** trans) { @@ -288,7 +412,8 @@ static int dbd_sqlite_end_transaction(apr_dbd_transaction_t * trans) int ret = -1; /* no transaction is an error cond */ if (trans) { - if (trans->errnum) { + /* rollback on error or explicit rollback request */ + if (trans->errnum || TXN_DO_ROLLBACK(trans)) { trans->errnum = 0; ret = dbd_sqlite_query(trans->handle, &rows, @@ -304,7 +429,31 @@ static int dbd_sqlite_end_transaction(apr_dbd_transaction_t * trans) return ret; } -static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_) +static int dbd_sqlite_transaction_mode_get(apr_dbd_transaction_t *trans) +{ + if (!trans) + return APR_DBD_TRANSACTION_COMMIT; + + return trans->mode; +} + +static int dbd_sqlite_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_status_t error_free(void *data) +{ + free(data); + return APR_SUCCESS; +} + +static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_, + const char **error) { apr_dbd_t *sql; sqlite *conn = NULL; @@ -323,7 +472,19 @@ static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_) iperms = atoi(perm); } - conn = sqlite_open(params, iperms, NULL); + if (error) { + *error = NULL; + + conn = sqlite_open(params, iperms, (char **)error); + + if (*error) { + apr_pool_cleanup_register(pool, *error, error_free, + apr_pool_cleanup_null); + } + } + else { + conn = sqlite_open(params, iperms, NULL); + } sql = apr_pcalloc(pool, sizeof(*sql)); sql->conn = conn; @@ -369,7 +530,7 @@ static int dbd_sqlite_num_tuples(apr_dbd_results_t * res) return res->ntuples; } -APU_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite2_driver = { +APU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite2_driver = { "sqlite2", NULL, dbd_sqlite_native, @@ -392,5 +553,14 @@ APU_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite2_driver = { dbd_sqlite_pvselect, dbd_sqlite_pquery, dbd_sqlite_pselect, + dbd_sqlite_get_name, + dbd_sqlite_transaction_mode_get, + dbd_sqlite_transaction_mode_set, + NULL, + dbd_sqlite_pvbquery, + dbd_sqlite_pvbselect, + dbd_sqlite_pbquery, + dbd_sqlite_pbselect, + dbd_sqlite_datum_get }; #endif |