mod_dbd.c revision 6078848fce1bb946f8ef7a53bb188b9b975b56b8
71da3cca78eea6010f89b139ecadb79e6d213c4fnd/* Copyright 2003-5 The Apache Software Foundation or its licensors, as
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * applicable.
71da3cca78eea6010f89b139ecadb79e6d213c4fnd *
71da3cca78eea6010f89b139ecadb79e6d213c4fnd * Licensed under the Apache License, Version 2.0 (the "License");
71da3cca78eea6010f89b139ecadb79e6d213c4fnd * you may not use this file except in compliance with the License.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * You may obtain a copy of the License at
71da3cca78eea6010f89b139ecadb79e6d213c4fnd *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * http://www.apache.org/licenses/LICENSE-2.0
71da3cca78eea6010f89b139ecadb79e6d213c4fnd *
71da3cca78eea6010f89b139ecadb79e6d213c4fnd * Unless required by applicable law or agreed to in writing, software
71da3cca78eea6010f89b139ecadb79e6d213c4fnd * distributed under the License is distributed on an "AS IS" BASIS,
71da3cca78eea6010f89b139ecadb79e6d213c4fnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71da3cca78eea6010f89b139ecadb79e6d213c4fnd * See the License for the specific language governing permissions and
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * limitations under the License.
f4c310fd2555c6faca1f980f00b161eadb089023gstein */
f4c310fd2555c6faca1f980f00b161eadb089023gstein
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker/* Overview of what this is and does:
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * http://www.apache.org/~niq/dbd.html
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * or
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * http://apache.webthing.com/database/
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include <ctype.h>
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "http_protocol.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "http_config.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "http_log.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "apr_reslist.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "apr_strings.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "apr_dbd.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "mod_dbd.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3strikerextern module AP_MODULE_DECLARE_DATA dbd_module;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker/************ svr cfg: manage db connection pool ****************/
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3strikertypedef struct dbd_prepared {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker const char *label;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker const char *query;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker struct dbd_prepared *next;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker} dbd_prepared;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3strikertypedef struct svr_cfg {
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *name;
1b21d7b3d97def358b2e923655edeb16613a1c31gstein const char *params;
1327b173ab33ae5bec795b798d5c54c16a7b5c05gstein int persist;
1b21d7b3d97def358b2e923655edeb16613a1c31gstein dbd_prepared *prepared;
1b21d7b3d97def358b2e923655edeb16613a1c31gstein#if APR_HAS_THREADS
1b21d7b3d97def358b2e923655edeb16613a1c31gstein apr_reslist_t *dbpool;
1b21d7b3d97def358b2e923655edeb16613a1c31gstein int nmin;
f4c310fd2555c6faca1f980f00b161eadb089023gstein int nkeep;
f4c310fd2555c6faca1f980f00b161eadb089023gstein int nmax;
f4c310fd2555c6faca1f980f00b161eadb089023gstein int exptime;
f4c310fd2555c6faca1f980f00b161eadb089023gstein#else
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_dbd_t *conn;
f4c310fd2555c6faca1f980f00b161eadb089023gstein#endif
f4c310fd2555c6faca1f980f00b161eadb089023gstein} svr_cfg;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteintypedef enum { cmd_name, cmd_params, cmd_persist,
f4c310fd2555c6faca1f980f00b161eadb089023gstein cmd_min, cmd_keep, cmd_max, cmd_exp
f4c310fd2555c6faca1f980f00b161eadb089023gstein} cmd_parts;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
000397350b42c6266351bd618fa07df929fa7c79gstein
000397350b42c6266351bd618fa07df929fa7c79gstein#define ISINT(val) \
000397350b42c6266351bd618fa07df929fa7c79gstein for (p = val; *p; ++p) \
5ca401d5a2dd63d75464895dc2a6ea292b62fd99gstein if (!isdigit(*p)) \
5ca401d5a2dd63d75464895dc2a6ea292b62fd99gstein return "Argument must be numeric!"
5ca401d5a2dd63d75464895dc2a6ea292b62fd99gsteinstatic const char *dbd_param(cmd_parms *cmd, void *cfg, const char *val)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *p;
f4c310fd2555c6faca1f980f00b161eadb089023gstein const apr_dbd_driver_t *driver = NULL;
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr_cfg *svr = (svr_cfg*) ap_get_module_config
f4c310fd2555c6faca1f980f00b161eadb089023gstein (cmd->server->module_config, &dbd_module);
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein switch ((long) cmd->info) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein case cmd_name:
9f18c80269be35c0b5653e84b0db0a24044722c4gstein svr->name = val;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein /* loading the driver involves once-only dlloading that is
f4c310fd2555c6faca1f980f00b161eadb089023gstein * best done at server startup. This also guarantees that
f4c310fd2555c6faca1f980f00b161eadb089023gstein * we won't return an error later.
f4c310fd2555c6faca1f980f00b161eadb089023gstein */
f4c310fd2555c6faca1f980f00b161eadb089023gstein switch (apr_dbd_get_driver(cmd->pool, svr->name, &driver)) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein case APR_ENOTIMPL:
f4c310fd2555c6faca1f980f00b161eadb089023gstein return apr_psprintf(cmd->pool, "DBD: No driver for %s", svr->name);
f4c310fd2555c6faca1f980f00b161eadb089023gstein case APR_EDSOOPEN:
f4c310fd2555c6faca1f980f00b161eadb089023gstein return apr_psprintf(cmd->pool,
b47464a901075041e800be2de098a603923fa4f9gstein "DBD: Can't load driver file apr_dbd_%s.so",
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr->name);
f4c310fd2555c6faca1f980f00b161eadb089023gstein case APR_ESYMNOTFOUND:
f4c310fd2555c6faca1f980f00b161eadb089023gstein return apr_psprintf(cmd->pool,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "DBD: Failed to load driver apr_dbd_%s_driver",
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker svr->name);
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein break;
f4c310fd2555c6faca1f980f00b161eadb089023gstein case cmd_params:
98e9c4a310bb623ff788680f88b6bd200ff36a24wrowe svr->params = val;
f4c310fd2555c6faca1f980f00b161eadb089023gstein break;
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein case cmd_persist:
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein ISINT(val);
5a9667916c79d8c699b069068e5570aa1c331c80gstein svr->persist = atoi(val);
67ec15681c83d4f5e119f0742618569017beb3fbstriker break;
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein#if APR_HAS_THREADS
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein case cmd_min:
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein ISINT(val);
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein svr->nmin = atoi(val);
5a9667916c79d8c699b069068e5570aa1c331c80gstein break;
9d0665da83d1e22c0ea0e5f6f940f70f75bf5237ianh case cmd_keep:
f5ec9b038bb9db933072ba2c0a8e7bb2a3cedbdagstein ISINT(val);
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr->nkeep = atoi(val);
f4c310fd2555c6faca1f980f00b161eadb089023gstein break;
f4c310fd2555c6faca1f980f00b161eadb089023gstein case cmd_max:
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein ISINT(val);
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein svr->nmax = atoi(val);
67ec15681c83d4f5e119f0742618569017beb3fbstriker break;
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein case cmd_exp:
9f18c80269be35c0b5653e84b0db0a24044722c4gstein ISINT(val);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker svr->exptime = atoi(val);
9d0665da83d1e22c0ea0e5f6f940f70f75bf5237ianh break;
f4c310fd2555c6faca1f980f00b161eadb089023gstein#endif
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm return NULL;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gsteinvoid ap_dbd_prepare(server_rec *s, const char *query, const char *label)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
f4c310fd2555c6faca1f980f00b161eadb089023gstein dbd_prepared *prepared = apr_pcalloc(s->process->pool, sizeof(dbd_prepared));
b47464a901075041e800be2de098a603923fa4f9gstein prepared->label = label;
f4c310fd2555c6faca1f980f00b161eadb089023gstein prepared->query = query;
f4c310fd2555c6faca1f980f00b161eadb089023gstein prepared->next = svr->prepared;
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr->prepared = prepared;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic const char *dbd_prepare(cmd_parms *cmd, void *cfg, const char *query,
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *label)
b47464a901075041e800be2de098a603923fa4f9gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_dbd_prepare(cmd->server, query, label);
b47464a901075041e800be2de098a603923fa4f9gstein return NULL;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic const command_rec dbd_cmds[] = {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker AP_INIT_TAKE1("DBDriver", dbd_param, (void*)cmd_name, RSRC_CONF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "SQL Driver"),
b47464a901075041e800be2de098a603923fa4f9gstein AP_INIT_TAKE1("DBDParams", dbd_param, (void*)cmd_params, RSRC_CONF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "SQL Driver Params"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE1("DBDPersist", dbd_param, (void*)cmd_persist, RSRC_CONF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "Use persistent connection/pool"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE2("DBDPrepareSQL", dbd_prepare, NULL, RSRC_CONF,
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm "Prepared SQL statement, label"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein#if APR_HAS_THREADS
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE1("DBDMin", dbd_param, (void*)cmd_min, RSRC_CONF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "Minimum number of connections"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE1("DBDKeep", dbd_param, (void*)cmd_keep, RSRC_CONF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "Maximum number of sustained connections"),
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker AP_INIT_TAKE1("DBDMax", dbd_param, (void*)cmd_max, RSRC_CONF,
de18a9e85398b9c79c422f578633ed56c2747bbbgstein "Maximum number of connections"),
de18a9e85398b9c79c422f578633ed56c2747bbbgstein AP_INIT_TAKE1("DBDExptime", dbd_param, (void*)cmd_exp, RSRC_CONF,
de18a9e85398b9c79c422f578633ed56c2747bbbgstein "Keepalive time for idle connections"),
de18a9e85398b9c79c422f578633ed56c2747bbbgstein#endif
de18a9e85398b9c79c422f578633ed56c2747bbbgstein {NULL}
de18a9e85398b9c79c422f578633ed56c2747bbbgstein};
de18a9e85398b9c79c422f578633ed56c2747bbbgstein#define DEFAULT_NMIN 0
de18a9e85398b9c79c422f578633ed56c2747bbbgstein#define DEFAULT_NMAX 5
de18a9e85398b9c79c422f578633ed56c2747bbbgstein#define DEFAULT_NKEEP 1
de18a9e85398b9c79c422f578633ed56c2747bbbgstein#define DEFAULT_EXPTIME 120
de18a9e85398b9c79c422f578633ed56c2747bbbgstein#define COND_PARAM(x,val) \
de18a9e85398b9c79c422f578633ed56c2747bbbgstein if (cfg->x == val) { \
de18a9e85398b9c79c422f578633ed56c2747bbbgstein cfg->x = ((svr_cfg*)base)->x; \
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein#define COND_PARAM0(x) COND_PARAM(x,0)
f4c310fd2555c6faca1f980f00b161eadb089023gstein#define COND_PARAM1(x) COND_PARAM(x,-1)
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic void *dbd_merge(apr_pool_t *pool, void *base, void *add) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr_cfg *cfg = apr_pmemdup(pool, add, sizeof(svr_cfg));
f4c310fd2555c6faca1f980f00b161eadb089023gstein COND_PARAM0(name);
f4c310fd2555c6faca1f980f00b161eadb089023gstein COND_PARAM0(params);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker COND_PARAM1(persist);
f4c310fd2555c6faca1f980f00b161eadb089023gstein#if APR_HAS_THREADS
f4c310fd2555c6faca1f980f00b161eadb089023gstein COND_PARAM(nmin, DEFAULT_NMIN);
f4c310fd2555c6faca1f980f00b161eadb089023gstein COND_PARAM(nkeep, DEFAULT_NKEEP);
f4c310fd2555c6faca1f980f00b161eadb089023gstein COND_PARAM(nmax, DEFAULT_NMAX);
de18a9e85398b9c79c422f578633ed56c2747bbbgstein COND_PARAM(exptime, DEFAULT_EXPTIME);
de18a9e85398b9c79c422f578633ed56c2747bbbgstein#endif
9f18c80269be35c0b5653e84b0db0a24044722c4gstein return cfg;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein}
12901074f5d6b36d08be84d8637b6f2c21e0da26trawick#undef COND_PARAM
000397350b42c6266351bd618fa07df929fa7c79gstein#undef COND_PARAM0
000397350b42c6266351bd618fa07df929fa7c79gstein#undef COND_PARAM1
000397350b42c6266351bd618fa07df929fa7c79gsteinstatic void *dbd_cfg(apr_pool_t *p, server_rec *x)
9f18c80269be35c0b5653e84b0db0a24044722c4gstein{
9f18c80269be35c0b5653e84b0db0a24044722c4gstein svr_cfg *svr = (svr_cfg*) apr_pcalloc(p, sizeof(svr_cfg));
12901074f5d6b36d08be84d8637b6f2c21e0da26trawick svr->persist = -1;
000397350b42c6266351bd618fa07df929fa7c79gstein#if APR_HAS_THREADS
000397350b42c6266351bd618fa07df929fa7c79gstein svr->nmin = DEFAULT_NMIN;
000397350b42c6266351bd618fa07df929fa7c79gstein svr->nkeep = DEFAULT_NKEEP;
000397350b42c6266351bd618fa07df929fa7c79gstein svr->nmax = DEFAULT_NMAX;
000397350b42c6266351bd618fa07df929fa7c79gstein svr->exptime = DEFAULT_EXPTIME;
f4c310fd2555c6faca1f980f00b161eadb089023gstein#endif
f4c310fd2555c6faca1f980f00b161eadb089023gstein return svr;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic apr_status_t dbd_prepared_init(apr_pool_t *pool, svr_cfg *svr,
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_dbd_t *dbd)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein dbd_prepared *p;
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_status_t ret = APR_SUCCESS;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker apr_dbd_prepared_t *stmt;
f4c310fd2555c6faca1f980f00b161eadb089023gstein dbd->prepared = apr_hash_make(pool);
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein for (p = svr->prepared; p; p = p->next) {
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein stmt = NULL;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein if (apr_dbd_prepare(dbd->driver, pool, dbd->handle, p->query,
9f18c80269be35c0b5653e84b0db0a24044722c4gstein p->label, &stmt) == 0) {
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein apr_hash_set(dbd->prepared, p->label, APR_HASH_KEY_STRING, stmt);
9f18c80269be35c0b5653e84b0db0a24044722c4gstein }
9f18c80269be35c0b5653e84b0db0a24044722c4gstein else {
9f18c80269be35c0b5653e84b0db0a24044722c4gstein ret = APR_EGENERAL;
709df1e1c2e1710570f8cb4209497e88662829c3gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return ret;
709df1e1c2e1710570f8cb4209497e88662829c3gstein}
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein/************ svr cfg: manage db connection pool ****************/
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein/* an apr_reslist_constructor for SQL connections
f4c310fd2555c6faca1f980f00b161eadb089023gstein * Also use this for opening in non-reslist modes, since it gives
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein * us all the error-handling in one place.
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein */
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gsteinstatic apr_status_t dbd_construct(void **db, void *params, apr_pool_t *pool)
709df1e1c2e1710570f8cb4209497e88662829c3gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr_cfg *svr = (svr_cfg*) params;
709df1e1c2e1710570f8cb4209497e88662829c3gstein ap_dbd_t *rec = apr_pcalloc(pool, sizeof(ap_dbd_t));
709df1e1c2e1710570f8cb4209497e88662829c3gstein apr_status_t rv = apr_dbd_get_driver(pool, svr->name, &rec->driver);
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein/* Error-checking get_driver isn't necessary now (because it's done at
f4c310fd2555c6faca1f980f00b161eadb089023gstein * config-time). But in case that changes in future ...
7281ea331999debdc337b02ce37a3169e0e033a2gstein */
7281ea331999debdc337b02ce37a3169e0e033a2gstein switch (rv) {
7281ea331999debdc337b02ce37a3169e0e033a2gstein case APR_ENOTIMPL:
7281ea331999debdc337b02ce37a3169e0e033a2gstein ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool,
7281ea331999debdc337b02ce37a3169e0e033a2gstein "DBD: driver for %s not available", svr->name);
67ec15681c83d4f5e119f0742618569017beb3fbstriker return rv;
67ec15681c83d4f5e119f0742618569017beb3fbstriker case APR_EDSOOPEN:
67ec15681c83d4f5e119f0742618569017beb3fbstriker ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool,
67ec15681c83d4f5e119f0742618569017beb3fbstriker "DBD: can't find driver for %s", svr->name);
67ec15681c83d4f5e119f0742618569017beb3fbstriker return rv;
f4c310fd2555c6faca1f980f00b161eadb089023gstein case APR_ESYMNOTFOUND:
000397350b42c6266351bd618fa07df929fa7c79gstein ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "DBD: driver for %s is invalid or corrupted", svr->name);
000397350b42c6266351bd618fa07df929fa7c79gstein return rv;
f4c310fd2555c6faca1f980f00b161eadb089023gstein default:
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "DBD: mod_dbd not compatible with apr in get_driver");
000397350b42c6266351bd618fa07df929fa7c79gstein return rv;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker case APR_SUCCESS:
000397350b42c6266351bd618fa07df929fa7c79gstein break;
000397350b42c6266351bd618fa07df929fa7c79gstein }
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
9f18c80269be35c0b5653e84b0db0a24044722c4gstein rv = apr_dbd_open(rec->driver, pool, svr->params, &rec->handle);
000397350b42c6266351bd618fa07df929fa7c79gstein switch (rv) {
000397350b42c6266351bd618fa07df929fa7c79gstein case APR_EGENERAL:
9f18c80269be35c0b5653e84b0db0a24044722c4gstein ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool,
000397350b42c6266351bd618fa07df929fa7c79gstein "DBD: Can't connect to %s[%s]", svr->name, svr->params);
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return rv;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein default:
9f18c80269be35c0b5653e84b0db0a24044722c4gstein ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool,
9f18c80269be35c0b5653e84b0db0a24044722c4gstein "DBD: mod_dbd not compatible with apr in open");
9f18c80269be35c0b5653e84b0db0a24044722c4gstein return rv;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein case APR_SUCCESS:
9f18c80269be35c0b5653e84b0db0a24044722c4gstein break;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein }
9f18c80269be35c0b5653e84b0db0a24044722c4gstein *db = rec;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein rv = dbd_prepared_init(pool, svr, rec);
9f18c80269be35c0b5653e84b0db0a24044722c4gstein return rv;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein}
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein#if APR_HAS_THREADS
000397350b42c6266351bd618fa07df929fa7c79gsteinstatic apr_status_t dbd_destruct(void *sql, void *params, apr_pool_t *pool)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_dbd_t *rec = sql;
f4c310fd2555c6faca1f980f00b161eadb089023gstein return apr_dbd_close(rec->driver, rec->handle);
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic apr_status_t dbd_setup(apr_pool_t *pool, server_rec *s)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_status_t rv = apr_reslist_create(&svr->dbpool, svr->nmin, svr->nkeep,
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker svr->nmax, svr->exptime,
f4c310fd2555c6faca1f980f00b161eadb089023gstein dbd_construct, dbd_destruct,
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr, pool);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (rv == APR_SUCCESS) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_pool_cleanup_register(pool, svr->dbpool,
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker (void*)apr_reslist_destroy,
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_pool_cleanup_null);
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein else {
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "DBD Pool: failed to initialise");
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein return rv;
26250b0077972bf21b6d8a8d23772a4cf53f9477gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gstein
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#endif
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein/* Functions we export for modules to use:
f4c310fd2555c6faca1f980f00b161eadb089023gstein - open acquires a connection from the pool (opens one if necessary)
f4c310fd2555c6faca1f980f00b161eadb089023gstein - close releases it back in to the pool
f4c310fd2555c6faca1f980f00b161eadb089023gstein*/
f4c310fd2555c6faca1f980f00b161eadb089023gsteinvoid ap_dbd_close(server_rec *s, ap_dbd_t *sql)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (!svr->persist) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_dbd_close(sql->driver, sql->handle);
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein#if APR_HAS_THREADS
f4c310fd2555c6faca1f980f00b161eadb089023gstein else {
f39230a531b23d94f86a087963299bbe2e431a4agstein apr_reslist_release(svr->dbpool, sql);
f39230a531b23d94f86a087963299bbe2e431a4agstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein#endif
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic apr_status_t dbd_close(void *CONN)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
5b03ba47ff7225cacb131f14b019332af27da960gstein ap_dbd_t *conn = CONN;
5b03ba47ff7225cacb131f14b019332af27da960gstein return apr_dbd_close(conn->driver, conn->handle);
5b03ba47ff7225cacb131f14b019332af27da960gstein}
5b03ba47ff7225cacb131f14b019332af27da960gstein#define arec ((ap_dbd_t*)rec)
e0d102c882a7ed34d3eec24b36da49f097066a36stoddard#if APR_HAS_THREADS
f4c310fd2555c6faca1f980f00b161eadb089023gsteinap_dbd_t* ap_dbd_open(apr_pool_t *pool, server_rec *s)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein void *rec = NULL;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker apr_status_t rv = APR_SUCCESS;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker const char *errmsg;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (!svr->persist) {
f5d88bab65052e00ba37a1af17e5e67a437628b5wrowe /* Return a once-only connection */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker rv = dbd_construct(&rec, svr, s->process->pool);
f5d88bab65052e00ba37a1af17e5e67a437628b5wrowe return (rv == APR_SUCCESS) ? arec : NULL;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker }
f5d88bab65052e00ba37a1af17e5e67a437628b5wrowe
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (!svr->dbpool) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (dbd_setup(s->process->pool, s) != APR_SUCCESS) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein return NULL;
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (apr_reslist_acquire(svr->dbpool, &rec) != APR_SUCCESS) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "Failed to acquire DBD connection from pool!");
5b03ba47ff7225cacb131f14b019332af27da960gstein return NULL;
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein rv = apr_dbd_check_conn(arec->driver, pool, arec->handle);
5b03ba47ff7225cacb131f14b019332af27da960gstein if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker errmsg = apr_dbd_error(arec->driver, arec->handle, rv);
5b03ba47ff7225cacb131f14b019332af27da960gstein if (!errmsg) {
5b03ba47ff7225cacb131f14b019332af27da960gstein errmsg = "(unknown)";
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool,
5b03ba47ff7225cacb131f14b019332af27da960gstein "DBD[%s] Error: %s", svr->name, errmsg );
5b03ba47ff7225cacb131f14b019332af27da960gstein apr_reslist_invalidate(svr->dbpool, rec);
5b03ba47ff7225cacb131f14b019332af27da960gstein return NULL;
e0d102c882a7ed34d3eec24b36da49f097066a36stoddard }
5b03ba47ff7225cacb131f14b019332af27da960gstein return arec;
5b03ba47ff7225cacb131f14b019332af27da960gstein}
5b03ba47ff7225cacb131f14b019332af27da960gstein#else
5b03ba47ff7225cacb131f14b019332af27da960gsteinap_dbd_t* ap_dbd_open(apr_pool_t *pool, server_rec *s)
5b03ba47ff7225cacb131f14b019332af27da960gstein{
5b03ba47ff7225cacb131f14b019332af27da960gstein apr_status_t rv = APR_SUCCESS;
5b03ba47ff7225cacb131f14b019332af27da960gstein const char *errmsg;
5b03ba47ff7225cacb131f14b019332af27da960gstein void *rec = NULL;
5b03ba47ff7225cacb131f14b019332af27da960gstein svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein if (!svr->persist) {
5b03ba47ff7225cacb131f14b019332af27da960gstein /* Return a once-only connection */
5b03ba47ff7225cacb131f14b019332af27da960gstein rv = dbd_construct(&rec, svr, s->process->pool);
5b03ba47ff7225cacb131f14b019332af27da960gstein return (rv == APR_SUCCESS) ? arec : NULL;
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein/* since we're in nothread-land, we can mess with svr->conn with impunity */
5b03ba47ff7225cacb131f14b019332af27da960gstein/* If we have a persistent connection and it's good, we'll use it */
5b03ba47ff7225cacb131f14b019332af27da960gstein if (svr->conn) {
5b03ba47ff7225cacb131f14b019332af27da960gstein rv = apr_dbd_check_conn(svr->conn->driver, pool, svr->conn->handle);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) {
5b03ba47ff7225cacb131f14b019332af27da960gstein errmsg = apr_dbd_error(arec->driver, arec->handle, rv);
5b03ba47ff7225cacb131f14b019332af27da960gstein if (!errmsg) {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker errmsg = "(unknown)";
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool,
5b03ba47ff7225cacb131f14b019332af27da960gstein "DBD[%s] Error: %s", svr->name, errmsg);
5b03ba47ff7225cacb131f14b019332af27da960gstein svr->conn = NULL;
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein/* We don't have a connection right now, so we'll open one */
5b03ba47ff7225cacb131f14b019332af27da960gstein if (!svr->conn) {
5b03ba47ff7225cacb131f14b019332af27da960gstein if (dbd_construct(&rec, svr, s->process->pool) == APR_SUCCESS) {
5b03ba47ff7225cacb131f14b019332af27da960gstein svr->conn = arec ;
5b03ba47ff7225cacb131f14b019332af27da960gstein apr_pool_cleanup_register(s->process->pool, svr->conn,
5b03ba47ff7225cacb131f14b019332af27da960gstein dbd_close, apr_pool_cleanup_null);
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein return svr->conn;
5b03ba47ff7225cacb131f14b019332af27da960gstein}
5b03ba47ff7225cacb131f14b019332af27da960gstein#endif
f4c310fd2555c6faca1f980f00b161eadb089023gstein#if APR_HAS_THREADS
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3strikertypedef struct {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker ap_dbd_t *conn;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker apr_reslist_t *dbpool;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker} dbd_pool_rec;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic apr_status_t dbd_release(void *REQ)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein dbd_pool_rec *req = REQ;
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_reslist_release(req->dbpool, req->conn);
f4c310fd2555c6faca1f980f00b161eadb089023gstein return APR_SUCCESS;
26250b0077972bf21b6d8a8d23772a4cf53f9477gstein}
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3strikerap_dbd_t *ap_dbd_acquire(request_rec *r)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
9a1d0e3184c65f510dbef5e83ba5b9f27f961b44gstein svr_cfg *svr;
f4c310fd2555c6faca1f980f00b161eadb089023gstein dbd_pool_rec *req = ap_get_module_config(r->request_config, &dbd_module);
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (!req) {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker req = apr_palloc(r->pool, sizeof(dbd_pool_rec));
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker req->conn = ap_dbd_open(r->pool, r->server);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (req->conn) {
0946f90438dcf29a5fe5d9e21559b3b9d640bc12wrowe svr = ap_get_module_config(r->server->module_config, &dbd_module);
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_set_module_config(r->request_config, &dbd_module, req);
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (svr->persist) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein req->dbpool = svr->dbpool;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_register(r->pool, req, dbd_release,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_null);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein else {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_register(r->pool, req->conn, dbd_close,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_null);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein return req->conn;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein}
87e4c2191581abcfaba8133868a1e9c96d9643a5gsteinap_dbd_t *ap_dbd_cacquire(conn_rec *c)
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein{
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein svr_cfg *svr;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein dbd_pool_rec *req = ap_get_module_config(c->conn_config, &dbd_module);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (!req) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein req = apr_palloc(c->pool, sizeof(dbd_pool_rec));
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein req->conn = ap_dbd_open(c->pool, c->base_server);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (req->conn) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein svr = ap_get_module_config(c->base_server->module_config, &dbd_module);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein ap_set_module_config(c->conn_config, &dbd_module, req);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (svr->persist) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein req->dbpool = svr->dbpool;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_register(c->pool, req, dbd_release,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_null);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein else {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_register(c->pool, req->conn, dbd_close,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_null);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein return req->conn;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein}
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein#else
87e4c2191581abcfaba8133868a1e9c96d9643a5gsteinap_dbd_t *ap_dbd_acquire(request_rec *r)
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein{
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein svr_cfg *svr;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein ap_dbd_t *ret = ap_get_module_config(r->request_config, &dbd_module);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (!ret) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein svr = ap_get_module_config(r->server->module_config, &dbd_module);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein ret = ap_dbd_open(r->pool, r->server);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (ret) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein ap_set_module_config(r->request_config, &dbd_module, ret);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (!svr->persist) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_register(r->pool, svr->conn, dbd_close,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_null);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein /* if persist then dbd_open registered cleanup on proc pool */
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein return ret;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein}
87e4c2191581abcfaba8133868a1e9c96d9643a5gsteinap_dbd_t *ap_dbd_cacquire(conn_rec *c)
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein{
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein svr_cfg *svr;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein ap_dbd_t *ret = ap_get_module_config(c->conn_config, &dbd_module);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (!ret) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein svr = ap_get_module_config(c->base_server->module_config, &dbd_module);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein ret = ap_dbd_open(c->pool, c->base_server);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (ret) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein ap_set_module_config(c->conn_config, &dbd_module, ret);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein if (!svr->persist) {
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_register(c->pool, svr->conn, dbd_close,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein apr_pool_cleanup_null);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein /* if persist then dbd_open registered cleanup on proc pool */
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein }
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein return ret;
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein}
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein#endif
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void dbd_hooks(apr_pool_t *pool)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
e0d102c882a7ed34d3eec24b36da49f097066a36stoddard#if APR_HAS_THREADS
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_hook_child_init((void*)dbd_setup, NULL, NULL, APR_HOOK_MIDDLE);
72360798a27566f28e2cbee0e39a0a6e3c3bd729wrowe#endif
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein APR_REGISTER_OPTIONAL_FN(ap_dbd_open);
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein APR_REGISTER_OPTIONAL_FN(ap_dbd_close);
f4c310fd2555c6faca1f980f00b161eadb089023gstein APR_REGISTER_OPTIONAL_FN(ap_dbd_acquire);
f4c310fd2555c6faca1f980f00b161eadb089023gstein APR_REGISTER_OPTIONAL_FN(ap_dbd_cacquire);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker APR_REGISTER_OPTIONAL_FN(ap_dbd_prepare);
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_dbd_init(pool);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker}
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein
0946f90438dcf29a5fe5d9e21559b3b9d640bc12wrowemodule AP_MODULE_DECLARE_DATA dbd_module = {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker STANDARD20_MODULE_STUFF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein NULL,
f4c310fd2555c6faca1f980f00b161eadb089023gstein NULL,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein dbd_cfg,
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein dbd_merge,
f4c310fd2555c6faca1f980f00b161eadb089023gstein dbd_cmds,
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker dbd_hooks
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein};
87e4c2191581abcfaba8133868a1e9c96d9643a5gstein