mod_dbd currently supports modules requiring a connection of an arbitrary
duration (explicit ap_dbd_open and ap_dbd_close), or tied to the request_rec
(ap_dbd_acquire, which releases the connection back to the reslist on request
pool cleanup).

Brian France's dbd modules for smtpd want the option that's missing from 
there: a dbd handle tied to the conn_rec.  Today I got around to hacking
that - patch attached.  Review invited - I'll commit to trunk if noone shouts.

-- 
Nick Kew
Index: modules/database/mod_dbd.c
===================================================================
--- modules/database/mod_dbd.c	(revision 292769)
+++ modules/database/mod_dbd.c	(working copy)
@@ -401,7 +401,11 @@
 {
     svr_cfg *svr;
     dbd_pool_rec *req = ap_get_module_config(r->request_config, &dbd_module);
+    /* If we have a conn_config we can use it here.  We can't do the reverse.*/
     if (!req) {
+        req = ap_get_module_config(r->connection->conn_config, &dbd_module);
+    }
+    if (!req) {
         req = apr_palloc(r->pool, sizeof(dbd_pool_rec));
         req->conn = ap_dbd_open(r->pool, r->server);
         if (req->conn) {
@@ -420,15 +424,42 @@
     }
     return req->conn;
 }
+ap_dbd_t *ap_dbd_cacquire(conn_rec *c)
+{
+    svr_cfg *svr;
+    dbd_pool_rec *req = ap_get_module_config(c->conn_config, &dbd_module);
+    if (!req) {
+        req = apr_palloc(c->pool, sizeof(dbd_pool_rec));
+        req->conn = ap_dbd_open(c->pool, c->base_server);
+        if (req->conn) {
+            svr = ap_get_module_config(c->base_server->module_config, &dbd_module);
+            ap_set_module_config(c->conn_config, &dbd_module, req);
+            if (svr->persist) {
+                req->dbpool = svr->dbpool;
+                apr_pool_cleanup_register(c->pool, req, dbd_release,
+                                          apr_pool_cleanup_null);
+            }
+            else {
+                apr_pool_cleanup_register(c->pool, req->conn, dbd_close,
+                                          apr_pool_cleanup_null);
+            }
+        }
+    }
+    return req->conn;
+}
 #else
 ap_dbd_t *ap_dbd_acquire(request_rec *r)
 {
     svr_cfg *svr;
     ap_dbd_t *ret = ap_get_module_config(r->request_config, &dbd_module);
+    /* If we have a conn_config we can use it here.  We can't do the reverse.*/
     if (!ret) {
+        ret = ap_get_module_config(r->connection->conn_config, &dbd_module);
+    }
+    if (!ret) {
         svr = ap_get_module_config(r->server->module_config, &dbd_module);
         ret = ap_dbd_open(r->pool, r->server);
-        if ( ret ) {
+        if (ret) {
             ap_set_module_config(r->request_config, &dbd_module, ret);
             if (!svr->persist) {
                 apr_pool_cleanup_register(r->pool, svr->conn, dbd_close,
@@ -439,6 +470,24 @@
     }
     return ret;
 }
+ap_dbd_t *ap_dbd_cacquire(conn_rec *c)
+{
+    svr_cfg *svr;
+    ap_dbd_t *ret = ap_get_module_config(c->conn_config, &dbd_module);
+    if (!ret) {
+        svr = ap_get_module_config(c->base_server->module_config, &dbd_module);
+        ret = ap_dbd_open(c->pool, c->base_server);
+        if (ret) {
+            ap_set_module_config(c->conn_config, &dbd_module, ret);
+            if (!svr->persist) {
+                apr_pool_cleanup_register(c->pool, svr->conn, dbd_close,
+                                          apr_pool_cleanup_null);
+            }
+            /* if persist then dbd_open registered cleanup on proc pool */
+        }
+    }
+    return ret;
+}
 #endif
 
 static void dbd_hooks(apr_pool_t *pool)
@@ -449,6 +498,7 @@
     APR_REGISTER_OPTIONAL_FN(ap_dbd_open);
     APR_REGISTER_OPTIONAL_FN(ap_dbd_close);
     APR_REGISTER_OPTIONAL_FN(ap_dbd_acquire);
+    APR_REGISTER_OPTIONAL_FN(ap_dbd_cacquire);
     APR_REGISTER_OPTIONAL_FN(ap_dbd_prepare);
     apr_dbd_init(pool);
 }
Index: modules/database/mod_dbd.h
===================================================================
--- modules/database/mod_dbd.h	(revision 292283)
+++ modules/database/mod_dbd.h	(working copy)
@@ -58,6 +58,12 @@
  */
 AP_DECLARE(ap_dbd_t*) ap_dbd_acquire(request_rec*);
 
+/* acquire a connection that will have the lifetime of a connection
+ * and MUST NOT be explicitly closed.  Return NULL on error.
+ * This is the preferred function for most applications.
+ */
+AP_DECLARE(ap_dbd_t*) ap_dbd_cacquire(conn_rec*);
+
 /* Prepare a statement for use by a client module */
 AP_DECLARE(void) ap_dbd_prepare(server_rec*, const char*, const char*);
 
@@ -65,6 +71,7 @@
 APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_open, (apr_pool_t*, server_rec*));
 APR_DECLARE_OPTIONAL_FN(void, ap_dbd_close, (server_rec*, ap_dbd_t*));
 APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_acquire, (request_rec*));
+APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_cacquire, (conn_rec*));
 APR_DECLARE_OPTIONAL_FN(void, ap_dbd_prepare, (server_rec*, const char*, const char*));
 
 #endif

Reply via email to