summaryrefslogtreecommitdiff
path: root/srclib/apr-util/dbd/apr_dbd_sqlite2.c
diff options
context:
space:
mode:
Diffstat (limited to 'srclib/apr-util/dbd/apr_dbd_sqlite2.c')
-rw-r--r--srclib/apr-util/dbd/apr_dbd_sqlite2.c186
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