wez Sat Dec 9 22:18:43 2006 UTC Modified files: /php-src/ext/pdo config.m4 pdo.c pdo_dbh.c pdo_sql_parser.c pdo_sqlstate.c pdo_stmt.c php_pdo.h php_pdo_driver.h php_pdo_int.h php_pdo_phpvers_compat.h Log: merge PHP 5 pdo into HEAD. This source compiles on both PHP 5 and PHP 6. If you're poking around in here, please make sure that any changes you make compile on both PHP 5 and 6. Thanks!
http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/config.m4?r1=1.17&r2=1.18&diff_format=u Index: php-src/ext/pdo/config.m4 diff -u php-src/ext/pdo/config.m4:1.17 php-src/ext/pdo/config.m4:1.18 --- php-src/ext/pdo/config.m4:1.17 Thu Aug 24 16:00:35 2006 +++ php-src/ext/pdo/config.m4 Sat Dec 9 22:18:42 2006 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.17 2006/08/24 16:00:35 tony2001 Exp $ +dnl $Id: config.m4,v 1.18 2006/12/09 22:18:42 wez Exp $ dnl config.m4 for extension pdo dnl vim:se ts=2 sw=2 et: @@ -49,7 +49,10 @@ esac fi PHP_NEW_EXTENSION(pdo, pdo.c pdo_dbh.c pdo_stmt.c pdo_sql_parser.c pdo_sqlstate.c, $ext_shared) - PHP_ADD_EXTENSION_DEP(pdo, spl, true) + ifdef([PHP_ADD_EXTENSION_DEP], + [ + PHP_ADD_EXTENSION_DEP(pdo, spl, true) + ]) ifdef([PHP_INSTALL_HEADERS], [ http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo.c?r1=1.76&r2=1.77&diff_format=u Index: php-src/ext/pdo/pdo.c diff -u php-src/ext/pdo/pdo.c:1.76 php-src/ext/pdo/pdo.c:1.77 --- php-src/ext/pdo/pdo.c:1.76 Sat Oct 14 15:07:36 2006 +++ php-src/ext/pdo/pdo.c Sat Dec 9 22:18:42 2006 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo.c,v 1.76 2006/10/14 15:07:36 bjori Exp $ */ +/* $Id: pdo.c,v 1.77 2006/12/09 22:18:42 wez Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -54,7 +54,12 @@ /* for exceptional circumstances */ zend_class_entry *pdo_exception_ce; -PDO_API zend_class_entry *php_pdo_get_exception(TSRMLS_D) +PDO_API zend_class_entry *php_pdo_get_dbh_ce(void) +{ + return pdo_dbh_ce; +} + +PDO_API zend_class_entry *php_pdo_get_exception(void) { return pdo_exception_ce; } @@ -68,7 +73,7 @@ PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC) { -#if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) +#if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1)) if (!root) { if (!spl_ce_RuntimeException) { zend_class_entry **pce; @@ -82,7 +87,7 @@ } } #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); @@ -151,7 +156,7 @@ /* }}} */ /* TODO: visit persistent handles: for each persistent statement handle, - * remove bound parameter associations in RSHUTDOWN */ + * remove bound parameter associations */ #ifdef COMPILE_DL_PDO ZEND_GET_MODULE(pdo) @@ -368,6 +373,8 @@ if (drivers) { efree(drivers); + } else { + efree(ldrivers); } php_info_print_table_end(); http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo_dbh.c?r1=1.137&r2=1.138&diff_format=u Index: php-src/ext/pdo/pdo_dbh.c diff -u php-src/ext/pdo/pdo_dbh.c:1.137 php-src/ext/pdo/pdo_dbh.c:1.138 --- php-src/ext/pdo/pdo_dbh.c:1.137 Mon Dec 4 02:40:20 2006 +++ php-src/ext/pdo/pdo_dbh.c Sat Dec 9 22:18:42 2006 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_dbh.c,v 1.137 2006/12/04 02:40:20 iliaa Exp $ */ +/* $Id: pdo_dbh.c,v 1.138 2006/12/09 22:18:42 wez Exp $ */ /* The PDO Database Handle Class */ @@ -75,7 +75,7 @@ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message); } else { zval *ex, *info; - zend_class_entry *def_ex = php_pdo_get_exception_base(1 TSRMLS_CC), *pdo_ex = php_pdo_get_exception(TSRMLS_C); + zend_class_entry *def_ex = php_pdo_get_exception_base(1 TSRMLS_CC), *pdo_ex = php_pdo_get_exception(); MAKE_STD_ZVAL(ex); object_init_ex(ex, pdo_ex); @@ -153,7 +153,7 @@ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message); } else if (EG(exception) == NULL) { zval *ex; - zend_class_entry *def_ex = php_pdo_get_exception_base(1 TSRMLS_CC), *pdo_ex = php_pdo_get_exception(TSRMLS_C); + zend_class_entry *def_ex = php_pdo_get_exception_base(1 TSRMLS_CC), *pdo_ex = php_pdo_get_exception(); MAKE_STD_ZVAL(ex); object_init_ex(ex, pdo_ex); @@ -187,7 +187,7 @@ php_stream *stream; char *dsn = NULL; - stream = php_stream_open_wrapper(uri, "rb", REPORT_ERRORS, NULL); + stream = php_stream_open_wrapper(uri, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); if (stream) { dsn = php_stream_get_line(stream, ZSTR(buf), buflen, NULL); php_stream_close(stream); @@ -228,7 +228,7 @@ snprintf(alt_dsn, sizeof(alt_dsn), "pdo.dsn.%s", data_source); if (FAILURE == cfg_get_string(alt_dsn, &ini_dsn)) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "invalid data source name"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source name"); ZVAL_NULL(object); return; } @@ -237,7 +237,7 @@ colon = strchr(data_source, ':'); if (!colon) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "invalid data source name (via INI: %s)", alt_dsn); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source name (via INI: %s)", alt_dsn); ZVAL_NULL(object); return; } @@ -245,15 +245,15 @@ if (!strncmp(data_source, "uri:", sizeof("uri:")-1)) { /* the specified URI holds connection details */ - data_source = dsn_from_uri(data_source, alt_dsn, sizeof(alt_dsn) TSRMLS_CC); + data_source = dsn_from_uri(data_source + sizeof("uri:")-1, alt_dsn, sizeof(alt_dsn) TSRMLS_CC); if (!data_source) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "invalid data source URI"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source URI"); ZVAL_NULL(object); return; } colon = strchr(data_source, ':'); if (!colon) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "invalid data source name (via URI)"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source name (via URI)"); ZVAL_NULL(object); return; } @@ -264,7 +264,7 @@ if (!driver) { /* NB: don't want to include the data_source in the error message as * it might contain a password */ - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "could not find driver"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "could not find driver"); ZVAL_NULL(object); return; } @@ -274,7 +274,7 @@ /* 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; @@ -394,11 +394,12 @@ if (options) { zval **attr_value; zstr str_key; - long long_key; + ulong 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)) { + && 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)); @@ -445,7 +446,7 @@ ZVAL_ASCII_STRINGL(&z_key, "queryString", sizeof("queryString")-1, 0); std_object_handlers.write_property(object, &z_key, query_string TSRMLS_CC); zval_ptr_dtor(&query_string); -#ifdef UG +#ifdef IS_UNICODE if (UG(unicode)) { zval_dtor(&z_key); } @@ -520,7 +521,7 @@ if (ZEND_NUM_ARGS() > 1 && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_STATEMENT_CLASS, (void**)&opt)) { if (Z_TYPE_PP(opt) != IS_ARRAY || zend_hash_index_find(Z_ARRVAL_PP(opt), 0, (void**)&item) == FAILURE - || !PDO_ZVAL_PP_IS_TEXT(item) + || PDO_ZVAL_PP_IS_TEXT(item) || zend_u_lookup_class(Z_TYPE_PP(item), Z_UNIVAL_PP(item), Z_UNILEN_PP(item), &pce TSRMLS_CC) == FAILURE ) { pdo_raise_impl_error(dbh, NULL, "HY000", @@ -605,14 +606,14 @@ PDO_CONSTRUCT_CHECK; if (dbh->in_txn) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "There is already an active transaction"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "There is already an active transaction"); RETURN_FALSE; } if (!dbh->methods->begin) { /* TODO: this should be an exception; see the auto-commit mode * comments below */ - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "This driver doesn't support transactions"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "This driver doesn't support transactions"); RETURN_FALSE; } @@ -635,7 +636,7 @@ PDO_CONSTRUCT_CHECK; if (!dbh->in_txn) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "There is no active transaction"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "There is no active transaction"); RETURN_FALSE; } @@ -658,7 +659,7 @@ PDO_CONSTRUCT_CHECK; if (!dbh->in_txn) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "There is no active transaction"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "There is no active transaction"); RETURN_FALSE; } @@ -720,6 +721,7 @@ } } } + 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); @@ -804,7 +806,7 @@ fail: if (attr == PDO_ATTR_AUTOCOMMIT) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "The auto-commit mode cannot be changed for this driver"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "The auto-commit mode cannot be changed for this driver"); } else if (!dbh->methods->set_attribute) { pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support setting attributes" TSRMLS_CC); } else { @@ -968,6 +970,10 @@ } PDO_CONSTRUCT_CHECK; + if (dbh->query_stmt) { + RETURN_STRING(dbh->query_stmt->error_code, 1); + } + RETURN_STRING(dbh->error_code, 1); } /* }}} */ @@ -984,10 +990,14 @@ PDO_CONSTRUCT_CHECK; array_init(return_value); - add_next_index_string(return_value, dbh->error_code, 1); + if (dbh->query_stmt) { + add_next_index_string(return_value, dbh->query_stmt->error_code, 1); + } else { + add_next_index_string(return_value, dbh->error_code, 1); + } if (dbh->methods->fetch_err) { - dbh->methods->fetch_err(dbh, NULL, return_value TSRMLS_CC); + dbh->methods->fetch_err(dbh, dbh->query_stmt, return_value TSRMLS_CC); } } /* }}} */ @@ -1051,6 +1061,12 @@ } } /* something broke */ + dbh->query_stmt = stmt; + dbh->query_stmt_zval = *return_value; + PDO_HANDLE_STMT_ERR(); + } else { + PDO_HANDLE_DBH_ERR(); + zval_dtor(return_value); } RETURN_FALSE; @@ -1092,7 +1108,7 @@ Prevents use of a PDO instance that has been unserialized */ static PHP_METHOD(PDO, __wakeup) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "You cannot serialize or unserialize PDO instances"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "You cannot serialize or unserialize PDO instances"); } /* }}} */ @@ -1100,7 +1116,7 @@ Prevents serialization of a PDO instance */ static PHP_METHOD(PDO, __sleep) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "You cannot serialize or unserialize PDO instances"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "You cannot serialize or unserialize PDO instances"); } /* }}} */ @@ -1160,14 +1176,14 @@ } if (!(dbh->cls_methods[kind] = pemalloc(sizeof(HashTable), dbh->is_persistent))) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "out of memory while allocating PDO methods"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "out of memory while allocating PDO methods."); } zend_hash_init_ex(dbh->cls_methods[kind], 8, NULL, NULL, dbh->is_persistent, 0); while (funcs->fname) { ifunc->type = ZEND_INTERNAL_FUNCTION; ifunc->handler = funcs->handler; - ifunc->function_name.s = funcs->fname; + pdo_zstr_sval(ifunc->function_name) = funcs->fname; ifunc->scope = dbh->ce; ifunc->prototype = NULL; if (funcs->arg_info) { @@ -1209,7 +1225,8 @@ #else zval *object, #endif - zstr method_name, int method_len TSRMLS_DC) + zstr method_name, + int method_len TSRMLS_DC) { zend_function *fbc = NULL; zstr lc_method_name; @@ -1223,7 +1240,8 @@ lc_method_name = zend_u_str_tolower_dup(ztype, method_name, method_len); - if (zend_u_hash_find(&dbh->ce->function_table, ztype, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { + if (zend_u_hash_find(&dbh->ce->function_table, ztype, lc_method_name, + method_len+1, (void**)&fbc) == FAILURE) { /* not a pre-defined method, nor a user-defined method; check * the driver specific methods */ if (!dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH]) { @@ -1243,7 +1261,7 @@ } out: - efree(lc_method_name.v); + pdo_zstr_efree(lc_method_name); return fbc; } @@ -1252,7 +1270,16 @@ return -1; } +static zend_object_value dbh_ze1_clone_obj(zval *object TSRMLS_DC) +{ + 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; +} + static zend_object_handlers pdo_dbh_object_handlers; +#if PHP_MAJOR_VERSION < 6 +static zend_object_handlers pdo_dbh_object_handlers_ze1; +#endif void pdo_dbh_init(TSRMLS_D) { @@ -1265,6 +1292,13 @@ 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; + +#if PHP_MAJOR_VERSION < 6 + 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; +#endif REGISTER_PDO_CLASS_CONST_LONG("PARAM_BOOL", (long)PDO_PARAM_BOOL); REGISTER_PDO_CLASS_CONST_LONG("PARAM_NULL", (long)PDO_PARAM_NULL); @@ -1280,6 +1314,7 @@ REGISTER_PDO_CLASS_CONST_LONG("PARAM_EVT_EXEC_POST", (long)PDO_PARAM_EVT_EXEC_POST); REGISTER_PDO_CLASS_CONST_LONG("PARAM_EVT_FETCH_PRE", (long)PDO_PARAM_EVT_FETCH_PRE); REGISTER_PDO_CLASS_CONST_LONG("PARAM_EVT_FETCH_POST", (long)PDO_PARAM_EVT_FETCH_POST); + REGISTER_PDO_CLASS_CONST_LONG("PARAM_EVT_NORMALIZE", (long)PDO_PARAM_EVT_NORMALIZE); REGISTER_PDO_CLASS_CONST_LONG("FETCH_LAZY", (long)PDO_FETCH_LAZY); REGISTER_PDO_CLASS_CONST_LONG("FETCH_ASSOC",(long)PDO_FETCH_ASSOC); @@ -1319,6 +1354,7 @@ REGISTER_PDO_CLASS_CONST_LONG("ATTR_DRIVER_NAME", (long)PDO_ATTR_DRIVER_NAME); 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); @@ -1406,12 +1442,12 @@ PDO_API void php_pdo_dbh_addref(pdo_dbh_t *dbh TSRMLS_DC) { - dbh->refcount++; + dbh->refcount++; } PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh TSRMLS_DC) { - dbh_free(dbh TSRMLS_CC); + dbh_free(dbh TSRMLS_CC); } static void pdo_dbh_free_storage(pdo_dbh_t *dbh TSRMLS_DC) @@ -1450,7 +1486,11 @@ 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); +#if PHP_MAJOR_VERSION < 6 + retval.handlers = EG(ze1_compatibility_mode) ? &pdo_dbh_object_handlers_ze1 : &pdo_dbh_object_handlers; +#else retval.handlers = &pdo_dbh_object_handlers; +#endif return retval; } http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo_sql_parser.c?r1=1.47&r2=1.48&diff_format=u Index: php-src/ext/pdo/pdo_sql_parser.c diff -u php-src/ext/pdo/pdo_sql_parser.c:1.47 php-src/ext/pdo/pdo_sql_parser.c:1.48 --- php-src/ext/pdo/pdo_sql_parser.c:1.47 Tue Dec 5 18:05:56 2006 +++ php-src/ext/pdo/pdo_sql_parser.c Sat Dec 9 22:18:42 2006 @@ -1,5 +1,5 @@ -/* Generated by re2c 0.10.6 on Tue Dec 5 13:05:42 2006 */ -#line 1 "ext/pdo/pdo_sql_parser.re" +/* Generated by re2c 0.10.6 on Sat Dec 9 17:16:39 2006 */ +#line 1 "pdo_sql_parser.re" /* +----------------------------------------------------------------------+ | PHP Version 5 | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sql_parser.c,v 1.47 2006/12/05 18:05:56 iliaa Exp $ */ +/* $Id: pdo_sql_parser.c,v 1.48 2006/12/09 22:18:42 wez Exp $ */ #include "php.h" #include "php_pdo_driver.h" @@ -46,7 +46,7 @@ char *cursor = s->cur; s->tok = cursor; - #line 53 "ext/pdo/pdo_sql_parser.re" + #line 53 "pdo_sql_parser.re" { @@ -85,7 +85,7 @@ 162, 162, 162, 162, 162, 162, 162, 162, }; -#line 89 "ext/pdo/pdo_sql_parser.c" +#line 89 "pdo_sql_parser.c" { YYCTYPE yych; @@ -107,9 +107,9 @@ if(yych == '"') goto yy26; goto yy30; yy3: -#line 61 "ext/pdo/pdo_sql_parser.re" +#line 61 "pdo_sql_parser.re" { RET(PDO_PARSER_TEXT); } -#line 113 "ext/pdo/pdo_sql_parser.c" +#line 113 "pdo_sql_parser.c" yy4: yych = *++YYCURSOR; if(yybm[0+yych] & 16) { @@ -142,9 +142,9 @@ if(yybm[0+(yych = *YYCURSOR)] & 4) { goto yy13; } -#line 60 "ext/pdo/pdo_sql_parser.re" +#line 60 "pdo_sql_parser.re" { RET(PDO_PARSER_BIND_POS); } -#line 148 "ext/pdo/pdo_sql_parser.c" +#line 148 "pdo_sql_parser.c" yy8: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -152,14 +152,14 @@ if(yybm[0+yych] & 2) { goto yy8; } -#line 62 "ext/pdo/pdo_sql_parser.re" +#line 62 "pdo_sql_parser.re" { RET(PDO_PARSER_TEXT); } -#line 158 "ext/pdo/pdo_sql_parser.c" +#line 158 "pdo_sql_parser.c" yy11: ++YYCURSOR; -#line 63 "ext/pdo/pdo_sql_parser.re" +#line 63 "pdo_sql_parser.re" { RET(PDO_PARSER_EOI); } -#line 163 "ext/pdo/pdo_sql_parser.c" +#line 163 "pdo_sql_parser.c" yy13: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -167,9 +167,9 @@ if(yybm[0+yych] & 4) { goto yy13; } -#line 58 "ext/pdo/pdo_sql_parser.re" +#line 58 "pdo_sql_parser.re" { RET(PDO_PARSER_TEXT); } -#line 173 "ext/pdo/pdo_sql_parser.c" +#line 173 "pdo_sql_parser.c" yy16: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -177,9 +177,9 @@ if(yybm[0+yych] & 8) { goto yy16; } -#line 59 "ext/pdo/pdo_sql_parser.re" +#line 59 "pdo_sql_parser.re" { RET(PDO_PARSER_BIND); } -#line 183 "ext/pdo/pdo_sql_parser.c" +#line 183 "pdo_sql_parser.c" yy19: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; @@ -193,9 +193,9 @@ goto yy13; } yy22: -#line 57 "ext/pdo/pdo_sql_parser.re" +#line 57 "pdo_sql_parser.re" { RET(PDO_PARSER_TEXT); } -#line 199 "ext/pdo/pdo_sql_parser.c" +#line 199 "pdo_sql_parser.c" yy23: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -211,9 +211,9 @@ goto yy13; } yy27: -#line 56 "ext/pdo/pdo_sql_parser.re" +#line 56 "pdo_sql_parser.re" { RET(PDO_PARSER_TEXT); } -#line 217 "ext/pdo/pdo_sql_parser.c" +#line 217 "pdo_sql_parser.c" yy28: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; @@ -233,7 +233,7 @@ goto yy27; } } -#line 64 "ext/pdo/pdo_sql_parser.re" +#line 64 "pdo_sql_parser.re" } http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo_sqlstate.c?r1=1.8&r2=1.9&diff_format=u Index: php-src/ext/pdo/pdo_sqlstate.c diff -u php-src/ext/pdo/pdo_sqlstate.c:1.8 php-src/ext/pdo/pdo_sqlstate.c:1.9 --- php-src/ext/pdo/pdo_sqlstate.c:1.8 Sun Jan 1 13:09:52 2006 +++ php-src/ext/pdo/pdo_sqlstate.c Sat Dec 9 22:18:42 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sqlstate.c,v 1.8 2006/01/01 13:09:52 sniper Exp $ */ +/* $Id: pdo_sqlstate.c,v 1.9 2006/12/09 22:18:42 wez Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo_stmt.c?r1=1.170&r2=1.171&diff_format=u Index: php-src/ext/pdo/pdo_stmt.c diff -u php-src/ext/pdo/pdo_stmt.c:1.170 php-src/ext/pdo/pdo_stmt.c:1.171 --- php-src/ext/pdo/pdo_stmt.c:1.170 Fri Dec 8 19:51:29 2006 +++ php-src/ext/pdo/pdo_stmt.c Sat Dec 9 22:18:42 2006 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_stmt.c,v 1.170 2006/12/08 19:51:29 iliaa Exp $ */ +/* $Id: pdo_stmt.c,v 1.171 2006/12/09 22:18:42 wez Exp $ */ /* The PDO Statement Handle Class */ @@ -291,7 +291,7 @@ ZVAL_ADDREF(param->driver_params); } - if (param->name && stmt->columns) { + if (!is_param && param->name && stmt->columns) { /* try to map the name to the column */ int i; @@ -302,13 +302,11 @@ } } -#if 0 /* if you prepare and then execute passing an array of params keyed by names, * then this will trigger, and we don't want that */ if (param->paramno == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Did not found column name '%s' in the defined columns; it will not be bound", param->name); } -#endif } if (param->name) { @@ -320,24 +318,61 @@ } else { param->name = estrndup(param->name, param->namelen); } - zend_hash_update(hash, param->name, param->namelen, param, sizeof(*param), (void**)&pparam); - } else { - zend_hash_index_update(hash, param->paramno, param, sizeof(*param), (void**)&pparam); } - if (is_param && !rewrite_name_to_position(stmt, pparam TSRMLS_CC)) { + if (is_param && !rewrite_name_to_position(stmt, param TSRMLS_CC)) { if (param->name) { efree(param->name); param->name = NULL; } return 0; } - - /* tell the driver we just created a parameter */ + + /* ask the driver to perform any normalization it needs on the + * parameter name. Note that it is illegal for the driver to take + * a reference to param, as it resides in transient storage only + * at this time. */ if (stmt->methods->param_hook) { - return stmt->methods->param_hook(stmt, pparam, PDO_PARAM_EVT_ALLOC TSRMLS_CC); + if (!stmt->methods->param_hook(stmt, param, PDO_PARAM_EVT_NORMALIZE + TSRMLS_CC)) { + if (param->name) { + efree(param->name); + param->name = NULL; + } + return 0; + } + } + + /* delete any other parameter registered with this number. + * If the parameter is named, it will be removed and correctly + * disposed of by the hash_update call that follows */ + if (param->paramno >= 0) { + zend_hash_index_del(hash, param->paramno); + } + + /* allocate storage for the parameter, keyed by its "canonical" name */ + if (param->name) { + zend_hash_update(hash, param->name, param->namelen, param, + sizeof(*param), (void**)&pparam); + } else { + zend_hash_index_update(hash, param->paramno, param, sizeof(*param), + (void**)&pparam); } + /* tell the driver we just created a parameter */ + if (stmt->methods->param_hook) { + if (!stmt->methods->param_hook(stmt, pparam, PDO_PARAM_EVT_ALLOC + TSRMLS_CC)) { + /* undo storage allocation; the hash will free the parameter + * name if required */ + if (pparam->name) { + zend_hash_del(hash, pparam->name, pparam->namelen); + } else { + zend_hash_index_del(hash, pparam->paramno); + } + return 0; + } + } return 1; } /* }}} */ @@ -371,13 +406,13 @@ zend_hash_internal_pointer_reset(Z_ARRVAL_P(input_params)); while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(input_params), (void*)&tmp)) { zstr tmp_str; - + memset(¶m, 0, sizeof(param)); if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(input_params), &tmp_str, &str_length, &num_index, 0, NULL)) { /* yes this is correct. we don't want to count the null byte. ask wez */ - param.name = tmp_str.s; + param.name = pdo_zstr_sval(tmp_str); param.namelen = str_length - 1; param.paramno = -1; } else { @@ -458,21 +493,24 @@ } /* }}} */ -static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno TSRMLS_DC) /* {{{ */ +static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *type_override TSRMLS_DC) /* {{{ */ { struct pdo_column_data *col; char *value = NULL; unsigned long value_len = 0; int caller_frees = 0; + int type, new_type; col = &stmt->columns[colno]; + type = PDO_PARAM_TYPE(col->param_type); + new_type = type_override ? PDO_PARAM_TYPE(*type_override) : type; value = NULL; value_len = 0; stmt->methods->get_col(stmt, colno, &value, &value_len, &caller_frees TSRMLS_CC); - switch (PDO_PARAM_TYPE(col->param_type)) { + switch (type) { case PDO_PARAM_INT: if (value && value_len == sizeof(long)) { ZVAL_LONG(dest, *(long*)value); @@ -493,8 +531,16 @@ if (value == NULL) { ZVAL_NULL(dest); } else if (value_len == 0) { - php_stream_to_zval((php_stream*)value, dest); - } else { + if (stmt->dbh->stringify || new_type == PDO_PARAM_STR) { + char *buf = NULL; + size_t len; + len = php_stream_copy_to_mem((php_stream*)value, &buf, PHP_STREAM_COPY_ALL, 0); + ZVAL_STRINGL(dest, buf, len, 0); + php_stream_close((php_stream*)value); + } else { + php_stream_to_zval((php_stream*)value, dest); + } + } else if (!stmt->dbh->stringify && new_type != PDO_PARAM_STR) { /* they gave us a string, but LOBs are represented as streams in PDO */ php_stream *stm; #ifdef TEMP_STREAM_TAKE_BUFFER @@ -513,27 +559,17 @@ } else { ZVAL_NULL(dest); } + } else { + ZVAL_STRINGL(dest, value, value_len, !caller_frees); + if (caller_frees) { + caller_frees = 0; + } } break; case PDO_PARAM_STR: if (value && !(value_len == 0 && stmt->dbh->oracle_nulls == PDO_NULL_EMPTY_STRING)) { -#ifdef IS_UNICODE - if (UG(unicode)) { - UErrorCode status = U_ZERO_ERROR; - UChar *u_str; - int u_len; - - zend_string_to_unicode_ex(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &u_str, &u_len, value, value_len, &status); - ZVAL_UNICODEL(dest, u_str, u_len, 0); - if (caller_frees) { - efree(value); - } - } else -#endif - { - ZVAL_STRINGL(dest, value, value_len, !caller_frees); - } + ZVAL_STRINGL(dest, value, value_len, !caller_frees); if (caller_frees) { caller_frees = 0; } @@ -543,6 +579,25 @@ ZVAL_NULL(dest); } + if (type != new_type) { + switch (new_type) { + case PDO_PARAM_INT: + convert_to_long_ex(&dest); + break; + case PDO_PARAM_BOOL: + convert_to_boolean_ex(&dest); + break; + case PDO_PARAM_STR: + convert_to_string_ex(&dest); + break; + case PDO_PARAM_NULL: + convert_to_null_ex(&dest); + break; + default: + ; + } + } + if (caller_frees && value) { efree(value); } @@ -599,7 +654,7 @@ zval_dtor(param->parameter); /* set new value */ - fetch_value(stmt, param->parameter, param->paramno TSRMLS_CC); + fetch_value(stmt, param->parameter, param->paramno, (int *)¶m->param_type TSRMLS_CC); /* TODO: some smart thing that avoids duplicating the value in the * general loop below. For now, if you're binding output columns, @@ -666,10 +721,9 @@ 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 = NULL; + char *fname = NULL, *cname; zend_class_entry * ce = NULL, **pce; zend_function *function_handler; - zstr lcname; - unsigned int lcname_len; if (Z_TYPE_P(callable) == IS_ARRAY) { if (Z_ARRVAL_P(callable)->nNumOfElements < 2) { @@ -679,8 +733,8 @@ object = (zval**)Z_ARRVAL_P(callable)->pListHead->pData; method = (zval**)Z_ARRVAL_P(callable)->pListHead->pListNext->pData; - if (PDO_ZVAL_PP_IS_TEXT(object)) { /* static call */ - if (zend_u_lookup_class(Z_TYPE_PP(object), Z_UNIVAL_PP(object), Z_UNILEN_PP(object), &pce TSRMLS_CC) == FAILURE) { + 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 { @@ -694,11 +748,11 @@ return 0; } - if (!PDO_ZVAL_PP_IS_TEXT(method)) { + if (Z_TYPE_PP(method) != IS_STRING) { 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 (PDO_ZVAL_P_IS_TEXT(callable)) { + } else if (Z_TYPE_P(callable) == IS_STRING) { method = &callable; } @@ -706,16 +760,39 @@ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback" TSRMLS_CC); return 0; } - - lcname = zend_u_str_case_fold(Z_TYPE_PP(method), Z_UNIVAL_PP(method), Z_UNILEN_PP(method), 1, &lcname_len); + + /* ATM we do not support array($obj, "CLASS::FUNC") or "CLASS_FUNC" */ + cname = fname; + if ((fname = strstr(fname, "::")) == NULL) { + fname = cname; + cname = NULL; + } else { + *fname = '\0'; + fname += 2; + } + if (cname) { + if (zend_lookup_class(cname, strlen(cname), &pce TSRMLS_CC) == FAILURE) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not exist" TSRMLS_CC); + return 0; + } else { + if (ce) { + /* pce must be base of ce or ce itself */ + if (ce != *pce && !instanceof_function(ce, *pce TSRMLS_CC)) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class has bogus lineage" TSRMLS_CC); + return 0; + } + } + ce = *pce; + } + } + zend_str_tolower_copy(fname, fname, strlen(fname)); fci->function_table = ce ? &ce->function_table : EG(function_table); - if (zend_u_hash_find(fci->function_table, Z_TYPE_PP(method), lcname, lcname_len+1, (void **)&function_handler) == FAILURE) { - efree(lcname.v); + if (zend_hash_find(fci->function_table, fname, strlen(fname)+1, (void **)&function_handler) == FAILURE) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function does not exist" TSRMLS_CC); return 0; } - efree(lcname.v); + efree(cname ? cname : fname); fci->size = sizeof(zend_fcall_info); fci->function_name = NULL; @@ -809,7 +886,7 @@ case PDO_FETCH_NAMED: if (!return_all) { ALLOC_HASHTABLE(return_value->value.ht); - zend_u_hash_init(return_value->value.ht, stmt->column_count, NULL, ZVAL_PTR_DTOR, 0, UG(unicode)); + 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); @@ -818,7 +895,7 @@ case PDO_FETCH_COLUMN: if (stmt->fetch.column >= 0 && stmt->fetch.column < stmt->column_count) { - fetch_value(stmt, return_value, stmt->fetch.column TSRMLS_CC); + fetch_value(stmt, return_value, stmt->fetch.column, NULL TSRMLS_CC); if (!return_all) { return 1; } else { @@ -842,10 +919,10 @@ do_fetch_opt_finish(stmt, 0 TSRMLS_CC); INIT_PZVAL(&val); - fetch_value(stmt, &val, i++ TSRMLS_CC); + fetch_value(stmt, &val, i++, NULL TSRMLS_CC); if (Z_TYPE(val) != IS_NULL) { - convert_to_text(&val); - if (zend_u_lookup_class(Z_TYPE(val), Z_UNIVAL(val), Z_UNILEN(val), &cep TSRMLS_CC) == FAILURE) { + convert_to_string(&val); + if (zend_lookup_class(Z_STRVAL(val), Z_STRLEN(val), &cep TSRMLS_CC) == FAILURE) { stmt->fetch.cls.ce = ZEND_STANDARD_CLASS_DEF_PTR; } else { stmt->fetch.cls.ce = *cep; @@ -921,7 +998,7 @@ if (return_all) { INIT_PZVAL(&grp_val); - fetch_value(stmt, &grp_val, i TSRMLS_CC); + fetch_value(stmt, &grp_val, i, NULL TSRMLS_CC); convert_to_string(&grp_val); if (how == PDO_FETCH_COLUMN) { i = stmt->column_count; /* no more data to fetch */ @@ -933,7 +1010,7 @@ for (idx = 0; i < stmt->column_count; i++, idx++) { zval *val; MAKE_STD_ZVAL(val); - fetch_value(stmt, val, i TSRMLS_CC); + fetch_value(stmt, val, i, NULL TSRMLS_CC); switch (how) { case PDO_FETCH_ASSOC: @@ -1014,12 +1091,15 @@ } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #endif -#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1 +#if (PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1) && (PHP_MAJOR_VERSION < 6) if (!ce->unserialize) { zval_ptr_dtor(&val); pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "cannot unserialize class" TSRMLS_CC); return 0; - } else if (ce->unserialize(&return_value, ce, Z_TYPE_P(val) == IS_STRING ? Z_STRVAL_P(val) : "", Z_TYPE_P(val) == IS_STRING ? Z_STRLEN_P(val) : 0, NULL TSRMLS_CC) == FAILURE) { + } else if (ce->unserialize(&return_value, ce, + Z_TYPE_P(val) == IS_STRING ? Z_STRVAL_P(val) : "", + Z_TYPE_P(val) == IS_STRING ? Z_STRLEN_P(val) : 0, + NULL TSRMLS_CC) == FAILURE) { zval_ptr_dtor(&val); pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "cannot unserialize class" TSRMLS_CC); zval_dtor(return_value); @@ -1145,6 +1225,13 @@ return 0; } return 1; + + case PDO_FETCH_LAZY: + if (fetch_all) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO::FETCH_LAZY can't be used with PDOStatement::fetchAll()" TSRMLS_CC); + return 0; + } + /* fall through */ default: if ((flags & PDO_FETCH_SERIALIZE) == PDO_FETCH_SERIALIZE) { @@ -1289,7 +1376,7 @@ RETURN_FALSE; } - fetch_value(stmt, return_value, col_n TSRMLS_CC); + fetch_value(stmt, return_value, col_n, NULL TSRMLS_CC); } /* }}} */ @@ -1338,12 +1425,12 @@ /* no break */ case 2: stmt->fetch.cls.ctor_args = ctor_args; /* we're not going to free these */ - if (!PDO_ZVAL_P_IS_TEXT(arg2)) { + if (Z_TYPE_P(arg2) != IS_STRING) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Invalid class name (should be a string)" TSRMLS_CC); error = 1; break; } else { - stmt->fetch.cls.ce = zend_u_fetch_class(Z_TYPE_P(arg2), Z_UNIVAL_P(arg2), Z_UNILEN_P(arg2), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); + stmt->fetch.cls.ce = zend_fetch_class(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); if (!stmt->fetch.cls.ce) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not find user-specified class" TSRMLS_CC); error = 1; @@ -1434,7 +1521,9 @@ if (error != 2) { RETURN_FALSE; } else { /* on no results, return an empty array */ - array_init(return_value); + if (Z_TYPE_P(return_value) != IS_ARRAY) { + array_init(return_value); + } return; } } @@ -1477,9 +1566,9 @@ bind an input parameter to the value of a PHP variable. $paramno is the 1-based position of the placeholder in the SQL statement (but can be the parameter name for drivers that support named placeholders). It should be called prior to execute(). */ static PHP_METHOD(PDOStatement, bindValue) { - pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(getThis() TSRMLS_CC); struct pdo_bound_param_data param = {0}; - + PHP_STMT_GET_OBJ; + param.paramno = -1; param.param_type = PDO_PARAM_STR; @@ -1602,6 +1691,17 @@ /* {{{ proto mixed PDOStatement::getAttribute(long attribute) Get an attribute */ + +static int generic_stmt_attr_get(pdo_stmt_t *stmt, zval *return_value, long attr) +{ + switch (attr) { + case PDO_ATTR_EMULATE_PREPARES: + RETVAL_BOOL(stmt->supports_placeholders == PDO_PLACEHOLDER_NONE); + return 1; + } + return 0; +} + static PHP_METHOD(PDOStatement, getAttribute) { long attr; @@ -1612,8 +1712,12 @@ } if (!stmt->methods->get_attribute) { - pdo_raise_impl_error(stmt->dbh, stmt, "IM001", "This driver doesn't support getting attributes" TSRMLS_CC); - RETURN_FALSE; + if (!generic_stmt_attr_get(stmt, return_value, attr)) { + pdo_raise_impl_error(stmt->dbh, stmt, "IM001", + "This driver doesn't support getting attributes" TSRMLS_CC); + RETURN_FALSE; + } + return; } PDO_STMT_CLEAR_ERR(); @@ -1623,9 +1727,13 @@ RETURN_FALSE; case 0: - /* XXX: should do something better here */ - pdo_raise_impl_error(stmt->dbh, stmt, "IM001", "driver doesn't support getting that attribute" TSRMLS_CC); - RETURN_FALSE; + if (!generic_stmt_attr_get(stmt, return_value, attr)) { + /* XXX: should do something better here */ + pdo_raise_impl_error(stmt->dbh, stmt, "IM001", + "driver doesn't support getting that attribute" TSRMLS_CC); + RETURN_FALSE; + } + return; default: return; @@ -1762,11 +1870,13 @@ stmt->fetch.cls.ce = *cep; stmt->fetch.cls.ctor_args = NULL; + #ifdef ilia_0 /* we'll only need this when we have persistent statements, if ever */ if (stmt->dbh->is_persistent) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release"); } #endif + if (argc == 3) { if (Z_TYPE_PP(args[skip+2]) != IS_NULL && Z_TYPE_PP(args[skip+2]) != IS_ARRAY) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC); @@ -1787,11 +1897,13 @@ if (Z_TYPE_PP(args[skip+1]) != IS_OBJECT) { goto fail_out; } + #ifdef ilia_0 /* we'll only need this when we have persistent statements, if ever */ if (stmt->dbh->is_persistent) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release"); } #endif + MAKE_STD_ZVAL(stmt->fetch.into); Z_TYPE_P(stmt->fetch.into) = IS_OBJECT; @@ -1844,6 +1956,7 @@ return 0; } + pdo_stmt_describe_columns(stmt TSRMLS_CC); return 1; @@ -1864,7 +1977,7 @@ PDO_HANDLE_STMT_ERR(); RETURN_FALSE; } - + RETURN_TRUE; } /* }}} */ @@ -1954,7 +2067,7 @@ Prevents use of a PDOStatement instance that has been unserialized */ static PHP_METHOD(PDOStatement, __wakeup) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "You cannot serialize or unserialize PDOStatement instances"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "You cannot serialize or unserialize PDOStatement instances"); } /* }}} */ @@ -1962,7 +2075,7 @@ Prevents serialization of a PDOStatement instance */ static PHP_METHOD(PDOStatement, __sleep) { - zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "You cannot serialize or unserialize PDOStatement instances"); + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "You cannot serialize or unserialize PDOStatement instances"); } /* }}} */ @@ -1996,9 +2109,9 @@ { pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); - convert_to_text(member); + convert_to_string(member); - if (PDO_MEMBER_IS(member, "queryString")) { + if(strcmp(Z_STRVAL_P(member), "queryString") == 0) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "property queryString is read only" TSRMLS_CC); } else { std_object_handlers.write_property(object, member, value TSRMLS_CC); @@ -2009,9 +2122,9 @@ { pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); - convert_to_text(member); + convert_to_string(member); - if (PDO_MEMBER_IS(member, "queryString")) { + if(strcmp(Z_STRVAL_P(member), "queryString") == 0) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "property queryString is read only" TSRMLS_CC); } else { std_object_handlers.unset_property(object, member TSRMLS_CC); @@ -2024,7 +2137,8 @@ #else zval *object, #endif - zstr method_name, int method_len TSRMLS_DC) + zstr method_name, + int method_len TSRMLS_DC) { zend_function *fbc = NULL; zstr lc_method_name; @@ -2059,7 +2173,7 @@ } out: - efree(lc_method_name.v); + pdo_zstr_efree(lc_method_name); return fbc; } @@ -2157,9 +2271,10 @@ int i; struct pdo_column_data *cols = stmt->columns; - for (i = stmt->column_count; i > 0;) { - if (cols[--i].name) { + for (i = 0; i < stmt->column_count; i++) { + if (cols[i].name) { efree(cols[i].name); + cols[i].name = NULL; } } efree(stmt->columns); @@ -2180,13 +2295,23 @@ efree(stmt); } -void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC) +PDO_API void php_pdo_stmt_addref(pdo_stmt_t *stmt TSRMLS_DC) +{ + stmt->refcount++; +} + +PDO_API void php_pdo_stmt_delref(pdo_stmt_t *stmt TSRMLS_DC) { if (--stmt->refcount == 0) { free_statement(stmt TSRMLS_CC); } } +void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC) +{ + php_pdo_stmt_delref(stmt TSRMLS_CC); +} + zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; @@ -2252,7 +2377,9 @@ *data = &I->fetch_ahead; } -static int pdo_stmt_iter_get_key(zend_object_iterator *iter, zstr *str_key, uint *str_key_len, +static int pdo_stmt_iter_get_key(zend_object_iterator *iter, + zstr *str_key, + uint *str_key_len, ulong *int_key TSRMLS_DC) { struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data; @@ -2344,7 +2471,7 @@ if (Z_TYPE_P(member) == IS_LONG) { if (Z_LVAL_P(member) >= 0 && Z_LVAL_P(member) < stmt->column_count) { - fetch_value(stmt, return_value, Z_LVAL_P(member) TSRMLS_CC); + fetch_value(stmt, return_value, Z_LVAL_P(member), NULL TSRMLS_CC); } } else { convert_to_string(member); @@ -2352,7 +2479,7 @@ * numbers */ for (colno = 0; colno < stmt->column_count; colno++) { if (strcmp(stmt->columns[colno].name, Z_STRVAL_P(member)) == 0) { - fetch_value(stmt, return_value, colno TSRMLS_CC); + fetch_value(stmt, return_value, colno, NULL TSRMLS_CC); break; } } @@ -2409,7 +2536,7 @@ for (i = 0; i < stmt->column_count; i++) { zval *val; MAKE_STD_ZVAL(val); - fetch_value(stmt, val, i TSRMLS_CC); + fetch_value(stmt, val, i, NULL TSRMLS_CC); add_assoc_zval(tmp, stmt->columns[i].name, val); } @@ -2428,23 +2555,30 @@ #else zval *object, #endif - zstr method_name, int method_len TSRMLS_DC) + zstr method_name, + int method_len TSRMLS_DC) { zend_function *fbc; zstr lc_method_name; +#ifdef IS_UNICODE + zend_uchar ztype = UG(unicode) ? IS_UNICODE : IS_STRING; +#endif - lc_method_name = zend_u_str_tolower_dup(UG(unicode)?IS_UNICODE:IS_STRING, method_name, method_len); + lc_method_name = zend_u_str_tolower_dup(ztype, method_name, method_len); - if (zend_u_hash_find(&pdo_row_ce->function_table, UG(unicode)?IS_UNICODE:IS_STRING, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { - efree(lc_method_name.v); + if (zend_u_hash_find(&pdo_row_ce->function_table, ztype, + lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { + pdo_zstr_efree(lc_method_name); return NULL; } - efree(lc_method_name.v); + pdo_zstr_efree(lc_method_name); return fbc; } -static int row_call_method(zstr method, INTERNAL_FUNCTION_PARAMETERS) +static int row_call_method( + zstr method, + INTERNAL_FUNCTION_PARAMETERS) { return FAILURE; } @@ -2454,7 +2588,8 @@ static zend_internal_function ctor = {0}; ctor.type = ZEND_INTERNAL_FUNCTION; - ctor.function_name.s = "__construct"; + pdo_zstr_sval(ctor.function_name) = "__construct"; + ctor.scope = pdo_row_ce; ctor.handler = ZEND_FN(dbstmt_constructor); @@ -2466,9 +2601,9 @@ return pdo_dbstmt_ce; } -static int row_get_classname(zval *object, zstr *class_name, zend_uint *class_name_len, int parent TSRMLS_DC) +static int row_get_classname(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) { - class_name->s = estrndup("PDORow", sizeof("PDORow")-1); + *class_name = estrndup("PDORow", sizeof("PDORow")-1); *class_name_len = sizeof("PDORow")-1; return 0; } http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/php_pdo.h?r1=1.13&r2=1.14&diff_format=u Index: php-src/ext/pdo/php_pdo.h diff -u php-src/ext/pdo/php_pdo.h:1.13 php-src/ext/pdo/php_pdo.h:1.14 --- php-src/ext/pdo/php_pdo.h:1.13 Wed Jun 7 21:13:33 2006 +++ php-src/ext/pdo/php_pdo.h Sat Dec 9 22:18:42 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo.h,v 1.13 2006/06/07 21:13:33 rasmus Exp $ */ +/* $Id: php_pdo.h,v 1.14 2006/12/09 22:18:42 wez Exp $ */ #ifndef PHP_PDO_H #define PHP_PDO_H @@ -61,7 +61,7 @@ #endif #define REGISTER_PDO_CLASS_CONST_LONG(const_name, value) \ - zend_declare_class_constant_long(pdo_dbh_ce, 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; \ @@ -70,7 +70,7 @@ } \ #define REGISTER_PDO_CLASS_CONST_STRING(const_name, value) \ - zend_declare_class_constant_stringl(pdo_dbh_ce, 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) { \ http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/php_pdo_driver.h?r1=1.83&r2=1.84&diff_format=u Index: php-src/ext/pdo/php_pdo_driver.h diff -u php-src/ext/pdo/php_pdo_driver.h:1.83 php-src/ext/pdo/php_pdo_driver.h:1.84 --- php-src/ext/pdo/php_pdo_driver.h:1.83 Thu Sep 28 23:27:49 2006 +++ php-src/ext/pdo/php_pdo_driver.h Sat Dec 9 22:18:42 2006 @@ -16,12 +16,13 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_driver.h,v 1.83 2006/09/28 23:27:49 tony2001 Exp $ */ +/* $Id: php_pdo_driver.h,v 1.84 2006/12/09 22:18:42 wez Exp $ */ #ifndef PHP_PDO_DRIVER_H #define PHP_PDO_DRIVER_H #include "php_pdo.h" +#include "php_pdo_phpvers_compat.h" /* forward declarations */ typedef struct _pdo_dbh_t pdo_dbh_t; @@ -44,7 +45,7 @@ # define FALSE 0 #endif -#define PDO_DRIVER_API 20060318 +#define PDO_DRIVER_API 20061209 enum pdo_param_type { PDO_PARAM_NULL, @@ -131,6 +132,7 @@ 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. * Drivers should define their own attribute constants beginning with this @@ -251,7 +253,7 @@ /* return last insert id. NULL indicates error condition, otherwise, the return value * MUST be an emalloc'd NULL terminated string. */ -typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC); +typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, int *len TSRMLS_DC); /* fetch error information. if stmt is not null, fetch information pertaining * to the statement, otherwise fetch global error information. The driver @@ -340,7 +342,8 @@ PDO_PARAM_EVT_EXEC_PRE, PDO_PARAM_EVT_EXEC_POST, PDO_PARAM_EVT_FETCH_PRE, - PDO_PARAM_EVT_FETCH_POST + PDO_PARAM_EVT_FETCH_POST, + 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,7 +492,7 @@ 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 @@ -643,7 +646,8 @@ unsigned long data_source_len, struct pdo_data_src_parser *parsed, int nparams); -PDO_API zend_class_entry *php_pdo_get_exception(TSRMLS_D); +PDO_API zend_class_entry *php_pdo_get_dbh_ce(void); +PDO_API zend_class_entry *php_pdo_get_exception(void); PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery, int *outquery_len TSRMLS_DC); @@ -654,6 +658,10 @@ PDO_API void php_pdo_dbh_addref(pdo_dbh_t *dbh TSRMLS_DC); PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh TSRMLS_DC); +PDO_API void php_pdo_stmt_addref(pdo_stmt_t *stmt TSRMLS_DC); +PDO_API void php_pdo_stmt_delref(pdo_stmt_t *stmt TSRMLS_DC); + + #endif /* PHP_PDO_DRIVER_H */ /* * Local variables: http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/php_pdo_int.h?r1=1.24&r2=1.25&diff_format=u Index: php-src/ext/pdo/php_pdo_int.h diff -u php-src/ext/pdo/php_pdo_int.h:1.24 php-src/ext/pdo/php_pdo_int.h:1.25 --- php-src/ext/pdo/php_pdo_int.h:1.24 Sun Feb 5 23:31:47 2006 +++ php-src/ext/pdo/php_pdo_int.h Sat Dec 9 22:18:43 2006 @@ -18,9 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_int.h,v 1.24 2006/02/05 23:31:47 helly Exp $ */ - -#include "php_pdo_phpvers_compat.h" +/* $Id: php_pdo_int.h,v 1.25 2006/12/09 22:18:43 wez Exp $ */ /* Stuff private to the PDO extension and not for consumption by PDO drivers * */ @@ -59,7 +57,13 @@ extern void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC); -#define PDO_DBH_CLEAR_ERR() strcpy(dbh->error_code, PDO_ERR_NONE) +#define PDO_DBH_CLEAR_ERR() do { \ + strcpy(dbh->error_code, PDO_ERR_NONE); \ + if (dbh->query_stmt) { \ + dbh->query_stmt = NULL; \ + zend_objects_store_del_ref(&dbh->query_stmt_zval TSRMLS_CC); \ + } \ +} while (0) #define PDO_STMT_CLEAR_ERR() strcpy(stmt->error_code, PDO_ERR_NONE) #define PDO_HANDLE_DBH_ERR() if (strcmp(dbh->error_code, PDO_ERR_NONE)) { pdo_handle_error(dbh, NULL TSRMLS_CC); } #define PDO_HANDLE_STMT_ERR() if (strcmp(stmt->error_code, PDO_ERR_NONE)) { pdo_handle_error(stmt->dbh, stmt TSRMLS_CC); } http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/php_pdo_phpvers_compat.h?r1=1.3&r2=1.4&diff_format=u Index: php-src/ext/pdo/php_pdo_phpvers_compat.h diff -u php-src/ext/pdo/php_pdo_phpvers_compat.h:1.3 php-src/ext/pdo/php_pdo_phpvers_compat.h:1.4 --- php-src/ext/pdo/php_pdo_phpvers_compat.h:1.3 Mon Feb 13 10:23:57 2006 +++ php-src/ext/pdo/php_pdo_phpvers_compat.h Sat Dec 9 22:18:43 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_phpvers_compat.h,v 1.3 2006/02/13 10:23:57 dmitry Exp $ */ +/* $Id: php_pdo_phpvers_compat.h,v 1.4 2006/12/09 22:18:43 wez Exp $ */ /* macros for backwards compatibility with PHP 5, so that HEAD of PDO and its * drivers may still build against PHP 5 */ @@ -25,6 +25,9 @@ # define PHP_PDO_PHPVERS_COMPAT_H # if PHP_MAJOR_VERSION < 6 +typedef char *zstr; +# define ZSTR(x) x + # define ZVAL_RT_STRINGL(a, b, c, d) ZVAL_STRINGL(a, b, c, d) # define ZVAL_ASCII_STRINGL(a, b, c, d) ZVAL_STRINGL(a, b, c, d) # define PDO_ZVAL_PP_IS_TEXT(pp) (Z_TYPE_PP(pp) == IS_STRING) @@ -42,13 +45,16 @@ # define convert_to_text(x) convert_to_string(x) # define zend_u_fetch_class(a, b, c, d) zend_fetch_class(b, c, d) # define PDO_MEMBER_IS(z, strlit) ((Z_STRLEN_P(z) == sizeof(strlit)-1) && 0 == strcmp(Z_STRVAL_P(z), strlit)) - +# define pdo_zstr_efree(x) efree(x) +# define pdo_zstr_sval(x) x # else # define PDO_ZVAL_PP_IS_TEXT(pp) ((Z_TYPE_PP(pp) == IS_STRING) || (Z_TYPE_PP(pp) == IS_UNICODE)) # define PDO_ZVAL_P_IS_TEXT(pp) ((Z_TYPE_P(pp) == IS_STRING) || (Z_TYPE_P(pp) == IS_UNICODE)) # define PDO_MEMBER_IS(z, strlit) ((Z_UNILEN_P(z) == sizeof(strlit)-1) && (ZEND_U_EQUAL(Z_TYPE_P(z), Z_UNIVAL_P(z), Z_UNILEN_P(z), strlit, sizeof(strlit)-1))) +# define pdo_zstr_efree(x) efree(x.v) +# define pdo_zstr_sval(x) x.s # endif #endif
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php