diff options
author | pgollucci <pgollucci@FreeBSD.org> | 2010-05-07 07:19:56 +0800 |
---|---|---|
committer | pgollucci <pgollucci@FreeBSD.org> | 2010-05-07 07:19:56 +0800 |
commit | 385db748418fda340c1493c7780ba4edec28823b (patch) | |
tree | 32b3e65ca8206bdc378217d4679ed4d25817ef4f /www/apache22 | |
parent | 602e2bb7728dcb311cb9863a6000d63ef07ffed4 (diff) | |
download | freebsd-ports-gnome-385db748418fda340c1493c7780ba4edec28823b.tar.gz freebsd-ports-gnome-385db748418fda340c1493c7780ba4edec28823b.tar.zst freebsd-ports-gnome-385db748418fda340c1493c7780ba4edec28823b.zip |
- This file isn't even used, it doesn't matter anyway devel/apr(1.4.2) and
the apr bundled with www/apache22 include this file as the licensing
issue was resolved ages ago
With Hat: apache@
Diffstat (limited to 'www/apache22')
-rw-r--r-- | www/apache22/files/apr_dbd_mysql.c | 1625 |
1 files changed, 0 insertions, 1625 deletions
diff --git a/www/apache22/files/apr_dbd_mysql.c b/www/apache22/files/apr_dbd_mysql.c deleted file mode 100644 index c617379b49e4..000000000000 --- a/www/apache22/files/apr_dbd_mysql.c +++ /dev/null @@ -1,1625 +0,0 @@ -/* - Copyright (c) 2003-7, WebThing Ltd and other contributors - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. Alternatively, where this program -is aggregated with the Apache APR-UTIL package version 1.2 or later, -you can distribute and/or modify it under the terms of the Apache -License 2.0 as published by the Apache Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -applicable License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -You may obtain a copy of the Apache License 2.0 at: -http://www.apache.org/licenses/LICENSE-2.0 - -*/ - -/* LICENSE NOTE - * - * The current GPL satisfies MySQL licensing terms without - * invoking any exceptions. ASF policy doesn't permit GPL - * software to be distributed by apache.org, but this should - * not be a problem for third-parties who wish to distribute - * it alongside the APR and other Apache software. - * - * It is updated to dual license after discussion with Debian - * and taking into account MySQL's FOSS exception. - * http://bahumbug.wordpress.com/2007/01/09/re-licensing-apr_dbd_mysql/ - * http://www.mysql.com/company/legal/licensing/foss-exception.html - * - * MAINTAINERS - * - * This code was originally written by Nick Kew for MySQL 4.1. - * and subsequently updated by others to support MySQL 5.0. - * The current lead maintainer is Bojan Smojver, with others - * contributing via the developer list at apr.apache.org. - * - */ - - -#include "apu.h" -#define HAVE_MYSQL_MYSQL_H - -#if APU_HAVE_MYSQL - -#include "apu_version.h" -#include "apu_config.h" - -#include <ctype.h> -#include <stdlib.h> - -#ifdef HAVE_MYSQL_H -#include <mysql.h> -#include <errmsg.h> -#elif defined(HAVE_MYSQL_MYSQL_H) -#include <mysql/mysql.h> -#include <mysql/errmsg.h> -#endif - -#include "apr_strings.h" -#include "apr_buckets.h" - -#include "apr_dbd_internal.h" - -/* default maximum field size 1 MB */ -#define FIELDSIZE 1048575 - -struct apr_dbd_prepared_t { - MYSQL_STMT* stmt; -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - int nargs; - int nvals; - apr_dbd_type_e *types; -#endif -}; - -struct apr_dbd_transaction_t { -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - int mode; -#endif - int errnum; - apr_dbd_t *handle; -}; - -struct apr_dbd_t { - MYSQL* conn ; - apr_dbd_transaction_t* trans ; - unsigned long fldsz; -}; - -struct apr_dbd_results_t { - int random; - MYSQL_RES *res; - MYSQL_STMT *statement; - MYSQL_BIND *bind; -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - apr_pool_t *pool; -#endif -}; -struct apr_dbd_row_t { - MYSQL_ROW row; - apr_dbd_results_t *res; -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - unsigned long *len; -#endif -}; - -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) -/* MySQL specific bucket for BLOB types */ -typedef struct apr_bucket_lob apr_bucket_lob; -/** - * A bucket referring to a MySQL BLOB - */ -struct apr_bucket_lob { - /** Number of buckets using this memory */ - apr_bucket_refcount refcount; - /** The row this bucket refers to */ - const apr_dbd_row_t *row; - /** The column this bucket refers to */ - int col; - /** The pool into which any needed structures should - * be created while reading from this bucket */ - apr_pool_t *readpool; -}; - -static void lob_bucket_destroy(void *data); -static apr_status_t lob_bucket_read(apr_bucket *e, const char **str, - apr_size_t *len, apr_read_type_e block); -static apr_bucket *apr_bucket_lob_make(apr_bucket *b, - const apr_dbd_row_t *row, int col, - apr_off_t offset, apr_size_t len, - apr_pool_t *p); -static apr_bucket *apr_bucket_lob_create(const apr_dbd_row_t *row, int col, - apr_off_t offset, - apr_size_t len, apr_pool_t *p, - apr_bucket_alloc_t *list); - -static const apr_bucket_type_t apr_bucket_type_lob = { - "LOB", 5, APR_BUCKET_DATA, - lob_bucket_destroy, - lob_bucket_read, - apr_bucket_setaside_notimpl, - apr_bucket_shared_split, - apr_bucket_shared_copy -}; - -static void lob_bucket_destroy(void *data) -{ - apr_bucket_lob *f = data; - - if (apr_bucket_shared_destroy(f)) { - /* no need to destroy database objects here; it will get - * done automatically when the pool gets cleaned up */ - apr_bucket_free(f); - } -} - -static apr_status_t lob_bucket_read(apr_bucket *e, const char **str, - apr_size_t *len, apr_read_type_e block) -{ - apr_bucket_lob *a = e->data; - const apr_dbd_row_t *row = a->row; - apr_dbd_results_t *res = row->res; - int col = a->col; - apr_bucket *b = NULL; - int rv; - apr_size_t blength = e->length; /* bytes remaining in file past offset */ - apr_off_t boffset = e->start; - MYSQL_BIND *bind = &res->bind[col]; - - *str = NULL; /* in case we die prematurely */ - - /* fetch from offset if not at the beginning */ - if (boffset > 0) { - rv = mysql_stmt_fetch_column(res->statement, bind, col, boffset); - if (rv != 0) { - return APR_EGENERAL; - } - } - blength -= blength > bind->buffer_length ? bind->buffer_length : blength; - *len = e->length - blength; - *str = bind->buffer; - - /* allocate new buffer, since we used this one for the bucket */ - bind->buffer = apr_palloc(res->pool, bind->buffer_length); - - /* - * Change the current bucket to refer to what we read, - * even if we read nothing because we hit EOF. - */ - apr_bucket_pool_make(e, *str, *len, res->pool); - - /* If we have more to read from the field, then create another bucket */ - if (blength > 0) { - /* for efficiency, we can just build a new apr_bucket struct - * to wrap around the existing LOB bucket */ - b = apr_bucket_alloc(sizeof(*b), e->list); - b->start = boffset + *len; - b->length = blength; - b->data = a; - b->type = &apr_bucket_type_lob; - b->free = apr_bucket_free; - b->list = e->list; - APR_BUCKET_INSERT_AFTER(e, b); - } - else { - lob_bucket_destroy(a); - } - - return APR_SUCCESS; -} - -static apr_bucket *apr_bucket_lob_make(apr_bucket *b, - const apr_dbd_row_t *row, int col, - apr_off_t offset, apr_size_t len, - apr_pool_t *p) -{ - apr_bucket_lob *f; - - f = apr_bucket_alloc(sizeof(*f), b->list); - f->row = row; - f->col = col; - f->readpool = p; - - b = apr_bucket_shared_make(b, f, offset, len); - b->type = &apr_bucket_type_lob; - - return b; -} - -static apr_bucket *apr_bucket_lob_create(const apr_dbd_row_t *row, int col, - apr_off_t offset, - apr_size_t len, apr_pool_t *p, - apr_bucket_alloc_t *list) -{ - apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); - - APR_BUCKET_INIT(b); - b->free = apr_bucket_free; - b->list = list; - return apr_bucket_lob_make(b, row, col, offset, len, p); -} - -#endif - -static apr_status_t free_result(void *data) -{ - mysql_free_result(data); - return APR_SUCCESS; -} - -static int dbd_mysql_select(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **results, - const char *query, int seek) -{ - int sz; - int ret; - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - ret = mysql_query(sql->conn, query); - if (!ret) { - if (sz = mysql_field_count(sql->conn), sz > 0) { - if (!*results) { - *results = apr_palloc(pool, sizeof(apr_dbd_results_t)); - } - (*results)->random = seek; - (*results)->statement = NULL; -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - (*results)->pool = pool; -#endif - if (seek) { - (*results)->res = mysql_store_result(sql->conn); - } - else { - (*results)->res = mysql_use_result(sql->conn); - } - apr_pool_cleanup_register(pool, (*results)->res, - free_result,apr_pool_cleanup_null); - } - } else { - ret = mysql_errno(sql->conn); - } - -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - if (TXN_NOTICE_ERRORS(sql->trans)) { -#else - if (sql->trans) { -#endif - sql->trans->errnum = ret; - } - return ret; -} - -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) -static const char *dbd_mysql_get_name(const apr_dbd_results_t *res, int n) -{ - if ((n < 0) || (n >= mysql_num_fields(res->res))) { - return NULL; - } - - return mysql_fetch_fields(res->res)[n].name; -} -#endif - -static int dbd_mysql_get_row(apr_pool_t *pool, apr_dbd_results_t *res, - apr_dbd_row_t **row, int rownum) -{ - MYSQL_ROW r = NULL; - int ret = 0; - - if (res->statement) { - if (res->random) { - if (rownum >= 0) { - mysql_stmt_data_seek(res->statement, (my_ulonglong)rownum); - } - } - ret = mysql_stmt_fetch(res->statement); - switch (ret) { - case 1: - ret = mysql_stmt_errno(res->statement); - break; - case MYSQL_NO_DATA: - ret = -1; - break; - default: - ret = 0; /* bad luck - get_entry will deal with this */ - break; - } - } - else { - if (res->random) { - if (rownum >= 0) { - mysql_data_seek(res->res, (my_ulonglong) rownum); - } - } - r = mysql_fetch_row(res->res); - if (r == NULL) { - ret = -1; - } - } - if (ret == 0) { - if (!*row) { - *row = apr_palloc(pool, sizeof(apr_dbd_row_t)); - } - (*row)->row = r; - (*row)->res = res; -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - (*row)->len = mysql_fetch_lengths(res->res); -#endif - } - else { - apr_pool_cleanup_run(pool, res->res, free_result); - } - return ret; -} -#if 0 -/* An improved API that was proposed but not followed up */ -static int dbd_mysql_get_entry(const apr_dbd_row_t *row, int n, - apr_dbd_datum_t *val) -{ - MYSQL_BIND *bind; - if (row->res->statement) { - bind = &row->res->bind[n]; - if (mysql_stmt_fetch_column(row->res->statement, bind, n, 0) != 0) { - val->type = APR_DBD_VALUE_NULL; - return -1; - } - if (*bind->is_null) { - val->type = APR_DBD_VALUE_NULL; - return -1; - } - else { - val->type = APR_DBD_VALUE_STRING; - val->value.stringval = bind->buffer; - } - } - else { - val->type = APR_DBD_VALUE_STRING; - val->value.stringval = row->row[n]; - } - return 0; -} -#else - -static const char *dbd_mysql_get_entry(const apr_dbd_row_t *row, int n) -{ - MYSQL_BIND *bind; - if (row->res->statement) { - bind = &row->res->bind[n]; - if (mysql_stmt_fetch_column(row->res->statement, bind, n, 0) != 0) { - return NULL; - } - if (*bind->is_null) { - return NULL; - } - else { - return bind->buffer; - } - } - else { - return row->row[n]; - } - return NULL; -} -#endif - -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) -static apr_status_t dbd_mysql_datum_get(const apr_dbd_row_t *row, int n, - apr_dbd_type_e type, void *data) -{ - if (row->res->statement) { - MYSQL_BIND *bind = &row->res->bind[n]; - unsigned long len = *bind->length; - - if (mysql_stmt_fetch_column(row->res->statement, bind, n, 0) != 0) { - return APR_EGENERAL; - } - - if (*bind->is_null) { - return APR_ENOENT; - } - - switch (type) { - case APR_DBD_TYPE_TINY: - *(char*)data = atoi(bind->buffer); - break; - case APR_DBD_TYPE_UTINY: - *(unsigned char*)data = atoi(bind->buffer); - break; - case APR_DBD_TYPE_SHORT: - *(short*)data = atoi(bind->buffer); - break; - case APR_DBD_TYPE_USHORT: - *(unsigned short*)data = atoi(bind->buffer); - break; - case APR_DBD_TYPE_INT: - *(int*)data = atoi(bind->buffer); - break; - case APR_DBD_TYPE_UINT: - *(unsigned int*)data = atoi(bind->buffer); - break; - case APR_DBD_TYPE_LONG: - *(long*)data = atol(bind->buffer); - break; - case APR_DBD_TYPE_ULONG: - *(unsigned long*)data = atol(bind->buffer); - break; - case APR_DBD_TYPE_LONGLONG: - *(apr_int64_t*)data = apr_atoi64(bind->buffer); - break; - case APR_DBD_TYPE_ULONGLONG: - *(apr_uint64_t*)data = apr_atoi64(bind->buffer); - break; - case APR_DBD_TYPE_FLOAT: - *(float*)data = atof(bind->buffer); - break; - case APR_DBD_TYPE_DOUBLE: - *(double*)data = atof(bind->buffer); - 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*)bind->buffer+bind->buffer_length-1) = '\0'; - *(char**)data = bind->buffer; - 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_lob_create(row, n, 0, len, - 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; - } - } - else { - if (row->row[n] == NULL) { - return APR_ENOENT; - } - - switch (type) { - case APR_DBD_TYPE_TINY: - *(char*)data = atoi(row->row[n]); - break; - case APR_DBD_TYPE_UTINY: - *(unsigned char*)data = atoi(row->row[n]); - break; - case APR_DBD_TYPE_SHORT: - *(short*)data = atoi(row->row[n]); - break; - case APR_DBD_TYPE_USHORT: - *(unsigned short*)data = atoi(row->row[n]); - break; - case APR_DBD_TYPE_INT: - *(int*)data = atoi(row->row[n]); - break; - case APR_DBD_TYPE_UINT: - *(unsigned int*)data = atoi(row->row[n]); - break; - case APR_DBD_TYPE_LONG: - *(long*)data = atol(row->row[n]); - break; - case APR_DBD_TYPE_ULONG: - *(unsigned long*)data = atol(row->row[n]); - break; - case APR_DBD_TYPE_LONGLONG: - *(apr_int64_t*)data = apr_atoi64(row->row[n]); - break; - case APR_DBD_TYPE_ULONGLONG: - *(apr_uint64_t*)data = apr_atoi64(row->row[n]); - break; - case APR_DBD_TYPE_FLOAT: - *(float*)data = atof(row->row[n]); - break; - case APR_DBD_TYPE_DOUBLE: - *(double*)data = atof(row->row[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->row[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->row[n], row->len[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 0; -} -#endif - -static const char *dbd_mysql_error(apr_dbd_t *sql, int n) -{ - return mysql_error(sql->conn); -} - -static int dbd_mysql_query(apr_dbd_t *sql, int *nrows, const char *query) -{ - int ret; - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - ret = mysql_query(sql->conn, query); - if (ret != 0) { - ret = mysql_errno(sql->conn); - } - *nrows = mysql_affected_rows(sql->conn); -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - if (TXN_NOTICE_ERRORS(sql->trans)) { -#else - if (sql->trans) { -#endif - sql->trans->errnum = ret; - } - return ret; -} - -static const char *dbd_mysql_escape(apr_pool_t *pool, const char *arg, - apr_dbd_t *sql) -{ - unsigned long len = strlen(arg); - char *ret = apr_palloc(pool, 2*len + 1); - mysql_real_escape_string(sql->conn, ret, arg, len); - return ret; -} - -static apr_status_t stmt_close(void *data) -{ - mysql_stmt_close(data); - return APR_SUCCESS; -} - -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) -static int dbd_mysql_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) -{ - /* Translate from apr_dbd to native query format */ - int ret; - - if (!*statement) { - *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t)); - } - (*statement)->stmt = mysql_stmt_init(sql->conn); - - if ((*statement)->stmt) { - apr_pool_cleanup_register(pool, (*statement)->stmt, - stmt_close, apr_pool_cleanup_null); - ret = mysql_stmt_prepare((*statement)->stmt, query, strlen(query)); - - if (ret != 0) { - ret = mysql_stmt_errno((*statement)->stmt); - } - - (*statement)->nargs = nargs; - (*statement)->nvals = nvals; - (*statement)->types = types; - - return ret; - } - - return CR_OUT_OF_MEMORY; -} - -static void dbd_mysql_bind(apr_dbd_prepared_t *statement, - const char **values, MYSQL_BIND *bind) -{ - int i, j; - - for (i = 0, j = 0; i < statement->nargs; i++, j++) { - bind[i].length = &bind[i].buffer_length; - bind[i].is_unsigned = 0; - bind[i].is_null = NULL; - - if (values[j] == NULL) { - bind[i].buffer_type = MYSQL_TYPE_NULL; - } - else { - switch (statement->types[i]) { - case APR_DBD_TYPE_BLOB: - case APR_DBD_TYPE_CLOB: - bind[i].buffer_type = MYSQL_TYPE_LONG_BLOB; - bind[i].buffer = (void*)values[j]; - bind[i].buffer_length = atol(values[++j]); - - /* skip table and column */ - j += 2; - break; - default: - bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - bind[i].buffer = (void*)values[j]; - bind[i].buffer_length = strlen(values[j]); - break; - } - } - } - - return; -} - -static int dbd_mysql_pquery_internal(apr_pool_t *pool, apr_dbd_t *sql, - int *nrows, apr_dbd_prepared_t *statement, - MYSQL_BIND *bind) -{ - int ret; - - ret = mysql_stmt_bind_param(statement->stmt, bind); - if (ret != 0) { - *nrows = 0; - ret = mysql_stmt_errno(statement->stmt); - } - else { - ret = mysql_stmt_execute(statement->stmt); - if (ret != 0) { - ret = mysql_stmt_errno(statement->stmt); - } - *nrows = mysql_stmt_affected_rows(statement->stmt); - } - - return ret; -} - -static int dbd_mysql_pquery(apr_pool_t *pool, apr_dbd_t *sql, - int *nrows, apr_dbd_prepared_t *statement, - const char **values) -{ - MYSQL_BIND *bind; - int ret; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - bind = apr_palloc(pool, statement->nargs * sizeof(MYSQL_BIND)); - - dbd_mysql_bind(statement, values, bind); - - ret = dbd_mysql_pquery_internal(pool, sql, nrows, statement, bind); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_mysql_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_mysql_pquery(pool, sql, nrows, statement, values); -} - -static int dbd_mysql_pselect_internal(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **res, - apr_dbd_prepared_t *statement, - int random, MYSQL_BIND *bind) -{ - int nfields, i; - my_bool *is_nullr; -#if MYSQL_VERSION_ID >= 50000 - my_bool *error; -#endif - int ret; - unsigned long *length, maxlen; - - ret = mysql_stmt_bind_param(statement->stmt, bind); - if (ret == 0) { - ret = mysql_stmt_execute(statement->stmt); - if (!ret) { - if (!*res) { - *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); - } - (*res)->random = random; - (*res)->statement = statement->stmt; - (*res)->res = mysql_stmt_result_metadata(statement->stmt); - (*res)->pool = pool; - apr_pool_cleanup_register(pool, (*res)->res, - free_result, apr_pool_cleanup_null); - nfields = mysql_num_fields((*res)->res); - if (!(*res)->bind) { - (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND)); - length = apr_pcalloc(pool, nfields*sizeof(unsigned long)); -#if MYSQL_VERSION_ID >= 50000 - error = apr_palloc(pool, nfields*sizeof(my_bool)); -#endif - is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool)); - for ( i = 0; i < nfields; ++i ) { - maxlen = ((*res)->res->fields[i].length < sql->fldsz ? - (*res)->res->fields[i].length : sql->fldsz) + 1; - if ((*res)->res->fields[i].type == MYSQL_TYPE_BLOB) { - (*res)->bind[i].buffer_type = MYSQL_TYPE_LONG_BLOB; - } - else { - (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - } - (*res)->bind[i].buffer_length = maxlen; - (*res)->bind[i].length = &length[i]; - (*res)->bind[i].buffer = apr_palloc(pool, maxlen); - (*res)->bind[i].is_null = is_nullr+i; -#if MYSQL_VERSION_ID >= 50000 - (*res)->bind[i].error = error+i; -#endif - } - } - ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind); - if (!ret) { - ret = mysql_stmt_store_result(statement->stmt); - } - } - } - if (ret != 0) { - ret = mysql_stmt_errno(statement->stmt); - } - - return ret; -} - -static int dbd_mysql_pselect(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **res, - apr_dbd_prepared_t *statement, int random, - const char **args) -{ - int ret; - MYSQL_BIND *bind; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - bind = apr_palloc(pool, statement->nargs * sizeof(MYSQL_BIND)); - - dbd_mysql_bind(statement, args, bind); - - ret = dbd_mysql_pselect_internal(pool, sql, res, statement, random, bind); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_mysql_pvselect(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **res, - apr_dbd_prepared_t *statement, int random, - 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_mysql_pselect(pool, sql, res, statement, random, values); -} - -static void dbd_mysql_bbind(apr_pool_t *pool, apr_dbd_prepared_t *statement, - const void **values, MYSQL_BIND *bind) -{ - void *arg; - int i, j; - apr_dbd_type_e type; - - for (i = 0, j = 0; i < statement->nargs; i++, j++) { - arg = (void *)values[j]; - - bind[i].length = &bind[i].buffer_length; - bind[i].is_null = NULL; - - type = (arg == NULL ? APR_DBD_TYPE_NULL : statement->types[i]); - switch (type) { - case APR_DBD_TYPE_TINY: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_TINY; - bind[i].is_unsigned = 0; - break; - case APR_DBD_TYPE_UTINY: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_TINY; - bind[i].is_unsigned = 1; - break; - case APR_DBD_TYPE_SHORT: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_SHORT; - bind[i].is_unsigned = 0; - break; - case APR_DBD_TYPE_USHORT: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_SHORT; - bind[i].is_unsigned = 1; - break; - case APR_DBD_TYPE_INT: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_LONG; - bind[i].is_unsigned = 0; - break; - case APR_DBD_TYPE_UINT: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_LONG; - bind[i].is_unsigned = 1; - break; - case APR_DBD_TYPE_LONG: - if (sizeof(int) == sizeof(long)) { - bind[i].buffer = arg; - } - else { - bind[i].buffer = apr_palloc(pool, sizeof(int)); - *(int*)bind[i].buffer = *(long*)arg; - } - bind[i].buffer_type = MYSQL_TYPE_LONG; - bind[i].is_unsigned = 0; - break; - case APR_DBD_TYPE_ULONG: - if (sizeof(unsigned int) == sizeof(unsigned long)) { - bind[i].buffer = arg; - } - else { - bind[i].buffer = apr_palloc(pool, sizeof(unsigned int)); - *(unsigned int*)bind[i].buffer = *(unsigned long*)arg; - } - bind[i].buffer_type = MYSQL_TYPE_LONG; - bind[i].is_unsigned = 1; - break; - case APR_DBD_TYPE_LONGLONG: - if (sizeof(long long) == sizeof(apr_int64_t)) { - bind[i].buffer = arg; - } - else { - bind[i].buffer = apr_palloc(pool, sizeof(long long)); - *(long long*)bind[i].buffer = *(apr_int64_t*)arg; - } - bind[i].buffer_type = MYSQL_TYPE_LONGLONG; - bind[i].is_unsigned = 0; - break; - case APR_DBD_TYPE_ULONGLONG: - if (sizeof(unsigned long long) == sizeof(apr_uint64_t)) { - bind[i].buffer = arg; - } - else { - bind[i].buffer = apr_palloc(pool, sizeof(unsigned long long)); - *(unsigned long long*)bind[i].buffer = *(apr_uint64_t*)arg; - } - bind[i].buffer_type = MYSQL_TYPE_LONGLONG; - bind[i].is_unsigned = 1; - break; - case APR_DBD_TYPE_FLOAT: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_FLOAT; - bind[i].is_unsigned = 0; - break; - case APR_DBD_TYPE_DOUBLE: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_DOUBLE; - bind[i].is_unsigned = 0; - 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: - bind[i].buffer = arg; - bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - bind[i].is_unsigned = 0; - bind[i].buffer_length = strlen((const char *)arg); - break; - case APR_DBD_TYPE_BLOB: - case APR_DBD_TYPE_CLOB: - bind[i].buffer = (void *)arg; - bind[i].buffer_type = MYSQL_TYPE_LONG_BLOB; - bind[i].is_unsigned = 0; - bind[i].buffer_length = *(apr_size_t*)values[++j]; - - /* skip table and column */ - j += 2; - break; - case APR_DBD_TYPE_NULL: - default: - bind[i].buffer_type = MYSQL_TYPE_NULL; - break; - } - } - - return; -} - -static int dbd_mysql_pbquery(apr_pool_t *pool, apr_dbd_t *sql, - int *nrows, apr_dbd_prepared_t *statement, - const void **values) -{ - MYSQL_BIND *bind; - int ret; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - bind = apr_palloc(pool, statement->nargs * sizeof(MYSQL_BIND)); - - dbd_mysql_bbind(pool, statement, values, bind); - - ret = dbd_mysql_pquery_internal(pool, sql, nrows, statement, bind); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_mysql_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_mysql_pbquery(pool, sql, nrows, statement, values); -} - -static int dbd_mysql_pbselect(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **res, - apr_dbd_prepared_t *statement, int random, - const void **args) -{ - int ret; - MYSQL_BIND *bind; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - bind = apr_palloc(pool, statement->nargs * sizeof(MYSQL_BIND)); - - dbd_mysql_bbind(pool, statement, args, bind); - - ret = dbd_mysql_pselect_internal(pool, sql, res, statement, random, bind); - - if (TXN_NOTICE_ERRORS(sql->trans)) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_mysql_pvbselect(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **res, - apr_dbd_prepared_t *statement, int random, - 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_mysql_pbselect(pool, sql, res, statement, random, values); -} -#else -static int dbd_mysql_prepare(apr_pool_t *pool, apr_dbd_t *sql, - const char *query, const char *label, - apr_dbd_prepared_t **statement) -{ - /* Translate from apr_dbd to native query format */ - char *myquery = apr_pstrdup(pool, query); - char *p = myquery; - const char *q; - int ret; - for (q = query; *q; ++q) { - if (q[0] == '%') { - if (isalpha(q[1])) { - *p++ = '?'; - ++q; - } - else if (q[1] == '%') { - /* reduce %% to % */ - *p++ = *q++; - } - else { - *p++ = *q; - } - } - else { - *p++ = *q; - } - } - *p = 0; - if (!*statement) { - *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t)); - } - (*statement)->stmt = mysql_stmt_init(sql->conn); - - if ((*statement)->stmt) { - apr_pool_cleanup_register(pool, (*statement)->stmt, - stmt_close, apr_pool_cleanup_null); - ret = mysql_stmt_prepare((*statement)->stmt, myquery, strlen(myquery)); - - if (ret != 0) { - ret = mysql_stmt_errno((*statement)->stmt); - } - - return ret; - } - - return CR_OUT_OF_MEMORY; -} - -static int dbd_mysql_pquery(apr_pool_t *pool, apr_dbd_t *sql, - int *nrows, apr_dbd_prepared_t *statement, - int nargs, const char **values) -{ - MYSQL_BIND *bind; - char *arg; - int ret; - int i; - my_bool is_null = FALSE; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - nargs = mysql_stmt_param_count(statement->stmt); - - bind = apr_palloc(pool, nargs*sizeof(MYSQL_BIND)); - for (i=0; i < nargs; ++i) { - arg = (char*)values[i]; - bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - bind[i].buffer = arg; - bind[i].buffer_length = strlen(arg); - bind[i].length = &bind[i].buffer_length; - bind[i].is_null = &is_null; - bind[i].is_unsigned = 0; - } - - ret = mysql_stmt_bind_param(statement->stmt, bind); - if (ret != 0) { - *nrows = 0; - ret = mysql_stmt_errno(statement->stmt); - } - else { - ret = mysql_stmt_execute(statement->stmt); - if (ret != 0) { - ret = mysql_stmt_errno(statement->stmt); - } - *nrows = mysql_stmt_affected_rows(statement->stmt); - } - if (sql->trans) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_mysql_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows, - apr_dbd_prepared_t *statement, va_list args) -{ - MYSQL_BIND *bind; - char *arg; - int ret; - int nargs = 0; - int i; - my_bool is_null = FALSE; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - nargs = mysql_stmt_param_count(statement->stmt); - - bind = apr_palloc(pool, nargs*sizeof(MYSQL_BIND)); - for (i=0; i < nargs; ++i) { - arg = va_arg(args, char*); - bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - bind[i].buffer = arg; - bind[i].buffer_length = strlen(arg); - bind[i].length = &bind[i].buffer_length; - bind[i].is_null = &is_null; - bind[i].is_unsigned = 0; - } - - ret = mysql_stmt_bind_param(statement->stmt, bind); - if (ret != 0) { - *nrows = 0; - ret = mysql_stmt_errno(statement->stmt); - } - else { - ret = mysql_stmt_execute(statement->stmt); - if (ret != 0) { - ret = mysql_stmt_errno(statement->stmt); - } - *nrows = mysql_stmt_affected_rows(statement->stmt); - } - if (sql->trans) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_mysql_pselect(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **res, - apr_dbd_prepared_t *statement, int random, - int nargs, const char **args) -{ - int i; - int nfields; - char *arg; - my_bool is_null = FALSE; - my_bool *is_nullr; -#if MYSQL_VERSION_ID >= 50000 - my_bool *error; -#endif - int ret; - unsigned long *length, maxlen; - MYSQL_BIND *bind; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - nargs = mysql_stmt_param_count(statement->stmt); - bind = apr_palloc(pool, nargs*sizeof(MYSQL_BIND)); - - for (i=0; i < nargs; ++i) { - arg = (char*)args[i]; - bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - bind[i].buffer = arg; - bind[i].buffer_length = strlen(arg); - bind[i].length = &bind[i].buffer_length; - bind[i].is_null = &is_null; - bind[i].is_unsigned = 0; - } - - ret = mysql_stmt_bind_param(statement->stmt, bind); - if (ret == 0) { - ret = mysql_stmt_execute(statement->stmt); - if (!ret) { - if (!*res) { - *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); - } - (*res)->random = random; - (*res)->statement = statement->stmt; - (*res)->res = mysql_stmt_result_metadata(statement->stmt); - apr_pool_cleanup_register(pool, (*res)->res, - free_result, apr_pool_cleanup_null); - nfields = mysql_num_fields((*res)->res); - if (!(*res)->bind) { - (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND)); - length = apr_pcalloc(pool, nfields*sizeof(unsigned long)); -#if MYSQL_VERSION_ID >= 50000 - error = apr_palloc(pool, nfields*sizeof(my_bool)); -#endif - is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool)); - for ( i = 0; i < nfields; ++i ) { - maxlen = ((*res)->res->fields[i].length < sql->fldsz ? - (*res)->res->fields[i].length : sql->fldsz) + 1; - (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - (*res)->bind[i].buffer_length = maxlen; - (*res)->bind[i].length = &length[i]; - (*res)->bind[i].buffer = apr_palloc(pool, maxlen); - (*res)->bind[i].is_null = is_nullr+i; -#if MYSQL_VERSION_ID >= 50000 - (*res)->bind[i].error = error+i; -#endif - } - } - ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind); - if (!ret) { - ret = mysql_stmt_store_result(statement->stmt); - } - } - } - if (ret != 0) { - ret = mysql_stmt_errno(statement->stmt); - } - if (sql->trans) { - sql->trans->errnum = ret; - } - return ret; -} - -static int dbd_mysql_pvselect(apr_pool_t *pool, apr_dbd_t *sql, - apr_dbd_results_t **res, - apr_dbd_prepared_t *statement, int random, - va_list args) -{ - int i; - int nfields; - char *arg; - my_bool is_null = FALSE; - my_bool *is_nullr; -#if MYSQL_VERSION_ID >= 50000 - my_bool *error; -#endif - int ret; - unsigned long *length, maxlen; - int nargs; - MYSQL_BIND *bind; - - if (sql->trans && sql->trans->errnum) { - return sql->trans->errnum; - } - - nargs = mysql_stmt_param_count(statement->stmt); - bind = apr_palloc(pool, nargs*sizeof(MYSQL_BIND)); - - for (i=0; i < nargs; ++i) { - arg = va_arg(args, char*); - bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - bind[i].buffer = arg; - bind[i].buffer_length = strlen(arg); - bind[i].length = &bind[i].buffer_length; - bind[i].is_null = &is_null; - bind[i].is_unsigned = 0; - } - - ret = mysql_stmt_bind_param(statement->stmt, bind); - if (ret == 0) { - ret = mysql_stmt_execute(statement->stmt); - if (!ret) { - if (!*res) { - *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); - } - (*res)->random = random; - (*res)->statement = statement->stmt; - (*res)->res = mysql_stmt_result_metadata(statement->stmt); - apr_pool_cleanup_register(pool, (*res)->res, - free_result, apr_pool_cleanup_null); - nfields = mysql_num_fields((*res)->res); - if (!(*res)->bind) { - (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND)); - length = apr_pcalloc(pool, nfields*sizeof(unsigned long)); -#if MYSQL_VERSION_ID >= 50000 - error = apr_palloc(pool, nfields*sizeof(my_bool)); -#endif - is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool)); - for ( i = 0; i < nfields; ++i ) { - maxlen = ((*res)->res->fields[i].length < sql->fldsz ? - (*res)->res->fields[i].length : sql->fldsz) + 1; - (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; - (*res)->bind[i].buffer_length = maxlen; - (*res)->bind[i].length = &length[i]; - (*res)->bind[i].buffer = apr_palloc(pool, maxlen); - (*res)->bind[i].is_null = is_nullr+i; -#if MYSQL_VERSION_ID >= 50000 - (*res)->bind[i].error = error+i; -#endif - } - } - ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind); - if (!ret) { - ret = mysql_stmt_store_result(statement->stmt); - } - } - } - if (ret != 0) { - ret = mysql_stmt_errno(statement->stmt); - } - if (sql->trans) { - sql->trans->errnum = ret; - } - return ret; -} -#endif - -static int dbd_mysql_end_transaction(apr_dbd_transaction_t *trans) -{ - int ret = -1; - if (trans) { -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - /* rollback on error or explicit rollback request */ - if (trans->errnum || TXN_DO_ROLLBACK(trans)) { -#else - if (trans->errnum) { -#endif - trans->errnum = 0; - ret = mysql_rollback(trans->handle->conn); - } - else { - ret = mysql_commit(trans->handle->conn); - } - } - ret |= mysql_autocommit(trans->handle->conn, 1); - trans->handle->trans = NULL; - return ret; -} -/* Whether or not transactions work depends on whether the - * underlying DB supports them within MySQL. Unfortunately - * it fails silently with the default InnoDB. - */ - -static int dbd_mysql_transaction(apr_pool_t *pool, apr_dbd_t *handle, - apr_dbd_transaction_t **trans) -{ - /* Don't try recursive transactions here */ - if (handle->trans) { - dbd_mysql_end_transaction(handle->trans) ; - } - if (!*trans) { - *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t)); - } - (*trans)->errnum = mysql_autocommit(handle->conn, 0); - (*trans)->handle = handle; - handle->trans = *trans; - return (*trans)->errnum; -} - -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) -static int dbd_mysql_transaction_mode_get(apr_dbd_transaction_t *trans) -{ - if (!trans) - return APR_DBD_TRANSACTION_COMMIT; - - return trans->mode; -} - -static int dbd_mysql_transaction_mode_set(apr_dbd_transaction_t *trans, - int mode) -{ - if (!trans) - return APR_DBD_TRANSACTION_COMMIT; - - return trans->mode = (mode & TXN_MODE_BITS); -} -#endif - -static apr_dbd_t *dbd_mysql_open(apr_pool_t *pool, const char *params) -{ - static const char *const delims = " \r\n\t;|,"; - const char *ptr; - int i; - const char *key; - size_t klen; - const char *value; - size_t vlen; -#if MYSQL_VERSION_ID >= 50013 - my_bool do_reconnect = 1; -#endif - MYSQL *real_conn; - unsigned long flags = 0; - - struct { - const char *field; - const char *value; - } fields[] = { - {"host", NULL}, - {"user", NULL}, - {"pass", NULL}, - {"dbname", NULL}, - {"port", NULL}, - {"sock", NULL}, - {"flags", NULL}, - {"fldsz", NULL}, - {NULL, NULL} - }; - unsigned int port = 0; - apr_dbd_t *sql = apr_pcalloc(pool, sizeof(apr_dbd_t)); - sql->fldsz = FIELDSIZE; - sql->conn = mysql_init(sql->conn); - if ( sql->conn == NULL ) { - return NULL; - } - for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) { - for (key = ptr-1; isspace(*key); --key); - klen = 0; - while (isalpha(*key)) { - /* don't parse backwards off the start of the string */ - if (key == params) { - --key; - ++klen; - break; - } - --key; - ++klen; - } - ++key; - for (value = ptr+1; isspace(*value); ++value); - vlen = strcspn(value, delims); - for (i = 0; fields[i].field != NULL; i++) { - if (!strncasecmp(fields[i].field, key, klen)) { - fields[i].value = apr_pstrndup(pool, value, vlen); - break; - } - } - ptr = value+vlen; - } - if (fields[4].value != NULL) { - port = atoi(fields[4].value); - } - if (fields[6].value != NULL && - !strcmp(fields[6].value, "CLIENT_FOUND_ROWS")) { - flags |= CLIENT_FOUND_ROWS; /* only option we know */ - } - if (fields[7].value != NULL) { - sql->fldsz = atol(fields[7].value); - } - -#if MYSQL_VERSION_ID >= 50013 - /* the MySQL manual says this should be BEFORE mysql_real_connect */ - mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect); -#endif - - real_conn = mysql_real_connect(sql->conn, fields[0].value, - fields[1].value, fields[2].value, - fields[3].value, port, - fields[5].value, flags); - - if(real_conn == NULL) { - mysql_close(sql->conn); - return NULL; - } - -#if MYSQL_VERSION_ID >= 50013 - /* Some say this should be AFTER mysql_real_connect */ - mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect); -#endif - - return sql; -} - -static apr_status_t dbd_mysql_close(apr_dbd_t *handle) -{ - mysql_close(handle->conn); - return APR_SUCCESS; -} - -static apr_status_t dbd_mysql_check_conn(apr_pool_t *pool, - apr_dbd_t *handle) -{ - return mysql_ping(handle->conn) ? APR_EGENERAL : APR_SUCCESS; -} - -static int dbd_mysql_select_db(apr_pool_t *pool, apr_dbd_t* handle, - const char* name) -{ - return mysql_select_db(handle->conn, name); -} - -static void *dbd_mysql_native(apr_dbd_t *handle) -{ - return handle->conn; -} - -static int dbd_mysql_num_cols(apr_dbd_results_t *res) -{ - if (res->statement) { - return mysql_stmt_field_count(res->statement); - } - else { - return mysql_num_fields(res->res); - } -} - -static int dbd_mysql_num_tuples(apr_dbd_results_t *res) -{ - if (res->random) { - if (res->statement) { - return (int) mysql_stmt_num_rows(res->statement); - } - else { - return (int) mysql_num_rows(res->res); - } - } - else { - return -1; - } -} - -static apr_status_t thread_end(void *data) -{ - mysql_thread_end(); - return APR_SUCCESS; -} - -static void dbd_mysql_init(apr_pool_t *pool) -{ - my_init(); - /* FIXME: this is a guess; find out what it really does */ - apr_pool_cleanup_register(pool, NULL, thread_end, apr_pool_cleanup_null); -} -APU_DECLARE_DATA const apr_dbd_driver_t apr_dbd_mysql_driver = { - "mysql", - dbd_mysql_init, - dbd_mysql_native, - dbd_mysql_open, - dbd_mysql_check_conn, - dbd_mysql_close, - dbd_mysql_select_db, - dbd_mysql_transaction, - dbd_mysql_end_transaction, - dbd_mysql_query, - dbd_mysql_select, - dbd_mysql_num_cols, - dbd_mysql_num_tuples, - dbd_mysql_get_row, - dbd_mysql_get_entry, - dbd_mysql_error, - dbd_mysql_escape, - dbd_mysql_prepare, - dbd_mysql_pvquery, - dbd_mysql_pvselect, - dbd_mysql_pquery, - dbd_mysql_pselect -#if APU_MAJOR_VERSION >= 2 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) - , - dbd_mysql_get_name, - dbd_mysql_transaction_mode_get, - dbd_mysql_transaction_mode_set, - "?", - dbd_mysql_pvbquery, - dbd_mysql_pvbselect, - dbd_mysql_pbquery, - dbd_mysql_pbselect, - dbd_mysql_datum_get -#endif -}; - -#endif |