⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_dbd.c

📁 apache服务器源代码(版本号:2.2.2)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2003-6 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* Overview of what this is and does: * http://www.apache.org/~niq/dbd.html * or * http://apache.webthing.com/database/ */#include <ctype.h>#include "http_protocol.h"#include "http_config.h"#include "http_log.h"#include "apr_reslist.h"#include "apr_strings.h"#include "apr_dbd.h"#include "mod_dbd.h"extern module AP_MODULE_DECLARE_DATA dbd_module;/************ svr cfg: manage db connection pool ****************/#define NMIN_SET     0x1#define NKEEP_SET    0x2#define NMAX_SET     0x4#define EXPTIME_SET  0x8typedef struct dbd_prepared {    const char *label;    const char *query;    struct dbd_prepared *next;} dbd_prepared;typedef struct svr_cfg {    const char *name;    const char *params;    int persist;    dbd_prepared *prepared;#if APR_HAS_THREADS    apr_thread_mutex_t *mutex;    apr_pool_t *pool;    apr_reslist_t *dbpool;    int nmin;    int nkeep;    int nmax;    int exptime;#else    ap_dbd_t *conn;#endif    unsigned int set;} svr_cfg;typedef enum { cmd_name, cmd_params, cmd_persist,               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 *dbd_param(cmd_parms *cmd, void *cfg, const char *val){    const char *p;    const apr_dbd_driver_t *driver = NULL;    svr_cfg *svr = (svr_cfg*) ap_get_module_config        (cmd->server->module_config, &dbd_module);    switch ((long) cmd->info) {    case cmd_name:        svr->name = val;        /* loading the driver involves once-only dlloading that is         * best done at server startup.  This also guarantees that         * we won't return an error later.         */        switch (apr_dbd_get_driver(cmd->pool, svr->name, &driver)) {        case APR_ENOTIMPL:            return apr_psprintf(cmd->pool, "DBD: No driver for %s", svr->name);        case APR_EDSOOPEN:            return apr_psprintf(cmd->pool,                                "DBD: Can't load driver file apr_dbd_%s.so",                                svr->name);        case APR_ESYMNOTFOUND:            return apr_psprintf(cmd->pool,                                "DBD: Failed to load driver apr_dbd_%s_driver",                                svr->name);        }        break;    case cmd_params:        svr->params = val;        break;#if APR_HAS_THREADS    case cmd_min:        ISINT(val);        svr->nmin = atoi(val);        svr->set |= NMIN_SET;        break;    case cmd_keep:        ISINT(val);        svr->nkeep = atoi(val);        svr->set |= NKEEP_SET;        break;    case cmd_max:        ISINT(val);        svr->nmax = atoi(val);        svr->set |= NMAX_SET;        break;    case cmd_exp:        ISINT(val);        svr->exptime = atoi(val);        svr->set |= EXPTIME_SET;        break;#endif    }    return NULL;}static const char *dbd_param_flag(cmd_parms *cmd, void *cfg, int flag){    svr_cfg *svr = (svr_cfg*) ap_get_module_config        (cmd->server->module_config, &dbd_module);    switch ((long) cmd->info) {    case cmd_persist:        svr->persist = flag;        break;    }    return NULL;}DBD_DECLARE_NONSTD(void) ap_dbd_prepare(server_rec *s, const char *query,                                        const char *label){    svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);    dbd_prepared *prepared = apr_pcalloc(s->process->pool, sizeof(dbd_prepared));    prepared->label = label;    prepared->query = query;    prepared->next = svr->prepared;    svr->prepared = prepared;}static const char *dbd_prepare(cmd_parms *cmd, void *cfg, const char *query,                               const char *label){    ap_dbd_prepare(cmd->server, query, label);    return NULL;}static const command_rec dbd_cmds[] = {    AP_INIT_TAKE1("DBDriver", dbd_param, (void*)cmd_name, RSRC_CONF,                  "SQL Driver"),    AP_INIT_TAKE1("DBDParams", dbd_param, (void*)cmd_params, RSRC_CONF,                  "SQL Driver Params"),    AP_INIT_FLAG("DBDPersist", dbd_param_flag, (void*)cmd_persist, RSRC_CONF,                 "Use persistent connection/pool"),    AP_INIT_TAKE2("DBDPrepareSQL", dbd_prepare, NULL, RSRC_CONF,                  "Prepared SQL statement, label"),#if APR_HAS_THREADS    AP_INIT_TAKE1("DBDMin", dbd_param, (void*)cmd_min, RSRC_CONF,                  "Minimum number of connections"),    /* XXX: note that mod_proxy calls this "smax" */    AP_INIT_TAKE1("DBDKeep", dbd_param, (void*)cmd_keep, RSRC_CONF,                  "Maximum number of sustained connections"),    AP_INIT_TAKE1("DBDMax", dbd_param, (void*)cmd_max, RSRC_CONF,                  "Maximum number of connections"),    /* XXX: note that mod_proxy calls this "ttl" (time to live) */    AP_INIT_TAKE1("DBDExptime", dbd_param, (void*)cmd_exp, RSRC_CONF,                  "Keepalive time for idle connections"),#endif    {NULL}};static void *dbd_merge(apr_pool_t *pool, void *BASE, void *ADD) {    svr_cfg *base = (svr_cfg*) BASE;    svr_cfg *add = (svr_cfg*) ADD;    svr_cfg *cfg = apr_pcalloc(pool, sizeof(svr_cfg));    cfg->name = strcmp(add->name, "") ? add->name : base->name;    cfg->params = strcmp(add->params, "") ? add->params : base->params;    cfg->persist = (add->persist == -1) ? base->persist : add->persist;#if APR_HAS_THREADS    cfg->nmin = (add->set&NMIN_SET) ? add->nmin : base->nmin;    cfg->nkeep = (add->set&NKEEP_SET) ? add->nkeep : base->nkeep;    cfg->nmax = (add->set&NMAX_SET) ? add->nmax : base->nmax;    cfg->exptime = (add->set&EXPTIME_SET) ? add->exptime : base->exptime;#endif    cfg->set = add->set | base->set;    return (void*) cfg;}/* A default nmin of >0 will help with generating meaningful * startup error messages if the database is down. */#define DEFAULT_NMIN 1#define DEFAULT_NKEEP 2#define DEFAULT_NMAX 10#define DEFAULT_EXPTIME 300static void *dbd_cfg(apr_pool_t *p, server_rec *x){    svr_cfg *svr = (svr_cfg*) apr_pcalloc(p, sizeof(svr_cfg));    svr->name = svr->params = ""; /* don't risk segfault on misconfiguration */    svr->persist = -1;#if APR_HAS_THREADS    svr->nmin = DEFAULT_NMIN;    svr->nkeep = DEFAULT_NKEEP;    svr->nmax = DEFAULT_NMAX;    svr->exptime = DEFAULT_EXPTIME;#endif    return svr;}static apr_status_t dbd_prepared_init(apr_pool_t *pool, svr_cfg *svr,                                      ap_dbd_t *dbd){    dbd_prepared *p;    apr_status_t ret = APR_SUCCESS;    apr_dbd_prepared_t *stmt;    dbd->prepared = apr_hash_make(pool);    for (p = svr->prepared; p; p = p->next) {        stmt = NULL;        if (apr_dbd_prepare(dbd->driver, pool, dbd->handle, p->query,                            p->label, &stmt) == 0) {            apr_hash_set(dbd->prepared, p->label, APR_HASH_KEY_STRING, stmt);        }        else {            ret = APR_EGENERAL;        }    }    return ret;}/************ svr cfg: manage db connection pool ****************//* an apr_reslist_constructor for SQL connections * Also use this for opening in non-reslist modes, since it gives * us all the error-handling in one place. */static apr_status_t dbd_construct(void **db, void *params, apr_pool_t *pool){    svr_cfg *svr = (svr_cfg*) params;    ap_dbd_t *rec = apr_pcalloc(pool, sizeof(ap_dbd_t));    apr_status_t rv;    /* this pool is mostly so dbd_close can destroy the prepared stmts */    rv = apr_pool_create(&rec->pool, pool);    if (rv != APR_SUCCESS) {        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, pool,                      "DBD: Failed to create memory pool");    }/* The driver is loaded at config time now, so this just checks a hash. * If that changes, the driver DSO could be registered to unload against * our pool, which is probably not what we want.  Error checking isn't * necessary now, but in case that changes in the future ... */    rv = apr_dbd_get_driver(rec->pool, svr->name, &rec->driver);    switch (rv) {    case APR_ENOTIMPL:        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,                      "DBD: driver for %s not available", svr->name);        return rv;    case APR_EDSOOPEN:        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,                      "DBD: can't find driver for %s", svr->name);        return rv;    case APR_ESYMNOTFOUND:        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,                      "DBD: driver for %s is invalid or corrupted", svr->name);        return rv;    default:        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,                      "DBD: mod_dbd not compatible with apr in get_driver");        return rv;    case APR_SUCCESS:        break;    }    rv = apr_dbd_open(rec->driver, rec->pool, svr->params, &rec->handle);    switch (rv) {    case APR_EGENERAL:        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,                      "DBD: Can't connect to %s", svr->name);        return rv;    default:        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,                      "DBD: mod_dbd not compatible with apr in open");        return rv;    case APR_SUCCESS:        break;    }    *db = rec;    rv = dbd_prepared_init(rec->pool, svr, rec);    if (rv != APR_SUCCESS) {        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,                      "DBD: failed to initialise prepared SQL statements");    }    return rv;}static apr_status_t dbd_close(void *CONN){    ap_dbd_t *conn = CONN;    apr_status_t rv = apr_dbd_close(conn->driver, conn->handle);    apr_pool_destroy(conn->pool);    return rv;}#if APR_HAS_THREADSstatic apr_status_t dbd_destruct(void *sql, void *params, apr_pool_t *pool){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -