diff options
Diffstat (limited to 'ext/pdo')
-rwxr-xr-x | ext/pdo/pdo.c | 22 | ||||
-rwxr-xr-x | ext/pdo/pdo_dbh.c | 157 | ||||
-rwxr-xr-x | ext/pdo/pdo_stmt.c | 34 | ||||
-rwxr-xr-x | ext/pdo/php_pdo.h | 13 | ||||
-rwxr-xr-x | ext/pdo/php_pdo_driver.h | 13 | ||||
-rwxr-xr-x | ext/pdo/php_pdo_int.h | 2 |
6 files changed, 157 insertions, 84 deletions
diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index a41dce27e3..99f658378c 100755 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -53,11 +53,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 +86,7 @@ PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC) } } #endif -#if (PHP_MAJOR_VERSION <= 5) && (PHP_MINOR_VERSION < 2) +#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2) return zend_exception_get_default(); #else return zend_exception_get_default(TSRMLS_C); @@ -83,7 +95,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) { @@ -133,7 +145,7 @@ zend_module_entry pdo_module_entry = { PHP_RINIT(pdo), PHP_RSHUTDOWN(pdo), PHP_MINFO(pdo), - "1.0.3", + "1.0.4dev", STANDARD_MODULE_PROPERTIES }; /* }}} */ @@ -303,7 +315,7 @@ 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); diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 6dc413883d..021c3efe85 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -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]) */ @@ -350,6 +354,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 +388,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 +517,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,7 +566,7 @@ 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); @@ -644,20 +664,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 +674,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 +689,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 +726,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 +738,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 +764,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 +782,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 +793,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 +857,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,7 +1009,8 @@ 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; @@ -980,6 +1022,8 @@ static PHP_METHOD(PDO, query) 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)) { @@ -1005,6 +1049,11 @@ static PHP_METHOD(PDO, query) zval_dtor(return_value); } + PDO_HANDLE_STMT_ERR(); + + /* kill the object handle for the stmt here */ + zval_dtor(return_value); + RETURN_FALSE; } /* }}} */ @@ -1075,8 +1124,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) @@ -1204,32 +1253,6 @@ static int dbh_compare(zval *object1, zval *object2 TSRMLS_DC) 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) -{ -#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 -} - -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 -} - void pdo_dbh_init(TSRMLS_D) { zend_class_entry ce; @@ -1274,6 +1297,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 +1320,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 +1364,7 @@ void pdo_dbh_init(TSRMLS_D) static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) { int i; - + if (--dbh->refcount) return; @@ -1361,7 +1386,7 @@ static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) if (dbh->password) { pefree(dbh->password, dbh->is_persistent); } - + if (dbh->def_stmt_ctor_args) { zval_ptr_dtor(&dbh->def_stmt_ctor_args); } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 2d5a98a569..6030fa3b95 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -717,6 +717,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,6 +735,8 @@ 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)) { @@ -854,13 +862,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); @@ -915,6 +924,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; @@ -971,6 +992,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 +1099,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) { @@ -1517,7 +1539,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, @@ -2357,11 +2379,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 b8758eeed9..ae3c15606d 100755 --- a/ext/pdo/php_pdo.h +++ b/ext/pdo/php_pdo.h @@ -62,14 +62,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 8444db0ace..60665cb471 100755 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/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,6 +500,9 @@ 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 */ @@ -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 aca881b655..8e6832877c 100755 --- a/ext/pdo/php_pdo_int.h +++ b/ext/pdo/php_pdo_int.h @@ -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); |