--- embedaddon/php/ext/pdo/pdo_stmt.c 2012/02/21 23:47:58 1.1.1.1 +++ embedaddon/php/ext/pdo/pdo_stmt.c 2012/05/29 12:34:40 1.1.1.2 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_stmt.c,v 1.1.1.1 2012/02/21 23:47:58 misho Exp $ */ +/* $Id: pdo_stmt.c,v 1.1.1.2 2012/05/29 12:34:40 misho Exp $ */ /* The PDO Statement Handle Class */ @@ -1333,16 +1333,15 @@ static PHP_METHOD(PDOStatement, fetchObject) long how = PDO_FETCH_CLASS; long ori = PDO_FETCH_ORI_NEXT; long off = 0; - char *class_name; + char *class_name = NULL; int class_name_len; zend_class_entry *old_ce; - zval *old_ctor_args, *ctor_args; + zval *old_ctor_args, *ctor_args = NULL; int error = 0, old_arg_count; PHP_STMT_GET_OBJ; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sz", - &class_name, &class_name_len, &ctor_args)) { + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!a", &class_name, &class_name_len, &ctor_args)) { RETURN_FALSE; } @@ -1357,17 +1356,8 @@ static PHP_METHOD(PDOStatement, fetchObject) old_arg_count = stmt->fetch.cls.fci.param_count; do_fetch_opt_finish(stmt, 0 TSRMLS_CC); - - switch(ZEND_NUM_ARGS()) { - case 0: - stmt->fetch.cls.ce = zend_standard_class_def; - break; - case 2: - if (Z_TYPE_P(ctor_args) != IS_NULL && Z_TYPE_P(ctor_args) != IS_ARRAY) { - pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC); - error = 1; - break; - } + + if (ctor_args) { if (Z_TYPE_P(ctor_args) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(ctor_args))) { ALLOC_ZVAL(stmt->fetch.cls.ctor_args); *stmt->fetch.cls.ctor_args = *ctor_args; @@ -1375,15 +1365,16 @@ static PHP_METHOD(PDOStatement, fetchObject) } else { stmt->fetch.cls.ctor_args = NULL; } - /* no break */ - case 1: + } + if (class_name && !error) { stmt->fetch.cls.ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); if (!stmt->fetch.cls.ce) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Could not find user-supplied class" TSRMLS_CC); error = 1; - break; } + } else if (!error) { + stmt->fetch.cls.ce = zend_standard_class_def; } if (!error && !do_fetch(stmt, TRUE, return_value, how, ori, off, 0 TSRMLS_CC)) { @@ -2244,7 +2235,7 @@ const zend_function_entry pdo_dbstmt_functions[] = { }; /* {{{ overloaded handlers for PDOStatement class */ -static void dbstmt_prop_write(zval *object, zval *member, zval *value TSRMLS_DC) +static void dbstmt_prop_write(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) { pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); @@ -2253,11 +2244,11 @@ static void dbstmt_prop_write(zval *object, zval *memb 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); + std_object_handlers.write_property(object, member, value, key TSRMLS_CC); } } -static void dbstmt_prop_delete(zval *object, zval *member TSRMLS_DC) +static void dbstmt_prop_delete(zval *object, zval *member, const zend_literal *key TSRMLS_DC) { pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); @@ -2266,7 +2257,7 @@ static void dbstmt_prop_delete(zval *object, zval *mem 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); + std_object_handlers.unset_property(object, member, key TSRMLS_CC); } } @@ -2276,7 +2267,7 @@ static union _zend_function *dbstmt_method_get( #else zval *object, #endif - char *method_name, int method_len TSRMLS_DC) + char *method_name, int method_len, const zend_literal *key TSRMLS_DC) { zend_function *fbc = NULL; char *lc_method_name; @@ -2325,17 +2316,14 @@ static int dbstmt_compare(zval *object1, zval *object2 static zend_object_value dbstmt_clone_obj(zval *zobject TSRMLS_DC) { zend_object_value retval; - zval *tmp; pdo_stmt_t *stmt; pdo_stmt_t *old_stmt; zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); stmt = ecalloc(1, sizeof(*stmt)); - stmt->ce = Z_OBJCE_P(zobject); + zend_object_std_init(&stmt->std, Z_OBJCE_P(zobject) TSRMLS_CC); + object_properties_init(&stmt->std, Z_OBJCE_P(zobject)); stmt->refcount = 1; - ALLOC_HASHTABLE(stmt->properties); - zend_hash_init(stmt->properties, 0, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(stmt->properties, &stmt->ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); old_stmt = (pdo_stmt_t *)zend_object_store_get_object(zobject TSRMLS_CC); @@ -2380,12 +2368,6 @@ void pdo_stmt_init(TSRMLS_D) static void free_statement(pdo_stmt_t *stmt TSRMLS_DC) { - if (stmt->properties) { - zend_hash_destroy(stmt->properties); - efree(stmt->properties); - stmt->properties = NULL; - } - if (stmt->bound_params) { zend_hash_destroy(stmt->bound_params); FREE_HASHTABLE(stmt->bound_params); @@ -2434,6 +2416,7 @@ static void free_statement(pdo_stmt_t *stmt TSRMLS_DC) if (stmt->dbh) { php_pdo_dbh_delref(stmt->dbh TSRMLS_CC); } + zend_object_std_dtor(&stmt->std TSRMLS_CC); efree(stmt); } @@ -2457,16 +2440,13 @@ void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_D zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; - zval *tmp; pdo_stmt_t *stmt; stmt = emalloc(sizeof(*stmt)); memset(stmt, 0, sizeof(*stmt)); - stmt->ce = ce; + zend_object_std_init(&stmt->std, ce TSRMLS_CC); + object_properties_init(&stmt->std, ce); stmt->refcount = 1; - ALLOC_HASHTABLE(stmt->properties); - zend_hash_init(stmt->properties, 0, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(stmt->properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); retval.handle = zend_objects_store_put(stmt, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbstmt_free_storage, (zend_objects_store_clone_t)dbstmt_clone_obj TSRMLS_CC); retval.handlers = &pdo_dbstmt_object_handlers; @@ -2601,7 +2581,7 @@ const zend_function_entry pdo_row_functions[] = { {NULL, NULL, NULL} }; -static zval *row_prop_or_dim_read(zval *object, zval *member, int type TSRMLS_DC) +static zval *row_prop_read(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) { zval *return_value; pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); @@ -2629,7 +2609,7 @@ static zval *row_prop_or_dim_read(zval *object, zval * } if (strcmp(Z_STRVAL_P(member), "queryString") == 0) { zval_ptr_dtor(&return_value); - return std_object_handlers.read_property(object, member, type TSRMLS_CC); + return std_object_handlers.read_property(object, member, type, key TSRMLS_CC); } } } @@ -2640,13 +2620,23 @@ static zval *row_prop_or_dim_read(zval *object, zval * return return_value; } -static void row_prop_or_dim_write(zval *object, zval *member, zval *value TSRMLS_DC) +static zval *row_dim_read(zval *object, zval *member, int type TSRMLS_DC) { + return row_prop_read(object, member, type, NULL TSRMLS_CC); +} + +static void row_prop_write(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +{ php_error_docref(NULL TSRMLS_CC, E_WARNING, "This PDORow is not from a writable result set"); } -static int row_prop_or_dim_exists(zval *object, zval *member, int check_empty TSRMLS_DC) +static void row_dim_write(zval *object, zval *member, zval *value TSRMLS_DC) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "This PDORow is not from a writable result set"); +} + +static int row_prop_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +{ pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); int colno = -1; @@ -2669,11 +2659,21 @@ static int row_prop_or_dim_exists(zval *object, zval * return 0; } -static void row_prop_or_dim_delete(zval *object, zval *offset TSRMLS_DC) +static int row_dim_exists(zval *object, zval *member, int check_empty TSRMLS_DC) { + return row_prop_exists(object, member, check_empty, NULL TSRMLS_CC); +} + +static void row_prop_delete(zval *object, zval *offset, const zend_literal *key TSRMLS_DC) +{ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a PDORow"); } +static void row_dim_delete(zval *object, zval *offset TSRMLS_DC) +{ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a PDORow"); +} + static HashTable *row_get_properties(zval *object TSRMLS_DC) { pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); @@ -2683,15 +2683,18 @@ static HashTable *row_get_properties(zval *object TSRM return NULL; } + if (!stmt->std.properties) { + rebuild_object_properties(&stmt->std); + } for (i = 0; i < stmt->column_count; i++) { zval *val; MAKE_STD_ZVAL(val); fetch_value(stmt, val, i, NULL TSRMLS_CC); - zend_hash_update(stmt->properties, stmt->columns[i].name, stmt->columns[i].namelen + 1, (void *)&val, sizeof(zval *), NULL); + zend_hash_update(stmt->std.properties, stmt->columns[i].name, stmt->columns[i].namelen + 1, (void *)&val, sizeof(zval *), NULL); } - return stmt->properties; + return stmt->std.properties; } static union _zend_function *row_method_get( @@ -2700,7 +2703,7 @@ static union _zend_function *row_method_get( #else zval *object, #endif - char *method_name, int method_len TSRMLS_DC) + char *method_name, int method_len, const zend_literal *key TSRMLS_DC) { zend_function *fbc; char *lc_method_name; @@ -2717,7 +2720,7 @@ static union _zend_function *row_method_get( return fbc; } -static int row_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) +static int row_call_method(const char *method, INTERNAL_FUNCTION_PARAMETERS) { return FAILURE; } @@ -2739,7 +2742,7 @@ static zend_class_entry *row_get_ce(const zval *object return pdo_row_ce; } -static int row_get_classname(const zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) +static int row_get_classname(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) { if (parent) { return FAILURE; @@ -2756,18 +2759,20 @@ static int row_compare(zval *object1, zval *object2 TS } zend_object_handlers pdo_row_object_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, - row_prop_or_dim_read, - row_prop_or_dim_write, - row_prop_or_dim_read, - row_prop_or_dim_write, + zend_objects_store_add_ref, + zend_objects_store_del_ref, NULL, + row_prop_read, + row_prop_write, + row_dim_read, + row_dim_write, NULL, NULL, - row_prop_or_dim_exists, - row_prop_or_dim_delete, - row_prop_or_dim_exists, - row_prop_or_dim_delete, + NULL, + row_prop_exists, + row_prop_delete, + row_dim_exists, + row_dim_delete, row_get_properties, row_method_get, row_call_method,