cvs: php-src(PHP_5_1) /ext/pdo pdo_dbh.c php_pdo_driver.h /ext/pdo/tests pdo_030.phpt

From: Date: Sun, 02 Oct 2005 20:07:11 +0000
Subject: cvs: php-src(PHP_5_1) /ext/pdo pdo_dbh.c php_pdo_driver.h /ext/pdo/tests pdo_030.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-34230@lists.php.net to get a copy of this message
helly Sun Oct 2 16:07:11 2005 EDT Added files: (Branch: PHP_5_1) /php-src/ext/pdo/tests pdo_030.phpt Modified files: /php-src/ext/pdo pdo_dbh.c php_pdo_driver.h Log: - Add PDO::setAttribute(PDO::ATTR_STATEMENT_CLASS)

http://cvs.php.net/diff.php/php-src/ext/pdo/pdo_dbh.c?r1=1.82.2.5&r2=1.82.2.6&ty=u Index: php-src/ext/pdo/pdo_dbh.c diff -u php-src/ext/pdo/pdo_dbh.c:1.82.2.5 php-src/ext/pdo/pdo_dbh.c:1.82.2.6 --- php-src/ext/pdo/pdo_dbh.c:1.82.2.5 Fri Sep 30 22:48:11 2005 +++ php-src/ext/pdo/pdo_dbh.c Sun Oct 2 16:07:11 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_dbh.c,v 1.82.2.5 2005/10/01 02:48:11 wez Exp $ */ +/* $Id: pdo_dbh.c,v 1.82.2.6 2005/10/02 20:07:11 helly Exp $ */ /* The PDO Database Handle Class */ @@ -539,8 +539,8 @@ ctor_args = NULL; } } else { - dbstmt_ce = pdo_dbstmt_ce; - ctor_args = NULL; + dbstmt_ce = dbh->def_stmt_ce; + ctor_args = dbh->def_stmt_ctor_args; } if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, ctor_args TSRMLS_CC)) { @@ -708,6 +708,62 @@ dbh->stringify = Z_LVAL_P(value) ? 1 : 0; RETURN_TRUE; + case PDO_ATTR_STATEMENT_CLASS: { + /* array(string classname, array(mixed ctor_args)) */ + zend_class_entry **pce; + zval **item; + + if (dbh->is_persistent) { + pdo_raise_impl_error(dbh, NULL, "HY000", + "PDO_ATTR_STATEMENT_CLASS cannot be used with persistent PDO instances" + TSRMLS_CC); + PDO_HANDLE_DBH_ERR(); + RETURN_FALSE; + } + if (Z_TYPE_P(value) != IS_ARRAY + || zend_hash_index_find(Z_ARRVAL_P(value), 0, (void**)&item) == FAILURE + || Z_TYPE_PP(item) != IS_STRING + || zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE + ) { + pdo_raise_impl_error(dbh, NULL, "HY000", + "PDO_ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); " + "the classname must be a string specifying an existing class" + TSRMLS_CC); + PDO_HANDLE_DBH_ERR(); + RETURN_FALSE; + } + if (!instanceof_function(*pce, pdo_dbstmt_ce TSRMLS_CC)) { + pdo_raise_impl_error(dbh, NULL, "HY000", + "user-supplied statement class must be derived from PDOStatement" TSRMLS_CC); + PDO_HANDLE_DBH_ERR(); + RETURN_FALSE; + } + if ((*pce)->constructor && !((*pce)->constructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED))) { + pdo_raise_impl_error(dbh, NULL, "HY000", + "user-supplied statement class cannot have a public constructor" TSRMLS_CC); + PDO_HANDLE_DBH_ERR(); + RETURN_FALSE; + } + dbh->def_stmt_ce = *pce; + if (dbh->def_stmt_ctor_args) { + zval_ptr_dtor(&dbh->def_stmt_ctor_args); + dbh->def_stmt_ctor_args = NULL; + } + if (zend_hash_index_find(Z_ARRVAL_P(value), 1, (void**)&item) == SUCCESS) { + if (Z_TYPE_PP(item) != IS_ARRAY) { + pdo_raise_impl_error(dbh, NULL, "HY000", + "PDO_ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); " + "ctor_args must be an array" + TSRMLS_CC); + PDO_HANDLE_DBH_ERR(); + RETURN_FALSE; + } + (*item)->refcount++; + dbh->def_stmt_ctor_args = *item; + } + RETURN_TRUE; + } + default: ; } @@ -763,6 +819,15 @@ case PDO_ATTR_DRIVER_NAME: RETURN_STRINGL((char*)dbh->driver->driver_name, dbh->driver->driver_name_len, 1); + + case PDO_ATTR_STATEMENT_CLASS: + array_init(return_value); + add_next_index_string(return_value, dbh->def_stmt_ce->name, 1); + if (dbh->def_stmt_ctor_args) { + dbh->def_stmt_ctor_args->refcount++; + add_next_index_zval(return_value, dbh->def_stmt_ctor_args); + } + return; } if (!dbh->methods->get_attribute) { @@ -895,7 +960,7 @@ PDO_DBH_CLEAR_ERR(); PDO_CONSTRUCT_CHECK; - if (!pdo_stmt_instantiate(dbh, return_value, pdo_dbstmt_ce, NULL TSRMLS_CC)) { + if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args TSRMLS_CC)) { pdo_raise_impl_error(dbh, NULL, "HY000", "failed to instantiate user supplied statement class" TSRMLS_CC); return; } @@ -929,7 +994,7 @@ stmt->executed = 1; } if (ret) { - pdo_stmt_construct(stmt, return_value, pdo_dbstmt_ce, NULL TSRMLS_CC); + pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args TSRMLS_CC); return; } } @@ -1145,7 +1210,7 @@ size_t name_len, const char *value, size_t value_len TSRMLS_DC) { #if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1 - zend_declare_class_constant_stringl(pdo_dbh_ce, const_name, name_len, value, value_len TSRMLS_CC); + zend_declare_class_constant_stringl(pdo_dbh_ce, (char*)const_name, name_len, (char*)value, value_len TSRMLS_CC); #else zval *constant = malloc(sizeof(*constant)); ZVAL_STRINGL(constant, zend_strndup(value, value_len), value_len, 0); @@ -1158,7 +1223,7 @@ unsigned int name_len, long value TSRMLS_DC) { #if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1 - zend_declare_class_constant_long(pdo_dbh_ce, const_name, name_len, value TSRMLS_CC); + zend_declare_class_constant_long(pdo_dbh_ce, (char*)const_name, name_len, value TSRMLS_CC); #else zval *constant = malloc(sizeof(*constant)); ZVAL_LONG(constant, value); @@ -1319,6 +1384,7 @@ ALLOC_HASHTABLE(dbh->properties); zend_hash_init(dbh->properties, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy(dbh->properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + dbh->def_stmt_ce = pdo_dbstmt_ce; retval.handle = zend_objects_store_put(dbh, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbh_free_storage, NULL TSRMLS_CC); retval.handlers = &pdo_dbh_object_handlers; http://cvs.php.net/diff.php/php-src/ext/pdo/php_pdo_driver.h?r1=1.66.2.1&r2=1.66.2.2&ty=u Index: php-src/ext/pdo/php_pdo_driver.h diff -u php-src/ext/pdo/php_pdo_driver.h:1.66.2.1 php-src/ext/pdo/php_pdo_driver.h:1.66.2.2 --- php-src/ext/pdo/php_pdo_driver.h:1.66.2.1 Sat Sep 24 10:18:01 2005 +++ php-src/ext/pdo/php_pdo_driver.h Sun Oct 2 16:07:11 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_driver.h,v 1.66.2.1 2005/09/24 14:18:01 edink Exp $ */ +/* $Id: php_pdo_driver.h,v 1.66.2.2 2005/10/02 20:07:11 helly Exp $ */ #ifndef PHP_PDO_DRIVER_H #define PHP_PDO_DRIVER_H @@ -475,6 +475,10 @@ HashTable *cls_methods[PDO_DBH_DRIVER_METHOD_KIND__MAX]; pdo_driver_t *driver; + + zend_class_entry *def_stmt_ce; + + zval *def_stmt_ctor_args; }; /* describes a column */ http://cvs.php.net/co.php/php-src/ext/pdo/tests/pdo_030.phpt?r=1.1&p=1 Index: php-src/ext/pdo/tests/pdo_030.phpt +++ php-src/ext/pdo/tests/pdo_030.phpt --TEST-- PDO Common: extending PDO (4) --SKIPIF-- <?php # vim:ft=php if (!extension_loaded('pdo')) die('skip'); $dir = getenv('REDIR_TEST_DIR'); if (false == $dir) die('skip no driver'); require_once $dir . 'pdo_test.inc'; PDOTest::skip(); ?> --FILE-- <?php if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/'); require getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $data = array( array('10', 'Abc', 'zxy'), array('20', 'Def', 'wvu'), array('30', 'Ghi', 'tsr'), ); class PDOStatementX extends PDOStatement { public $dbh; protected function __construct($dbh) { $this->dbh = $dbh; $this->setFetchMode(PDO::FETCH_ASSOC); echo __METHOD__ . "()\n"; } function __destruct() { echo __METHOD__ . "()\n"; } function execute() { echo __METHOD__ . "()\n"; parent::execute(); } } class PDODatabase extends PDO { function __destruct() { echo __METHOD__ . "()\n"; } function query($sql) { echo __METHOD__ . "()\n"; return parent::query($sql); } } $db = PDOTest::factory('PDODatabase'); var_dump(get_class($db)); $db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))'); $stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)"); var_dump(get_class($stmt)); foreach ($data as $row) { $stmt->execute($row); } unset($stmt); echo "===QUERY===\n"; $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatementx', array($db))); $stmt = $db->query('SELECT * FROM test'); var_dump(get_class($stmt)); var_dump(get_class($stmt->dbh)); echo "===FOREACH===\n"; foreach($stmt as $obj) { var_dump($obj); } echo "===DONE===\n"; exit(0); ?> --EXPECT-- string(11) "PDODatabase" string(12) "PDOStatement" ===QUERY=== PDODatabase::query() PDOStatementX::__construct() string(13) "PDOStatementX" string(11) "PDODatabase" ===FOREACH=== array(3) { ["id"]=> string(2) "10" ["val"]=> string(3) "Abc" ["val2"]=> string(3) "zxy" } array(3) { ["id"]=> string(2) "20" ["val"]=> string(3) "Def" ["val2"]=> string(3) "wvu" } array(3) { ["id"]=> string(2) "30" ["val"]=> string(3) "Ghi" ["val2"]=> string(3) "tsr" } ===DONE=== PDODatabase::__destruct() PDOStatementX::__destruct() --UEXPECT-- unicode(11) "PDODatabase" unicode(12) "PDOStatement" ===QUERY=== PDODatabase::query() PDOStatementX::__construct() PDOStatementX::execute() unicode(13) "PDOStatementX" unicode(11) "PDODatabase" ===FOREACH=== array(3) { [u"id"]=> unicode(2) "10" [u"val"]=> unicode(3) "Abc" [u"val2"]=> unicode(3) "zxy" } array(3) { [u"id"]=> unicode(2) "20" [u"val"]=> unicode(3) "Def" [u"val2"]=> unicode(3) "wvu" } array(3) { [u"id"]=> unicode(2) "30" [u"val"]=> unicode(3) "Ghi" [u"val2"]=> unicode(3) "tsr" } ===DONE=== PDODatabase::__destruct() PDOStatementX::__destruct()
« previous php.cvs (#34230) next »