wez             Fri Jun 10 01:47:56 2005 EDT

  Modified files:              
    /php-src/ext/pdo    pdo_dbh.c php_pdo_driver.h 
  Log:
  Fix a dumb bug that would effecively ignore persistent connections and create 
a
  new one each time.
  
  Add a hook for persistent connections: it is called when the object goes out 
of
  scope, and offers the driver an opportunity to release per-request scoped data
  at the right time.
  
  This hook is used by pdo_sqlite to unregister UDFs, which are dangerous to 
keep
  registered between requests.
  
  
  
  
http://cvs.php.net/diff.php/php-src/ext/pdo/pdo_dbh.c?r1=1.73&r2=1.74&ty=u
Index: php-src/ext/pdo/pdo_dbh.c
diff -u php-src/ext/pdo/pdo_dbh.c:1.73 php-src/ext/pdo/pdo_dbh.c:1.74
--- php-src/ext/pdo/pdo_dbh.c:1.73      Fri Jun 10 00:03:43 2005
+++ php-src/ext/pdo/pdo_dbh.c   Fri Jun 10 01:47:55 2005
@@ -18,7 +18,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: pdo_dbh.c,v 1.73 2005/06/10 04:03:43 wez Exp $ */
+/* $Id: pdo_dbh.c,v 1.74 2005/06/10 05:47:55 wez Exp $ */
 
 /* The PDO Database Handle Class */
 
@@ -216,6 +216,7 @@
        pdo_driver_t *driver = NULL;
        zval *options = NULL;
        char alt_dsn[512];
+       int call_factory = 1;
 
        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
"s|ssa!", &data_source, &data_source_len,
                                &username, &usernamelen, &password, 
&passwordlen, &options)) {
@@ -300,35 +301,39 @@
                        }
                }
 
-               /* let's see if we have one cached.... */
-               if (is_persistent && SUCCESS == 
zend_hash_find(&EG(persistent_list), hashkey, plen+1, (void*)&le)) {
-                       if (Z_TYPE_P(le) == php_pdo_list_entry()) {
-                               pdbh = (pdo_dbh_t*)le->ptr;
-
-                               /* is the connection still alive ? */
-                               if (pdbh->methods->check_liveness && FAILURE == 
(pdbh->methods->check_liveness)(pdbh TSRMLS_CC)) {
-                                       /* nope... need to kill it */
-                                       pdbh = NULL;
+               if (is_persistent) {
+                       /* let's see if we have one cached.... */
+                       if (SUCCESS == zend_hash_find(&EG(persistent_list), 
hashkey, plen+1, (void*)&le)) {
+                               if (Z_TYPE_P(le) == php_pdo_list_entry()) {
+                                       pdbh = (pdo_dbh_t*)le->ptr;
+
+                                       /* is the connection still alive ? */
+                                       if (pdbh->methods->check_liveness && 
FAILURE == (pdbh->methods->check_liveness)(pdbh TSRMLS_CC)) {
+                                               /* nope... need to kill it */
+                                               pdbh = NULL;
+                                       }
                                }
                        }
-               }
 
-               if (is_persistent && !pdbh) {
-                       /* need a brand new pdbh */
-                       pdbh = pecalloc(1, sizeof(*pdbh), 1);
-
-                       if (!pdbh) {
-                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "out 
of memory while allocating PDO handle");
-                               /* NOTREACHED */
-                       }
-                       
-                       pdbh->is_persistent = 1;
-                       if (!(pdbh->persistent_id = pemalloc(plen + 1, 1))) {
-                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "out 
of memory while allocating PDO handle");
+                       if (pdbh) {
+                               call_factory = 0;
+                       } else {
+                               /* need a brand new pdbh */
+                               pdbh = pecalloc(1, sizeof(*pdbh), 1);
+
+                               if (!pdbh) {
+                                       php_error_docref(NULL TSRMLS_CC, 
E_ERROR, "out of memory while allocating PDO handle");
+                                       /* NOTREACHED */
+                               }
+
+                               pdbh->is_persistent = 1;
+                               if (!(pdbh->persistent_id = pemalloc(plen + 1, 
1))) {
+                                       php_error_docref(NULL TSRMLS_CC, 
E_ERROR, "out of memory while allocating PDO handle");
+                               }
+                               memcpy((char *)pdbh->persistent_id, hashkey, 
plen+1);
+                               pdbh->persistent_id_len = plen+1;
+                               pdbh->refcount = 1;
                        }
-                       memcpy((char *)pdbh->persistent_id, hashkey, plen+1);
-                       pdbh->persistent_id_len = plen+1;
-                       pdbh->refcount = 1;
                }
 
                if (pdbh) {
@@ -358,7 +363,12 @@
        if (!dbh->data_source || (username && !dbh->username) || (password && 
!dbh->password)) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "out of memory");
        }
-       
+
+       if (!call_factory) {
+               /* we got a persistent guy from our cache */
+               return;
+       }
+
        if (driver->db_handle_factory(dbh, options TSRMLS_CC)) {
                /* all set */
 
@@ -1106,6 +1116,14 @@
 
 static void pdo_dbh_free_storage(pdo_dbh_t *dbh TSRMLS_DC)
 {
+       if (dbh->methods->rollback) {
+               /* roll back transactions, that are possibly nested, even 
though we don't
+                * official support them */
+               while (dbh->methods->rollback(dbh TSRMLS_CC))
+                       ;
+               dbh->in_txn = 0;
+       }
+       
        if (dbh->properties) {
                zend_hash_destroy(dbh->properties);
                efree(dbh->properties);
@@ -1114,6 +1132,8 @@
 
        if (!dbh->is_persistent) {
                dbh_free(dbh TSRMLS_CC);
+       } else if (dbh->methods->persistent_shutdown) {
+               dbh->methods->persistent_shutdown(dbh TSRMLS_CC);
        }
 }
 
http://cvs.php.net/diff.php/php-src/ext/pdo/php_pdo_driver.h?r1=1.57&r2=1.58&ty=u
Index: php-src/ext/pdo/php_pdo_driver.h
diff -u php-src/ext/pdo/php_pdo_driver.h:1.57 
php-src/ext/pdo/php_pdo_driver.h:1.58
--- php-src/ext/pdo/php_pdo_driver.h:1.57       Wed May 18 18:40:55 2005
+++ php-src/ext/pdo/php_pdo_driver.h    Fri Jun 10 01:47:55 2005
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: php_pdo_driver.h,v 1.57 2005/05/18 22:40:55 iliaa Exp $ */
+/* $Id: php_pdo_driver.h,v 1.58 2005/06/10 05:47:55 wez Exp $ */
 
 #ifndef PHP_PDO_DRIVER_H
 #define PHP_PDO_DRIVER_H
@@ -44,7 +44,7 @@
 # define FALSE 0
 #endif
 
-#define PDO_DRIVER_API 20050227
+#define PDO_DRIVER_API 20050610
 
 enum pdo_param_type {
        PDO_PARAM_NULL,
@@ -262,6 +262,11 @@
  * You may set this handler to NULL, which is equivalent to returning SUCCESS. 
*/
 typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh TSRMLS_DC);
 
+/* called at request end for each persistent dbh; this gives the driver
+ * the opportunity to safely release resources that only have per-request
+ * scope */
+typedef void (*pdo_dbh_request_shutdown)(pdo_dbh_t *dbh TSRMLS_DC);
+
 /* for adding methods to the dbh or stmt objects 
 pointer to a list of driver specific functions. The convention is
 to prefix the function names using the PDO driver name; this will
@@ -290,6 +295,7 @@
        pdo_dbh_get_attr_func           get_attribute;
        pdo_dbh_check_liveness_func     check_liveness;
        pdo_dbh_get_driver_methods_func get_driver_methods;
+       pdo_dbh_request_shutdown        persistent_shutdown;
 };
 
 /* }}} */
@@ -473,7 +479,7 @@
        unsigned long precision;
 
        /* don't touch this unless your name is dbdo */
-       void *dbdo_stuff;
+       void *dbdo_data;
 };
 
 /* describes a bound parameter */

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to