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.
20
#include "apr_pools.h"
21
#include "apr_dbd_internal.h"
24
#include "apr_thread_mutex.h"
26
#include "apr_strings.h"
28
static apr_hash_t *drivers = NULL;
30
#define CLEANUP_CAST (apr_status_t (*)(void*))
32
/* Once the autofoo supports building it for dynamic load, we can use
33
* #define APR_DSO_BUILD APR_HAS_DSO
38
static apr_thread_mutex_t* mutex = NULL;
41
#define DRIVER_LOAD(name,driver,pool) \
43
extern const apr_dbd_driver_t driver; \
44
apr_hash_set(drivers,name,APR_HASH_KEY_STRING,&driver); \
51
static apr_status_t apr_dbd_term(void *ptr)
53
/* set drivers to NULL so init can work again */
56
/* Everything else we need is handled by cleanups registered
57
* when we created mutexes and loaded DSOs
62
APU_DECLARE(apr_status_t) apr_dbd_init(apr_pool_t *pool)
64
apr_status_t ret = APR_SUCCESS;
66
if (drivers != NULL) {
69
drivers = apr_hash_make(pool);
70
apr_pool_cleanup_register(pool, NULL, apr_dbd_term,
71
apr_pool_cleanup_null);
76
ret = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool);
77
/* This already registers a pool cleanup */
83
DRIVER_LOAD("mysql", apr_dbd_mysql_driver, pool);
86
DRIVER_LOAD("pgsql", apr_dbd_pgsql_driver, pool);
89
DRIVER_LOAD("sqlite3", apr_dbd_sqlite3_driver, pool);
92
DRIVER_LOAD("sqlite2", apr_dbd_sqlite2_driver, pool);
94
#if APU_HAVE_SOME_OTHER_BACKEND
95
DRIVER_LOAD("firebird", apr_dbd_other_driver, pool);
100
APU_DECLARE(apr_status_t) apr_dbd_get_driver(apr_pool_t *pool, const char *name,
101
const apr_dbd_driver_t **driver)
105
apr_dso_handle_t *dlhandle = NULL;
109
*driver = apr_hash_get(drivers, name, APR_HASH_KEY_STRING);
117
rv = apr_thread_mutex_lock(mutex);
118
if (rv != APR_SUCCESS) {
121
*driver = apr_hash_get(drivers, name, APR_HASH_KEY_STRING);
128
sprintf(path, "apr_dbd_%s.dll", name);
130
sprintf(path, "apr_dbd_%s.so", name);
132
rv = apr_dso_load(&dlhandle, path, pool);
133
if (rv != APR_SUCCESS) { /* APR_EDSOOPEN */
136
sprintf(path, "apr_dbd_%s_driver", name);
137
rv = apr_dso_sym((void*)driver, dlhandle, path);
138
if (rv != APR_SUCCESS) { /* APR_ESYMNOTFOUND */
139
apr_dso_unload(dlhandle);
142
if ((*driver)->init) {
143
(*driver)->init(pool);
145
apr_hash_set(drivers, name, APR_HASH_KEY_STRING, *driver);
149
apr_thread_mutex_unlock(mutex);
152
#else /* APR_DSO_BUILD - so if it wasn't already loaded, it's NOTIMPL */
158
APU_DECLARE(apr_status_t) apr_dbd_open(const apr_dbd_driver_t *driver,
159
apr_pool_t *pool, const char *params,
163
*handle = driver->open(pool, params);
164
if (*handle == NULL) {
167
rv = apr_dbd_check_conn(driver, pool, *handle);
168
if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) {
169
apr_dbd_close(driver, *handle);
174
APU_DECLARE(int) apr_dbd_transaction_start(const apr_dbd_driver_t *driver,
175
apr_pool_t *pool, apr_dbd_t *handle,
176
apr_dbd_transaction_t **trans)
178
int ret = driver->start_transaction(pool, handle, trans);
180
apr_pool_cleanup_register(pool, *trans,
181
CLEANUP_CAST driver->end_transaction,
182
apr_pool_cleanup_null);
186
APU_DECLARE(int) apr_dbd_transaction_end(const apr_dbd_driver_t *driver,
188
apr_dbd_transaction_t *trans)
190
apr_pool_cleanup_kill(pool, trans, CLEANUP_CAST driver->end_transaction);
191
return driver->end_transaction(trans);
194
APU_DECLARE(apr_status_t) apr_dbd_close(const apr_dbd_driver_t *driver,
197
return driver->close(handle);
199
APU_DECLARE(const char*) apr_dbd_name(const apr_dbd_driver_t *driver)
203
APU_DECLARE(void*) apr_dbd_native_handle(const apr_dbd_driver_t *driver,
206
return driver->native_handle(handle);
208
APU_DECLARE(int) apr_dbd_check_conn(const apr_dbd_driver_t *driver, apr_pool_t *pool,
211
return driver->check_conn(pool, handle);
213
APU_DECLARE(int) apr_dbd_set_dbname(const apr_dbd_driver_t *driver, apr_pool_t *pool,
214
apr_dbd_t *handle, const char *name)
216
return driver->set_dbname(pool,handle,name);
218
APU_DECLARE(int) apr_dbd_query(const apr_dbd_driver_t *driver, apr_dbd_t *handle,
219
int *nrows, const char *statement)
221
return driver->query(handle,nrows,statement);
223
APU_DECLARE(int) apr_dbd_select(const apr_dbd_driver_t *driver, apr_pool_t *pool,
224
apr_dbd_t *handle, apr_dbd_results_t **res,
225
const char *statement, int random)
227
return driver->select(pool,handle,res,statement,random);
229
APU_DECLARE(int) apr_dbd_num_cols(const apr_dbd_driver_t *driver,
230
apr_dbd_results_t *res)
232
return driver->num_cols(res);
234
APU_DECLARE(int) apr_dbd_num_tuples(const apr_dbd_driver_t *driver,
235
apr_dbd_results_t *res)
237
return driver->num_tuples(res);
239
APU_DECLARE(int) apr_dbd_get_row(const apr_dbd_driver_t *driver, apr_pool_t *pool,
240
apr_dbd_results_t *res, apr_dbd_row_t **row,
243
return driver->get_row(pool,res,row,rownum);
245
APU_DECLARE(const char*) apr_dbd_get_entry(const apr_dbd_driver_t *driver,
246
apr_dbd_row_t *row, int col)
248
return driver->get_entry(row,col);
250
APU_DECLARE(const char*) apr_dbd_error(const apr_dbd_driver_t *driver,
251
apr_dbd_t *handle, int errnum)
253
return driver->error(handle,errnum);
255
APU_DECLARE(const char*) apr_dbd_escape(const apr_dbd_driver_t *driver,
256
apr_pool_t *pool, const char *string,
259
return driver->escape(pool,string,handle);
261
APU_DECLARE(int) apr_dbd_prepare(const apr_dbd_driver_t *driver, apr_pool_t *pool,
262
apr_dbd_t *handle, const char *query,
264
apr_dbd_prepared_t **statement)
266
return driver->prepare(pool,handle,query,label,statement);
268
APU_DECLARE(int) apr_dbd_pquery(const apr_dbd_driver_t *driver, apr_pool_t *pool,
269
apr_dbd_t *handle, int *nrows,
270
apr_dbd_prepared_t *statement, int nargs,
273
return driver->pquery(pool,handle,nrows,statement,nargs,args);
275
APU_DECLARE(int) apr_dbd_pselect(const apr_dbd_driver_t *driver, apr_pool_t *pool,
276
apr_dbd_t *handle, apr_dbd_results_t **res,
277
apr_dbd_prepared_t *statement, int random,
278
int nargs, const char **args)
280
return driver->pselect(pool,handle,res,statement,random,nargs,args);
282
APU_DECLARE(int) apr_dbd_pvquery(const apr_dbd_driver_t *driver, apr_pool_t *pool,
283
apr_dbd_t *handle, int *nrows,
284
apr_dbd_prepared_t *statement,...)
288
va_start(args, statement);
289
ret = driver->pvquery(pool,handle,nrows,statement,args);
293
APU_DECLARE(int) apr_dbd_pvselect(const apr_dbd_driver_t *driver, apr_pool_t *pool,
294
apr_dbd_t *handle, apr_dbd_results_t **res,
295
apr_dbd_prepared_t *statement, int random,...)
299
va_start(args, random);
300
ret = driver->pvselect(pool,handle,res,statement,random,args);