From 7a87af332103f1fc991442dbdabd3972103945ab Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Tue, 25 May 2004 17:43:24 +0000 Subject: [PATCH] Some definitions for cursors. Define a mechanism for driver-specific attributes. Use a refcount for the stmt structure. --- ext/pdo/pdo.c | 2 ++ ext/pdo/pdo_dbh.c | 8 +++----- ext/pdo/pdo_stmt.c | 25 ++++++++++++++++--------- ext/pdo/php_pdo_driver.h | 15 ++++++++++++++- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index 28b4d2c5c9..580ee5a755 100755 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -226,6 +226,8 @@ PHP_MINIT_FUNCTION(pdo) REGISTER_LONG_CONSTANT("PDO_ATTR_SERVER_INFO", (long)PDO_ATTR_SERVER_INFO, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_ATTR_CONNECTION_STATUS", (long)PDO_ATTR_CONNECTION_STATUS, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_ATTR_CASE", (long)PDO_ATTR_CASE, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PDO_ATTR_CURSOR_NAME", (long)PDO_ATTR_CURSOR_NAME, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PDO_ATTR_CURSOR", (long)PDO_ATTR_CURSOR, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_ERRMODE_SILENT", (long)PDO_ERRMODE_SILENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PDO_ERRMODE_WARNING", (long)PDO_ERRMODE_WARNING, CONST_CS|CONST_PERSISTENT); diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 62a6357e48..6e5e632c6b 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -183,11 +183,7 @@ static PHP_FUNCTION(dbh_constructor) dbh->username = username ? pestrdup(username, is_persistent) : NULL; dbh->password = password ? pestrdup(password, is_persistent) : NULL; - if (driver_options) { - dbh->auto_commit = pdo_attr_lval(driver_options, PDO_ATTR_AUTOCOMMIT, 1 TSRMLS_CC); - } else { - dbh->auto_commit = 1; - } + dbh->auto_commit = pdo_attr_lval(driver_options, PDO_ATTR_AUTOCOMMIT, 1 TSRMLS_CC); if (driver->db_handle_factory(dbh, driver_options TSRMLS_CC)) { /* all set */ @@ -246,6 +242,8 @@ static PHP_METHOD(PDO, prepare) /* we haven't created a lazy object yet */ ZVAL_NULL(&stmt->lazy_object_ref); + + stmt->refcount = 1; return; } efree(stmt); diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index a1fa9bf2be..2f0cf60e05 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -169,6 +169,7 @@ static void get_lazy_object(pdo_stmt_t *stmt, zval *return_value TSRMLS_DC) Z_TYPE(stmt->lazy_object_ref) = IS_OBJECT; Z_OBJ_HANDLE(stmt->lazy_object_ref) = zend_objects_store_put(stmt, NULL, pdo_row_free_storage, NULL TSRMLS_CC); Z_OBJ_HT(stmt->lazy_object_ref) = &pdo_row_object_handlers; + stmt->refcount++; } Z_TYPE_P(return_value) = IS_OBJECT; Z_OBJ_HANDLE_P(return_value) = Z_OBJ_HANDLE(stmt->lazy_object_ref); @@ -788,10 +789,8 @@ zend_object_handlers pdo_dbstmt_object_handlers = { NULL }; -void pdo_dbstmt_free_storage(zend_object *object TSRMLS_DC) +static void free_statement(pdo_stmt_t *stmt TSRMLS_DC) { - pdo_stmt_t *stmt = (pdo_stmt_t*)object; - if (stmt->methods && stmt->methods->dtor) { stmt->methods->dtor(stmt TSRMLS_CC); } @@ -821,14 +820,18 @@ void pdo_dbstmt_free_storage(zend_object *object TSRMLS_DC) } zend_objects_store_del_ref(&stmt->database_object_handle TSRMLS_CC); -/* XXX: Does not appear to be needed and causes problems according to valgrind - if (&stmt->lazy_object_ref) { - zend_objects_store_del_ref(&stmt->lazy_object_ref TSRMLS_CC); - } -*/ efree(stmt); } +void pdo_dbstmt_free_storage(zend_object *object TSRMLS_DC) +{ + pdo_stmt_t *stmt = (pdo_stmt_t*)object; + + if (--stmt->refcount == 0) { + free_statement(stmt TSRMLS_CC); + } +} + zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; @@ -1010,7 +1013,11 @@ void pdo_row_free_storage(zend_object *object TSRMLS_DC) { pdo_stmt_t *stmt = (pdo_stmt_t*)object; - /* nothing to do here */ + ZVAL_NULL(&stmt->lazy_object_ref); + + if (--stmt->refcount == 0) { + free_statement(stmt TSRMLS_CC); + } } zend_object_value pdo_row_new(zend_class_entry *ce TSRMLS_DC) diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 058bee253a..58327804a6 100755 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -65,6 +65,18 @@ enum pdo_attribute_type { PDO_ATTR_SERVER_INFO, /* server information */ PDO_ATTR_CONNECTION_STATUS, /* connection status */ PDO_ATTR_CASE, /* control case folding for portability */ + PDO_ATTR_CURSOR_NAME, /* name a cursor for use in "WHERE CURRENT OF " */ + PDO_ATTR_CURSOR, /* cursor type */ + + /* this defines the start of the range for driver specific options. + * Drivers should define their own attribute constants beginning with this + * value. */ + PDO_ATTR_DRIVER_SPECIFIC = 1000 +}; + +enum pdo_cursor_type { + PDO_CURSOR_FWDONLY, /* forward only cursor (default) */ + PDO_CURSOR_SCROLL, /* scrollable cursor */ }; /* generic error code values. @@ -100,7 +112,7 @@ static inline long pdo_attr_lval(zval *options, enum pdo_fetch_type option_name, { zval **v; - if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) { + if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) { convert_to_long_ex(v); return Z_LVAL_PP(v); } @@ -356,6 +368,7 @@ struct _pdo_stmt_t { /* for lazy fetches, we always return the same lazy object handle. * Let's keep it here. */ zval lazy_object_ref; + unsigned long refcount; }; /* call this in MINIT to register your PDO driver */ -- 2.40.0