[Mod-auth-commit] mod_dbi_pool/src mod_dbi_pool.c,NONE,1.1
Brought to you by:
firechipmunk,
honx
From: <fir...@us...> - 2003-12-31 08:31:41
|
Update of /cvsroot/mod-auth/mod_dbi_pool/src In directory sc8-pr-cvs1:/tmp/cvs-serv5710/src Added Files: mod_dbi_pool.c Log Message: initial generic dbi pooling. based on stuff by Nick Kew at: http://apache.webthing.com/ Still needs to support multiple pools to be of any use to us. NOTE: This code is currently 'infected' with the GPL. I plan to Talk to Nick about putting it under the Apache Software License --- NEW FILE: mod_dbi_pool.c --- /* XXXXX: Get Permissions from Nick Kew to Change this to Apache License * based on mod_mysql_pool Author: Paul Querna <chip force-elite.com> Copyright (c) 2003, WebThing Ltd 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. 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 GNU General Public 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. */ /* mod_dbi_pool: manage a pool of libdbi connections. EXPORTS: dbi_conn* dbipool_open(server_rec*) - retrieve a connection from the pool and check it's valid - May return null and log a message on error. void dbipool_close(server_rec*, dbi_conn*) - return a connection to the pool after use CONFIG: See the code round about line 106 */ #include <ctype.h> #include <dbi/dbi.h> #include <httpd.h> #include <http_protocol.h> #include <http_config.h> #include <http_log.h> #include <apr_reslist.h> #include <apr_strings.h> extern module AP_MODULE_DECLARE_DATA dbi_pool_module; /************ svr cfg: manage db connection pool ****************/ typedef struct svr_cfg { apr_reslist_t *dbpool; int nmin; int nkeep; int nmax; int exptime; const char *host; int port; const char *db; const char *dbi_driver; const char *user; const char *pass; } svr_cfg; typedef enum { cmd_host, cmd_port, cmd_db, cmd_dbi_driver, cmd_user, cmd_pass, cmd_min, cmd_keep, cmd_max, cmd_exp } cmd_parts; #define ISINT(val) \ for ( p = val; *p; ++p) \ if ( ! isdigit(*p) ) \ return "Argument must be numeric!" static const char *set_param(cmd_parms * cmd, void *cfg, const char *val) { const char *p; svr_cfg *svr = (svr_cfg *) ap_get_module_config (cmd->server->module_config, &dbi_pool_module); switch ((int) cmd->info) { case cmd_host: svr->host = val; break; case cmd_port: ISINT(val); svr->port = atoi(val); break; case cmd_db: svr->db = val; break; case cmd_dbi_driver: svr->dbi_driver = val; break; case cmd_user: svr->user = val; break; case cmd_pass: svr->pass = val; break; case cmd_min: ISINT(val); svr->nmin = atoi(val); break; case cmd_keep: ISINT(val); svr->nkeep = atoi(val); break; case cmd_max: ISINT(val); svr->nmax = atoi(val); break; case cmd_exp: ISINT(val); svr->exptime = atoi(val); break; } return NULL; } static const command_rec dbi_pool_cmds[] = { AP_INIT_TAKE1("DbiPoolHost", set_param, (void *) cmd_host, RSRC_CONF, "DBI Host"), AP_INIT_TAKE1("DbiPoolPort", set_param, (void *) cmd_port, RSRC_CONF, "DBI Port"), AP_INIT_TAKE1("DbiPoolDB", set_param, (void *) cmd_db, RSRC_CONF, "DBI Database"), AP_INIT_TAKE1("DbiPoolUser", set_param, (void *) cmd_user, RSRC_CONF, "DBI Username"), AP_INIT_TAKE1("DbiPoolPass", set_param, (void *) cmd_pass, RSRC_CONF, "DBI Password"), AP_INIT_TAKE1("DbiPoolMin", set_param, (void *) cmd_min, RSRC_CONF, "Minimum number of connections"), AP_INIT_TAKE1("DbiPoolKeep", set_param, (void *) cmd_keep, RSRC_CONF, "Maximum number of sustained connections"), AP_INIT_TAKE1("DbiPoolMax", set_param, (void *) cmd_max, RSRC_CONF, "Maximum number of connections"), AP_INIT_TAKE1("DbiPoolTTL", set_param, (void *) cmd_exp, RSRC_CONF, "Keepalive time for idle connections"), {NULL} }; static void *dbi_pool_cfg(apr_pool_t * p, server_rec * x) { svr_cfg *svr = (svr_cfg *) apr_pcalloc(p, sizeof(svr_cfg)); return svr; } /************ svr cfg: manage db connection pool ****************/ /* an apr_reslist_constructor for DBI connections */ static apr_status_t dbipool_construct(void **db, void *params, apr_pool_t * pool) { svr_cfg *svr = (svr_cfg *) params; int err_num = 0; const char *err_str; *db = dbi_conn_new(svr->dbi_driver); dbi_conn_set_option(*db, "host", svr->host); dbi_conn_set_option(*db, "username", svr->user); dbi_conn_set_option(*db, "password", svr->pass); dbi_conn_set_option(*db, "dbname", svr->db); if (dbi_conn_connect(*db) != 0) { err_num = dbi_conn_error(*db, &err_str); /* Connetion Failed */ ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool, "[mod_authn_dbi.c] DBI Connection to %s://%s@%s/%s Failed. Error: (%d) %s", svr->dbi_driver, svr->user, svr->host, svr->db, err_num, err_str); return APR_EGENERAL; } return APR_SUCCESS; } static apr_status_t dbipool_destruct(void *sql, void *params, apr_pool_t * pool) { dbi_conn_close((dbi_conn *) sql); return APR_SUCCESS; } static int setup_db_pool(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * s) { svr_cfg *svr = (svr_cfg *) ap_get_module_config(s->module_config, &dbi_pool_module); if (apr_reslist_create(&svr->dbpool, svr->nmin, svr->nkeep, svr->nmax, svr->exptime, dbipool_construct, dbipool_destruct, svr, p) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "DBIPool: failed to initialise"); return 500; } apr_pool_cleanup_register(p, svr->dbpool, (void *) apr_reslist_destroy, apr_pool_cleanup_null); return OK; } static void dbi_pool_hooks(apr_pool_t * p) { ap_hook_post_config(setup_db_pool, NULL, NULL, APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA dbi_pool_module = { STANDARD20_MODULE_STUFF, NULL, NULL, dbi_pool_cfg, NULL, dbi_pool_cmds, dbi_pool_hooks }; /* Functions we export for modules to use: - open acquires a connection from the pool (opens one if necessary) - close releases it back in to the pool */ dbi_conn *dbipool_open(server_rec * s) { dbi_conn *ret = NULL; svr_cfg *svr = (svr_cfg *) ap_get_module_config(s->module_config, &dbi_pool_module); if (apr_reslist_acquire(svr->dbpool, (void **) &ret) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Failed to acquire DBI connection from pool!"); return NULL; } return ret; } void dbipool_close(server_rec * s, dbi_conn * sql) { svr_cfg *svr = (svr_cfg *) ap_get_module_config(s->module_config, &dbi_pool_module); apr_reslist_release(svr->dbpool, sql); } |