diff options
| author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:36:21 -0400 |
|---|---|---|
| committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:36:21 -0400 |
| commit | d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (patch) | |
| tree | b38e2e5c6974b9a15f103e5cf884cba9fff90ef4 /ext/pdo | |
| parent | a88a88d0986a4a32288c102cdbfebd78d7e91d99 (diff) | |
| download | php-upstream/5.2.0.tar.gz | |
Imported Upstream version 5.2.0upstream/5.2.0
Diffstat (limited to 'ext/pdo')
| -rwxr-xr-x | ext/pdo/config.m4 | 4 | ||||
| -rwxr-xr-x | ext/pdo/pdo.c | 73 | ||||
| -rwxr-xr-x | ext/pdo/pdo_dbh.c | 174 | ||||
| -rwxr-xr-x | ext/pdo/pdo_stmt.c | 80 | ||||
| -rwxr-xr-x | ext/pdo/php_pdo.h | 17 | ||||
| -rwxr-xr-x | ext/pdo/php_pdo_driver.h | 19 | ||||
| -rwxr-xr-x | ext/pdo/php_pdo_int.h | 4 | ||||
| -rwxr-xr-x | ext/pdo/tests/bug_36428.phpt | 33 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_38253.phpt | 47 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_38394.phpt | 51 | ||||
| -rw-r--r-- | ext/pdo/tests/pdo_017.phpt | 9 | ||||
| -rw-r--r-- | ext/pdo/tests/pdo_026.phpt | 2 | ||||
| -rwxr-xr-x | ext/pdo/tests/pdo_029.phpt | 2 | ||||
| -rwxr-xr-x | ext/pdo/tests/pdo_030.phpt | 37 | ||||
| -rwxr-xr-x | ext/pdo/tests/pdo_031.phpt | 2 | ||||
| -rw-r--r-- | ext/pdo/tests/pdo_033.phpt | 39 | ||||
| -rw-r--r-- | ext/pdo/tests/pdo_test.inc | 6 |
17 files changed, 417 insertions, 182 deletions
diff --git a/ext/pdo/config.m4 b/ext/pdo/config.m4 index e275fecf6..9497f12da 100755 --- a/ext/pdo/config.m4 +++ b/ext/pdo/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.15.2.3 2005/11/24 21:38:09 wez Exp $ +dnl $Id: config.m4,v 1.15.2.3.2.1 2006/08/24 16:00:43 tony2001 Exp $ dnl config.m4 for extension pdo dnl vim:se ts=2 sw=2 et: @@ -37,7 +37,6 @@ if test "$PHP_PDO" != "no"; then if test "$ext_shared" = "yes" ; then case $host_alias in *darwin*) - if test "$pdo_running_under_pear" = "1"; then AC_MSG_ERROR([ Due to the way that loadable modules work on OSX/Darwin, you need to compile the PDO package statically into the PHP core. @@ -45,7 +44,6 @@ compile the PDO package statically into the PHP core. Please follow the instructions at: http://netevil.org/node.php?nid=202 for more detail on this issue. ]) - fi ext_shared=no ;; esac diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index 10ece60c7..d6786c4c8 100755 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo.c,v 1.57.2.17 2006/01/01 12:50:11 sniper Exp $ */ +/* $Id: pdo.c,v 1.57.2.17.2.7 2006/10/14 15:06:11 bjori Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -36,6 +36,7 @@ static zend_class_entry *spl_ce_RuntimeException; ZEND_DECLARE_MODULE_GLOBALS(pdo) +static PHP_GINIT_FUNCTION(pdo); /* True global resources - no need for thread safety here */ @@ -53,11 +54,23 @@ int php_pdo_list_entry(void) /* for exceptional circumstances */ zend_class_entry *pdo_exception_ce; -PDO_API zend_class_entry *php_pdo_get_exception(void) +PDO_API zend_class_entry *php_pdo_get_dbh_ce() +{ + return pdo_dbh_ce; +} + +PDO_API zend_class_entry *php_pdo_get_exception() { return pdo_exception_ce; } +PDO_API char *php_pdo_str_tolower_dup(const char *src, int len) +{ + char *dest = emalloc(len + 1); + zend_str_tolower_copy(dest, src, len); + return dest; +} + PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC) { #if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1)) @@ -74,7 +87,7 @@ PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC) } } #endif -#if (PHP_MAJOR_VERSION < 6) +#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2) return zend_exception_get_default(); #else return zend_exception_get_default(TSRMLS_C); @@ -83,7 +96,7 @@ PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC) zend_class_entry *pdo_dbh_ce, *pdo_dbstmt_ce, *pdo_row_ce; -/* proto array pdo_drivers() +/* {{{ proto array pdo_drivers() Return array of available PDO drivers */ PHP_FUNCTION(pdo_drivers) { @@ -130,26 +143,27 @@ zend_module_entry pdo_module_entry = { pdo_functions, PHP_MINIT(pdo), PHP_MSHUTDOWN(pdo), - PHP_RINIT(pdo), - PHP_RSHUTDOWN(pdo), + NULL, + NULL, PHP_MINFO(pdo), - "1.0.3", - STANDARD_MODULE_PROPERTIES + "1.0.4dev", + PHP_MODULE_GLOBALS(pdo), + PHP_GINIT(pdo), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX }; /* }}} */ +/* TODO: visit persistent handles: for each persistent statement handle, + * remove bound parameter associations */ + #ifdef COMPILE_DL_PDO ZEND_GET_MODULE(pdo) #endif -/* {{{ PHP_INI */ -PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("pdo.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pdo_globals, pdo_globals) -PHP_INI_END() -/* }}} */ - -/* {{{ php_pdo_init_globals */ -static void php_pdo_init_globals(zend_pdo_globals *pdo_globals) +/* {{{ PHP_GINIT_FUNCTION */ +static PHP_GINIT_FUNCTION(pdo) { pdo_globals->global_value = 0; } @@ -303,11 +317,8 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC) PHP_MINIT_FUNCTION(pdo) { zend_class_entry ce; - - spl_ce_RuntimeException = NULL; - ZEND_INIT_MODULE_GLOBALS(pdo, php_pdo_init_globals, NULL); - REGISTER_INI_ENTRIES(); + spl_ce_RuntimeException = NULL; if (FAILURE == pdo_sqlstate_init_error_table()) { return FAILURE; @@ -334,29 +345,12 @@ PHP_MINIT_FUNCTION(pdo) /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(pdo) { - UNREGISTER_INI_ENTRIES(); zend_hash_destroy(&pdo_driver_hash); pdo_sqlstate_fini_error_table(); return SUCCESS; } /* }}} */ -/* {{{ PHP_RINIT_FUNCTION */ -PHP_RINIT_FUNCTION(pdo) -{ - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_RSHUTDOWN_FUNCTION */ -PHP_RSHUTDOWN_FUNCTION(pdo) -{ - /* TODO: visit persistent handles: for each persistent statement handle, - * remove bound parameter associations */ - return SUCCESS; -} -/* }}} */ - /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(pdo) { @@ -379,13 +373,12 @@ PHP_MINFO_FUNCTION(pdo) if (drivers) { efree(drivers); + } else { + efree(ldrivers); } php_info_print_table_end(); -#if 0 - DISPLAY_INI_ENTRIES(); -#endif } /* }}} */ diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index cbf443bc9..ec6d88041 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_dbh.c,v 1.82.2.31 2006/05/03 21:58:38 pollita Exp $ */ +/* $Id: pdo_dbh.c,v 1.82.2.31.2.7 2006/08/21 16:53:50 iliaa Exp $ */ /* The PDO Database Handle Class */ @@ -36,12 +36,13 @@ #include "zend_object_handlers.h" #include "zend_hash.h" -void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate, const char *supp TSRMLS_DC) +static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_DC); + +void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate, const char *supp TSRMLS_DC) /* {{{ */ { pdo_error_type *pdo_err = &dbh->error_code; char *message = NULL; const char *msg; - if (dbh->error_mode == PDO_ERRMODE_SILENT) { #if 0 @@ -98,8 +99,9 @@ void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate efree(message); } } +/* }}} */ -void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) +void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ { pdo_error_type *pdo_err = &dbh->error_code; const char *msg = "<<Unknown>>"; @@ -178,8 +180,9 @@ void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) efree(supp); } } +/* }}} */ -static char *dsn_from_uri(char *uri, char *buf, size_t buflen TSRMLS_DC) +static char *dsn_from_uri(char *uri, char *buf, size_t buflen TSRMLS_DC) /* {{{ */ { php_stream *stream; char *dsn = NULL; @@ -191,6 +194,7 @@ static char *dsn_from_uri(char *uri, char *buf, size_t buflen TSRMLS_DC) } return dsn; } +/* }}} */ /* {{{ proto void PDO::__construct(string dsn, string username, string passwd [, array options]) */ @@ -270,7 +274,7 @@ static PHP_METHOD(PDO, dbh_constructor) /* is this supposed to be a persistent connection ? */ if (options) { zval **v; - int plen; + int plen = 0; char *hashkey = NULL; zend_rsrc_list_entry *le; pdo_dbh_t *pdbh = NULL; @@ -338,7 +342,9 @@ static PHP_METHOD(PDO, dbh_constructor) /* switch over to the persistent one */ dbh = pdbh; zend_object_store_set_object(object, dbh TSRMLS_CC); - dbh->refcount++; + if (!call_factory) { + dbh->refcount++; + } } if (hashkey) { @@ -350,6 +356,7 @@ static PHP_METHOD(PDO, dbh_constructor) dbh->data_source = (const char*)pestrdup(colon + 1, is_persistent); dbh->username = username ? pestrdup(username, is_persistent) : NULL; dbh->password = password ? pestrdup(password, is_persistent) : NULL; + dbh->default_fetch_type = PDO_FETCH_BOTH; dbh->auto_commit = pdo_attr_lval(options, PDO_ATTR_AUTOCOMMIT, 1 TSRMLS_CC); @@ -383,6 +390,21 @@ static PHP_METHOD(PDO, dbh_constructor) } dbh->driver = driver; + + if (options) { + zval **attr_value; + char *str_key; + long long_key; + + zend_hash_internal_pointer_reset(Z_ARRVAL_P(options)); + while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(options), (void**)&attr_value) + && HASH_KEY_IS_LONG == zend_hash_get_current_key(Z_ARRVAL_P(options), &str_key, &long_key, 0)) { + + pdo_dbh_attribute_set(dbh, long_key, *attr_value TSRMLS_CC); + zend_hash_move_forward(Z_ARRVAL_P(options)); + } + } + return; } @@ -497,7 +519,7 @@ static PHP_METHOD(PDO, prepare) || 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, ctor_args); " + "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(); @@ -546,10 +568,11 @@ static PHP_METHOD(PDO, prepare) /* unconditionally keep this for later reference */ stmt->query_string = estrndup(statement, statement_len); stmt->query_stringlen = statement_len; - stmt->default_fetch_type = PDO_FETCH_BOTH; + stmt->default_fetch_type = dbh->default_fetch_type; stmt->dbh = dbh; /* give it a reference to me */ zend_objects_store_add_ref(getThis() TSRMLS_CC); + php_pdo_dbh_addref(dbh TSRMLS_CC); stmt->database_object_handle = *getThis(); /* we haven't created a lazy object yet */ ZVAL_NULL(&stmt->lazy_object_ref); @@ -644,20 +667,8 @@ static PHP_METHOD(PDO, rollBack) } /* }}} */ -/* {{{ proto bool PDO::setAttribute(long attribute, mixed value) - Set an attribute */ -static PHP_METHOD(PDO, setAttribute) +static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_DC) /* {{{ */ { - pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC); - long attr; - zval *value = NULL; - - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz!", &attr, &value)) { - RETURN_FALSE; - } - - PDO_CONSTRUCT_CHECK; - switch (attr) { case PDO_ATTR_ERRMODE: convert_to_long(value); @@ -666,13 +677,13 @@ static PHP_METHOD(PDO, setAttribute) case PDO_ERRMODE_WARNING: case PDO_ERRMODE_EXCEPTION: dbh->error_mode = Z_LVAL_P(value); - RETURN_TRUE; + return SUCCESS; default: pdo_raise_impl_error(dbh, NULL, "HY000", "invalid error mode" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); - RETURN_FALSE; + return FAILURE; } - RETURN_FALSE; + return FAILURE; case PDO_ATTR_CASE: convert_to_long(value); @@ -681,23 +692,32 @@ static PHP_METHOD(PDO, setAttribute) case PDO_CASE_UPPER: case PDO_CASE_LOWER: dbh->desired_case = Z_LVAL_P(value); - RETURN_TRUE; + return SUCCESS; default: pdo_raise_impl_error(dbh, NULL, "HY000", "invalid case folding mode" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); - RETURN_FALSE; + return FAILURE; } - RETURN_FALSE; + return FAILURE; case PDO_ATTR_ORACLE_NULLS: convert_to_long(value); dbh->oracle_nulls = Z_LVAL_P(value); - RETURN_TRUE; + return SUCCESS; + + case PDO_ATTR_DEFAULT_FETCH_MODE: + convert_to_long(value); + if (Z_LVAL_P(value) == PDO_FETCH_USE_DEFAULT) { + pdo_raise_impl_error(dbh, NULL, "HY000", "invalid fetch mode type" TSRMLS_CC); + return FAILURE; + } + dbh->default_fetch_type = Z_LVAL_P(value); + return SUCCESS; case PDO_ATTR_STRINGIFY_FETCHES: convert_to_long(value); dbh->stringify = Z_LVAL_P(value) ? 1 : 0; - RETURN_TRUE; + return SUCCESS; case PDO_ATTR_STATEMENT_CLASS: { /* array(string classname, array(mixed ctor_args)) */ @@ -709,7 +729,7 @@ static PHP_METHOD(PDO, setAttribute) "PDO::ATTR_STATEMENT_CLASS cannot be used with persistent PDO instances" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); - RETURN_FALSE; + return FAILURE; } if (Z_TYPE_P(value) != IS_ARRAY || zend_hash_index_find(Z_ARRVAL_P(value), 0, (void**)&item) == FAILURE @@ -721,19 +741,19 @@ static PHP_METHOD(PDO, setAttribute) "the classname must be a string specifying an existing class" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); - RETURN_FALSE; + return FAILURE; } 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; + return FAILURE; } 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; + return FAILURE; } dbh->def_stmt_ce = *pce; if (dbh->def_stmt_ctor_args) { @@ -747,12 +767,12 @@ static PHP_METHOD(PDO, setAttribute) "ctor_args must be an array" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); - RETURN_FALSE; + return FAILURE; } (*item)->refcount++; dbh->def_stmt_ctor_args = *item; } - RETURN_TRUE; + return SUCCESS; } default: @@ -765,7 +785,7 @@ static PHP_METHOD(PDO, setAttribute) PDO_DBH_CLEAR_ERR(); if (dbh->methods->set_attribute(dbh, attr, value TSRMLS_CC)) { - RETURN_TRUE; + return SUCCESS; } fail: @@ -776,7 +796,28 @@ fail: } else { PDO_HANDLE_DBH_ERR(); } - RETURN_FALSE; + return FAILURE; +} +/* }}} */ + +/* {{{ proto bool PDO::setAttribute(long attribute, mixed value) + Set an attribute */ +static PHP_METHOD(PDO, setAttribute) +{ + pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + long attr; + zval *value = NULL; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz!", &attr, &value)) { + RETURN_FALSE; + } + + PDO_CONSTRUCT_CHECK; + + if (pdo_dbh_attribute_set(dbh, attr, value TSRMLS_CC)) { + RETURN_TRUE; + } + RETURN_FALSE; } /* }}} */ @@ -819,6 +860,9 @@ static PHP_METHOD(PDO, getAttribute) add_next_index_zval(return_value, dbh->def_stmt_ctor_args); } return; + case PDO_ATTR_DEFAULT_FETCH_MODE: + RETURN_LONG(dbh->default_fetch_type); + } if (!dbh->methods->get_attribute) { @@ -968,18 +1012,22 @@ static PHP_METHOD(PDO, query) /* unconditionally keep this for later reference */ stmt->query_string = estrndup(statement, statement_len); stmt->query_stringlen = statement_len; - stmt->default_fetch_type = PDO_FETCH_BOTH; + + stmt->default_fetch_type = dbh->default_fetch_type; stmt->active_query_string = stmt->query_string; stmt->active_query_stringlen = statement_len; stmt->dbh = dbh; /* give it a reference to me */ zend_objects_store_add_ref(getThis() TSRMLS_CC); + php_pdo_dbh_addref(dbh TSRMLS_CC); stmt->database_object_handle = *getThis(); /* we haven't created a lazy object yet */ ZVAL_NULL(&stmt->lazy_object_ref); if (dbh->methods->preparer(dbh, statement, statement_len, stmt, NULL TSRMLS_CC)) { if (ZEND_NUM_ARGS() == 1 || SUCCESS == pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAM_PASSTHRU, stmt, 1)) { + PDO_STMT_CLEAR_ERR(); + /* now execute the statement */ PDO_STMT_CLEAR_ERR(); if (stmt->methods->executer(stmt TSRMLS_CC)) { @@ -1075,8 +1123,8 @@ static PHP_METHOD(PDO, getAvailableDrivers) zend_function_entry pdo_dbh_functions[] = { ZEND_MALIAS(PDO, __construct, dbh_constructor, NULL, ZEND_ACC_PUBLIC) - PHP_ME(PDO, prepare, NULL, ZEND_ACC_PUBLIC) - PHP_ME(PDO, beginTransaction,NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, prepare, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, beginTransaction, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, commit, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, rollBack, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, setAttribute, NULL, ZEND_ACC_PUBLIC) @@ -1202,33 +1250,14 @@ static int dbh_compare(zval *object1, zval *object2 TSRMLS_DC) return -1; } -static zend_object_handlers pdo_dbh_object_handlers; - -PDO_API void php_pdo_declare_stringl_constant(const char *const_name, - size_t name_len, const char *value, size_t value_len TSRMLS_DC) +static zend_object_value dbh_ze1_clone_obj(zval *object TSRMLS_DC) { -#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1 - 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); - INIT_PZVAL(constant); - zend_hash_update(&pdo_dbh_ce->constants_table, (char*)const_name, name_len+1, &constant, sizeof(zval*), NULL); -#endif + php_error(E_ERROR, "Cannot clone object of class %s due to 'zend.ze1_compatibility_mode'", Z_OBJCE_P(object)->name); + return object->value.obj; } -PDO_API void php_pdo_declare_long_constant(const char *const_name, - size_t name_len, long value TSRMLS_DC) -{ -#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1 - 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); - INIT_PZVAL(constant); - zend_hash_update(&pdo_dbh_ce->constants_table, (char*)const_name, name_len+1, &constant, sizeof(zval*), NULL); -#endif -} +static zend_object_handlers pdo_dbh_object_handlers; +static zend_object_handlers pdo_dbh_object_handlers_ze1; void pdo_dbh_init(TSRMLS_D) { @@ -1241,6 +1270,11 @@ void pdo_dbh_init(TSRMLS_D) memcpy(&pdo_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); pdo_dbh_object_handlers.get_method = dbh_method_get; pdo_dbh_object_handlers.compare_objects = dbh_compare; + + memcpy(&pdo_dbh_object_handlers_ze1, &std_object_handlers, sizeof(zend_object_handlers)); + pdo_dbh_object_handlers_ze1.get_method = dbh_method_get; + pdo_dbh_object_handlers_ze1.compare_objects = dbh_compare; + pdo_dbh_object_handlers_ze1.clone_obj = dbh_ze1_clone_obj; REGISTER_PDO_CLASS_CONST_LONG("PARAM_BOOL", (long)PDO_PARAM_BOOL); REGISTER_PDO_CLASS_CONST_LONG("PARAM_NULL", (long)PDO_PARAM_NULL); @@ -1274,6 +1308,7 @@ void pdo_dbh_init(TSRMLS_D) #if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1 REGISTER_PDO_CLASS_CONST_LONG("FETCH_SERIALIZE",(long)PDO_FETCH_SERIALIZE); #endif + REGISTER_PDO_CLASS_CONST_LONG("FETCH_PROPS_LATE",(long)PDO_FETCH_PROPS_LATE); REGISTER_PDO_CLASS_CONST_LONG("FETCH_NAMED",(long)PDO_FETCH_NAMED); REGISTER_PDO_CLASS_CONST_LONG("ATTR_AUTOCOMMIT", (long)PDO_ATTR_AUTOCOMMIT); @@ -1296,6 +1331,7 @@ void pdo_dbh_init(TSRMLS_D) REGISTER_PDO_CLASS_CONST_LONG("ATTR_STRINGIFY_FETCHES",(long)PDO_ATTR_STRINGIFY_FETCHES); REGISTER_PDO_CLASS_CONST_LONG("ATTR_MAX_COLUMN_LEN",(long)PDO_ATTR_MAX_COLUMN_LEN); REGISTER_PDO_CLASS_CONST_LONG("ATTR_EMULATE_PREPARES",(long)PDO_ATTR_EMULATE_PREPARES); + REGISTER_PDO_CLASS_CONST_LONG("ATTR_DEFAULT_FETCH_MODE",(long)PDO_ATTR_DEFAULT_FETCH_MODE); REGISTER_PDO_CLASS_CONST_LONG("ERRMODE_SILENT", (long)PDO_ERRMODE_SILENT); REGISTER_PDO_CLASS_CONST_LONG("ERRMODE_WARNING", (long)PDO_ERRMODE_WARNING); @@ -1339,7 +1375,7 @@ void pdo_dbh_init(TSRMLS_D) static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) { int i; - + if (--dbh->refcount) return; @@ -1361,6 +1397,10 @@ static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) if (dbh->password) { pefree(dbh->password, dbh->is_persistent); } + + if (dbh->persistent_id) { + pefree((char *)dbh->persistent_id, dbh->is_persistent); + } if (dbh->def_stmt_ctor_args) { zval_ptr_dtor(&dbh->def_stmt_ctor_args); @@ -1422,7 +1462,7 @@ zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC) 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; + retval.handlers = EG(ze1_compatibility_mode) ? &pdo_dbh_object_handlers_ze1 : &pdo_dbh_object_handlers; return retval; } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index a9f65e28d..a837a14f0 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_stmt.c,v 1.118.2.38 2006/04/22 19:10:53 tony2001 Exp $ */ +/* $Id: pdo_stmt.c,v 1.118.2.38.2.8 2006/08/23 19:15:57 tony2001 Exp $ */ /* The PDO Statement Handle Class */ @@ -392,6 +392,12 @@ static PHP_METHOD(PDOStatement, execute) zval **tmp; uint str_length; ulong num_index; + + if (stmt->bound_params) { + zend_hash_destroy(stmt->bound_params); + FREE_HASHTABLE(stmt->bound_params); + stmt->bound_params = NULL; + } zend_hash_internal_pointer_reset(Z_ARRVAL_P(input_params)); while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(input_params), (void*)&tmp)) { @@ -703,8 +709,8 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * fci, zend_fcall_info_cache * fcc, int num_args TSRMLS_DC) /* {{{ */ { - zval **object = NULL, **method; - char *fname, *cname; + zval **object = NULL, **method = NULL; + char *fname = NULL, *cname; zend_class_entry * ce = NULL, **pce; zend_function *function_handler; @@ -717,6 +723,12 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * method = (zval**)Z_ARRVAL_P(callable)->pListHead->pListNext->pData; if (Z_TYPE_PP(object) == IS_STRING) { /* static call */ + if (zend_lookup_class(Z_STRVAL_PP(object), Z_STRLEN_PP(object), &pce TSRMLS_CC) == FAILURE) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not exist" TSRMLS_CC); + return 0; + } else { + ce = *pce; + } object = NULL; } else if (Z_TYPE_PP(object) == IS_OBJECT) { /* object call */ ce = Z_OBJCE_PP(object); @@ -729,10 +741,15 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback; bogus method name" TSRMLS_CC); return 0; } + } else if (Z_TYPE_P(callable) == IS_STRING) { + method = &callable; } - if (!zend_is_callable(callable, 0, &fname)) { + if (!method || !zend_is_callable(callable, 0, &fname)) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback" TSRMLS_CC); + if (fname) { + efree(fname); + } return 0; } @@ -825,9 +842,9 @@ static int do_fetch_opt_finish(pdo_stmt_t *stmt, int free_ctor_agrs TSRMLS_DC) / static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_fetch_type how, enum pdo_fetch_orientation ori, long offset, zval *return_all TSRMLS_DC) /* {{{ */ { - int flags = how & PDO_FETCH_FLAGS, idx, old_arg_count; - zend_class_entry * ce, * old_ce; - zval grp_val, *grp, **pgrp, *retval, *old_ctor_args; + int flags = how & PDO_FETCH_FLAGS, idx, old_arg_count = 0; + zend_class_entry *ce = NULL, *old_ce = NULL; + zval grp_val, *grp, **pgrp, *retval, *old_ctor_args = NULL; how = how & ~PDO_FETCH_FLAGS; if (how == PDO_FETCH_USE_DEFAULT) { @@ -854,13 +871,14 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, RETVAL_FALSE; switch (how) { + case PDO_FETCH_USE_DEFAULT: case PDO_FETCH_ASSOC: case PDO_FETCH_BOTH: case PDO_FETCH_NUM: case PDO_FETCH_NAMED: if (!return_all) { ALLOC_HASHTABLE(return_value->value.ht); - zend_hash_init(return_value->value.ht, stmt->column_count, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(return_value->value.ht, stmt->column_count, NULL, ZVAL_PTR_DTOR, 0); Z_TYPE_P(return_value) = IS_ARRAY; } else { array_init(return_value); @@ -907,6 +925,10 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, zval_dtor(&val); } ce = stmt->fetch.cls.ce; + if (!ce) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch class specified" TSRMLS_CC); + return 0; + } if ((flags & PDO_FETCH_SERIALIZE) == 0) { object_init_ex(return_value, ce); if (!stmt->fetch.cls.fci.size) { @@ -915,6 +937,18 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, return 0; } } + if (ce->constructor && (flags & PDO_FETCH_PROPS_LATE)) { + stmt->fetch.cls.fci.object_pp = &return_value; + stmt->fetch.cls.fcc.object_pp = &return_value; + if (zend_call_function(&stmt->fetch.cls.fci, &stmt->fetch.cls.fcc TSRMLS_CC) == FAILURE) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not call class constructor" TSRMLS_CC); + return 0; + } else { + if (stmt->fetch.cls.retval_ptr) { + zval_ptr_dtor(&stmt->fetch.cls.retval_ptr); + } + } + } } break; @@ -936,6 +970,10 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, break; case PDO_FETCH_FUNC: + if (!stmt->fetch.func.function) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch function specified" TSRMLS_CC); + return 0; + } if (!stmt->fetch.func.fci.size) { if (!do_fetch_func_prepare(stmt TSRMLS_CC)) { @@ -971,6 +1009,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, add_assoc_zval(return_value, stmt->columns[i].name, val); break; + case PDO_FETCH_USE_DEFAULT: case PDO_FETCH_BOTH: add_assoc_zval(return_value, stmt->columns[i].name, val); ZVAL_ADDREF(val); @@ -1077,7 +1116,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, switch (how) { case PDO_FETCH_CLASS: - if (ce->constructor) { + if (ce->constructor && !(flags & PDO_FETCH_PROPS_LATE)) { stmt->fetch.cls.fci.object_pp = &return_value; stmt->fetch.cls.fcc.object_pp = &return_value; if (zend_call_function(&stmt->fetch.cls.fci, &stmt->fetch.cls.fcc TSRMLS_CC) == FAILURE) { @@ -1505,7 +1544,11 @@ static int register_bound_param(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, } ZVAL_ADDREF(param.parameter); - return really_register_bound_param(¶m, stmt, is_param TSRMLS_CC); + if (!really_register_bound_param(¶m, stmt, is_param TSRMLS_CC)) { + zval_ptr_dtor(&(param.parameter)); + return 0; + } + return 1; } /* }}} */ /* {{{ proto bool PDOStatement::bindValue(mixed $paramno, mixed $param [, int $type ]) @@ -1517,7 +1560,7 @@ static PHP_METHOD(PDOStatement, bindValue) param.paramno = -1; param.param_type = PDO_PARAM_STR; - + if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz/|l", ¶m.paramno, ¶m.parameter, ¶m.param_type)) { if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|l", ¶m.name, @@ -1534,7 +1577,11 @@ static PHP_METHOD(PDOStatement, bindValue) } ZVAL_ADDREF(param.parameter); - RETURN_BOOL(really_register_bound_param(¶m, stmt, TRUE TSRMLS_CC)); + if (!really_register_bound_param(¶m, stmt, TRUE TSRMLS_CC)) { + zval_ptr_dtor(&(param.parameter)); + RETURN_FALSE; + } + RETURN_TRUE; } /* }}} */ @@ -2225,6 +2272,9 @@ static void free_statement(pdo_stmt_t *stmt TSRMLS_DC) do_fetch_opt_finish(stmt, 1 TSRMLS_CC); zend_objects_store_del_ref(&stmt->database_object_handle TSRMLS_CC); + if (stmt->dbh) { + php_pdo_dbh_delref(stmt->dbh TSRMLS_CC); + } efree(stmt); } @@ -2357,11 +2407,15 @@ static zend_object_iterator_funcs pdo_stmt_iter_funcs = { NULL }; -zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC) +zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) { pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(object TSRMLS_CC); struct php_pdo_iterator *I; + if (by_ref) { + zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + } + I = ecalloc(1, sizeof(*I)); I->iter.funcs = &pdo_stmt_iter_funcs; I->iter.data = I; diff --git a/ext/pdo/php_pdo.h b/ext/pdo/php_pdo.h index 74078b4de..31c610c54 100755 --- a/ext/pdo/php_pdo.h +++ b/ext/pdo/php_pdo.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo.h,v 1.7.2.5 2006/01/01 12:50:11 sniper Exp $ */ +/* $Id: php_pdo.h,v 1.7.2.5.2.2 2006/06/07 21:09:52 rasmus Exp $ */ #ifndef PHP_PDO_H #define PHP_PDO_H @@ -48,8 +48,6 @@ extern zend_module_entry pdo_module_entry; PHP_MINIT_FUNCTION(pdo); PHP_MSHUTDOWN_FUNCTION(pdo); -PHP_RINIT_FUNCTION(pdo); -PHP_RSHUTDOWN_FUNCTION(pdo); PHP_MINFO_FUNCTION(pdo); ZEND_BEGIN_MODULE_GLOBALS(pdo) @@ -62,14 +60,17 @@ ZEND_END_MODULE_GLOBALS(pdo) # define PDOG(v) (pdo_globals.v) #endif -PDO_API void php_pdo_declare_long_constant(const char *const_name, size_t name_len, long value TSRMLS_DC); -PDO_API void php_pdo_declare_stringl_constant(const char *const_name, size_t name_len, const char *value, size_t value_len TSRMLS_DC); - #define REGISTER_PDO_CLASS_CONST_LONG(const_name, value) \ - php_pdo_declare_long_constant(const_name, sizeof(const_name)-1, (long)value TSRMLS_CC); + zend_declare_class_constant_long(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, (long)value TSRMLS_CC); + +#define REGISTER_PDO_CONST_LONG(const_name, value) { \ + zend_class_entry **pce; \ + if (zend_hash_find(CG(class_table), "pdo", sizeof("pdo"), (void **) &pce) != FAILURE) \ + zend_declare_class_constant_long(*pce, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC); \ +} \ #define REGISTER_PDO_CLASS_CONST_STRING(const_name, value) \ - php_pdo_declare_stringl_constant(const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC); + zend_declare_class_constant_stringl(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC); #define PDO_CONSTRUCT_CHECK \ if (!dbh->driver) { \ diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 451778109..e87650b1b 100755 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_driver.h,v 1.66.2.11 2006/04/09 08:05:01 wez Exp $ */ +/* $Id: php_pdo_driver.h,v 1.66.2.11.2.3 2006/09/28 23:27:59 tony2001 Exp $ */ #ifndef PHP_PDO_DRIVER_H #define PHP_PDO_DRIVER_H @@ -44,7 +44,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC); # define FALSE 0 #endif -#define PDO_DRIVER_API 20060409 +#define PDO_DRIVER_API 20060511 enum pdo_param_type { PDO_PARAM_NULL, @@ -98,6 +98,7 @@ enum pdo_fetch_type { #define PDO_FETCH_UNIQUE 0x00030000 /* fetch into groups assuming first col is unique */ #define PDO_FETCH_CLASSTYPE 0x00040000 /* fetch class gets its class name from 1st column */ #define PDO_FETCH_SERIALIZE 0x00080000 /* fetch class instances by calling serialize */ +#define PDO_FETCH_PROPS_LATE 0x00100000 /* fetch props after calling ctor */ /* fetch orientation for scrollable cursors */ enum pdo_fetch_orientation { @@ -129,6 +130,7 @@ enum pdo_attribute_type { PDO_ATTR_DRIVER_NAME, /* name of the driver (as used in the constructor) */ PDO_ATTR_STRINGIFY_FETCHES, /* converts integer/float types to strings during fetch */ PDO_ATTR_MAX_COLUMN_LEN, /* make database calculate maximum length of data found in a column */ + PDO_ATTR_DEFAULT_FETCH_MODE, /* Set the default fetch mode */ PDO_ATTR_EMULATE_PREPARES, /* use query emulation rather than native */ /* this defines the start of the range for driver specific options. @@ -340,7 +342,7 @@ enum pdo_param_event { PDO_PARAM_EVT_EXEC_POST, PDO_PARAM_EVT_FETCH_PRE, PDO_PARAM_EVT_FETCH_POST, - PDO_PARAM_EVT_NORMALIZE + PDO_PARAM_EVT_NORMALIZE, }; typedef int (*pdo_stmt_param_hook_func)(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC); @@ -489,6 +491,7 @@ struct _pdo_dbh_t { pdo_driver_t *driver; zend_class_entry *def_stmt_ce; + zval *def_stmt_ctor_args; /* when calling PDO::query(), we need to keep the error @@ -497,12 +500,15 @@ struct _pdo_dbh_t { * when PDO::query() fails */ pdo_stmt_t *query_stmt; zval query_stmt_zval; + + /* defaults for fetches */ + enum pdo_fetch_type default_fetch_type; }; /* describes a column */ struct pdo_column_data { char *name; - long namelen; + int namelen; unsigned long maxlen; enum pdo_param_type param_type; unsigned long precision; @@ -515,7 +521,7 @@ struct pdo_column_data { struct pdo_bound_param_data { long paramno; /* if -1, then it has a name, and we don't know the index *yet* */ char *name; - long namelen; + int namelen; long max_value_len; /* as a hint for pre-allocation */ @@ -639,7 +645,8 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, unsigned long data_source_len, struct pdo_data_src_parser *parsed, int nparams); -PDO_API zend_class_entry *php_pdo_get_exception(void); +PDO_API zend_class_entry *php_pdo_get_dbh_ce(); +PDO_API zend_class_entry *php_pdo_get_exception(); PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery, int *outquery_len TSRMLS_DC); diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h index fb567af8c..c489903dd 100755 --- a/ext/pdo/php_pdo_int.h +++ b/ext/pdo/php_pdo_int.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_int.h,v 1.17.2.6 2006/01/01 12:50:11 sniper Exp $ */ +/* $Id: php_pdo_int.h,v 1.17.2.6.2.1 2006/05/11 22:43:44 helly Exp $ */ /* Stuff private to the PDO extension and not for consumption by PDO drivers * */ @@ -40,7 +40,7 @@ extern zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC); extern zend_function_entry pdo_dbstmt_functions[]; extern zend_class_entry *pdo_dbstmt_ce; void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC); -zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC); +zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); extern zend_object_handlers pdo_dbstmt_object_handlers; int pdo_stmt_describe_columns(pdo_stmt_t *stmt TSRMLS_DC); int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip_first_arg); diff --git a/ext/pdo/tests/bug_36428.phpt b/ext/pdo/tests/bug_36428.phpt new file mode 100755 index 000000000..6abba6bd7 --- /dev/null +++ b/ext/pdo/tests/bug_36428.phpt @@ -0,0 +1,33 @@ +--TEST-- +PDO Common: PHP Bug #36428: Incorrect error message for PDO::fetchAll +--SKIPIF-- +<?php # vim:ft=php +if (!extension_loaded('pdo')) die('skip'); +if (!extension_loaded('simplexml')) die('skip SimpleXML not loaded'); +$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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; + +$db = PDOTest::factory(); +$db->exec("CREATE TABLE test (a VARCHAR(10))"); +$db->exec("INSERT INTO test (a) VALUES ('xyz')"); +$res = $db->query("SELECT a FROM test"); +var_dump($res->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'SimpleXMLElement', array('<root/>'))); + +?> +===DONE=== +--EXPECTF-- +array(1) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["a"]=> + string(3) "xyz" + } +} +===DONE=== diff --git a/ext/pdo/tests/bug_38253.phpt b/ext/pdo/tests/bug_38253.phpt new file mode 100644 index 000000000..6dfdab8df --- /dev/null +++ b/ext/pdo/tests/bug_38253.phpt @@ -0,0 +1,47 @@ +--TEST-- +PDO Common: PHP Bug #38253: PDO produces segfault with default fetch mode +--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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; +$pdo = PDOTest::factory(); + +$pdo->exec ("create table test (id integer primary key, n text)"); +$pdo->exec ("INSERT INTO test (id, n) VALUES (1, 'hi')"); + +$pdo->setAttribute (PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS); +$stmt = $pdo->prepare ("SELECT * FROM test"); +$stmt->execute(); +var_dump($stmt->fetchAll()); + +$pdo = PDOTest::factory(); + +$pdo->exec ("create table test2 (id integer primary key, n text)"); +$pdo->exec ("INSERT INTO test2 (id, n) VALUES (1,'hi')"); + +$pdo->setAttribute (PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_FUNC); +$stmt = $pdo->prepare ("SELECT * FROM test2"); +$stmt->execute(); +var_dump($stmt->fetchAll()); + +?> +--EXPECTF-- +Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: No fetch class specified in %s on line %d + +Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error%s on line %d +array(0) { +} + +Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: No fetch function specified in %s on line %d + +Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error%s on line %d +array(0) { +} diff --git a/ext/pdo/tests/bug_38394.phpt b/ext/pdo/tests/bug_38394.phpt new file mode 100644 index 000000000..38ce9bc36 --- /dev/null +++ b/ext/pdo/tests/bug_38394.phpt @@ -0,0 +1,51 @@ +--TEST-- +PDO Common: PHP Bug #38394: Prepared statement error stops subsequent statements +--SKIPIF-- +<?php # vim:ft=php +if (!extension_loaded('pdo')) die('skip'); +$dir = getenv('REDIR_TEST_DIR'); +if (false == $dir) die('skip no driver'); +if (!strncasecmp(getenv('PDOTEST_DSN'), 'sqlite2', strlen('sqlite2'))) die('skip not relevant for pdo_sqlite2 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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; + +$db = PDOTest::factory(); +$db->exec("CREATE TABLE test (a INT, b INT, c INT)"); +$s = $db->prepare("INSERT INTO test (a,b,c) VALUES (:a,:b,:c)"); + +$s->execute(array('a' => 1, 'b' => 2, 'c' => 3)); + +@$s->execute(array('a' => 5, 'b' => 6, 'c' => 7, 'd' => 8)); + +$s->execute(array('a' => 9, 'b' => 10, 'c' => 11)); + +var_dump($db->query("SELECT * FROM test")->fetchAll(PDO::FETCH_ASSOC)); +?> +===DONE=== +--EXPECTF-- +array(2) { + [0]=> + array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" + } + [1]=> + array(3) { + ["a"]=> + string(1) "9" + ["b"]=> + string(2) "10" + ["c"]=> + string(2) "11" + } +} +===DONE=== diff --git a/ext/pdo/tests/pdo_017.phpt b/ext/pdo/tests/pdo_017.phpt index f1bfb97f6..651ee2860 100644 --- a/ext/pdo/tests/pdo_017.phpt +++ b/ext/pdo/tests/pdo_017.phpt @@ -56,8 +56,17 @@ $db->rollBack(); echo countRows('rollback'); +$db->beginTransaction(); +$delete->execute(); +echo countRows('delete'); +$db->commit(); + +echo countRows('commit'); + ?> --EXPECT-- Counted 3 rows after insert. Counted 0 rows after delete. Counted 3 rows after rollback. +Counted 0 rows after delete. +Counted 0 rows after commit. diff --git a/ext/pdo/tests/pdo_026.phpt b/ext/pdo/tests/pdo_026.phpt index a0891bedf..d993f3244 100644 --- a/ext/pdo/tests/pdo_026.phpt +++ b/ext/pdo/tests/pdo_026.phpt @@ -107,5 +107,5 @@ array(3) { string(3) "tsr" } ===DONE=== -PDODatabase::__destruct() PDOStatementX::__destruct() +PDODatabase::__destruct() diff --git a/ext/pdo/tests/pdo_029.phpt b/ext/pdo/tests/pdo_029.phpt index c0b674cd4..a5847149c 100755 --- a/ext/pdo/tests/pdo_029.phpt +++ b/ext/pdo/tests/pdo_029.phpt @@ -121,5 +121,5 @@ array(3) { string(3) "tsr" } ===DONE=== -PDODatabase::__destruct() PDOStatementX::__destruct() +PDODatabase::__destruct() diff --git a/ext/pdo/tests/pdo_030.phpt b/ext/pdo/tests/pdo_030.phpt index e9d547540..b6482d69d 100755 --- a/ext/pdo/tests/pdo_030.phpt +++ b/ext/pdo/tests/pdo_030.phpt @@ -135,42 +135,5 @@ array(3) { 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() diff --git a/ext/pdo/tests/pdo_031.phpt b/ext/pdo/tests/pdo_031.phpt index 79f6b4252..9065ce971 100755 --- a/ext/pdo/tests/pdo_031.phpt +++ b/ext/pdo/tests/pdo_031.phpt @@ -3,7 +3,7 @@ PDO Common: PDOStatement SPL iterator --SKIPIF-- <?php # vim:ft=php if (!extension_loaded('pdo')) die('skip'); -if (!extension_loaded('SPL')) die ('skip SPL not available'); +if (!extension_loaded('SPL')) die('skip SPL not available'); $dir = getenv('REDIR_TEST_DIR'); if (false == $dir) die('skip no driver'); require_once $dir . 'pdo_test.inc'; diff --git a/ext/pdo/tests/pdo_033.phpt b/ext/pdo/tests/pdo_033.phpt new file mode 100644 index 000000000..9739c0e0e --- /dev/null +++ b/ext/pdo/tests/pdo_033.phpt @@ -0,0 +1,39 @@ +--TEST-- +PDO Common: PDO::quote() +--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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; +$db = PDOTest::factory(); + +$unquoted = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'; + +$quoted = $db->quote($unquoted); + +$db->query("CREATE TABLE test (t char(100))"); +$db->query("INSERT INTO test (t) VALUES($quoted)"); + +$stmt = $db->prepare('SELECT * from test'); +$stmt->execute(); + +print_r($stmt->fetchAll(PDO::FETCH_ASSOC)); + + +?> +--EXPECT-- +Array +( + [0] => Array + ( + [t] => !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + ) + +) diff --git a/ext/pdo/tests/pdo_test.inc b/ext/pdo/tests/pdo_test.inc index a023fd89b..4d14f32d4 100644 --- a/ext/pdo/tests/pdo_test.inc +++ b/ext/pdo/tests/pdo_test.inc @@ -65,9 +65,9 @@ class PDOTest { } static function detect_transactional_mysql_engine($db) { - foreach ($db->query('show engines') as $row) { - if ($row[1] == 'YES' && ($row[0] == 'INNOBASE' || $row[0] == 'BDB')) { - return $row[0]; + foreach ($db->query("show variables like 'have%'") as $row) { + if ($row[1] == 'YES' && ($row[0] == 'have_innodb' || $row[0] == 'have_bdb')) { + return str_replace("have_", "", $row[0]); } } return false; |
