From: Michael Wallner Date: Mon, 17 Aug 2015 14:57:23 +0000 (+0200) Subject: finish port X-Git-Tag: v2.0.0RC1~7 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-pq;a=commitdiff_plain;h=cb69b6218d9d6e789527b3bd62c3cc37686547a3 finish port --- diff --git a/.travis.yml b/.travis.yml index afeaa5c..1ed1390 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,38 +12,22 @@ env: global: - PQ_DSN="postgres://postgres@localhost/test" matrix: - - PHP=5.4 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.4 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes + - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes before_script: - make -f travis/pecl/Makefile php - - make -f travis/pecl/Makefile pecl PECL=raphf + - make -f travis/pecl/Makefile pharext/raphf-phpng + - make -f travis/pecl/Makefile ext PECL=pq - psql -U postgres -c "CREATE DATABASE test" script: - - make -f travis/pecl/Makefile ext PECL=pq - make -f travis/pecl/Makefile test sudo: false diff --git a/gen_travis_yml.php b/gen_travis_yml.php index 804dad0..19240be 100755 --- a/gen_travis_yml.php +++ b/gen_travis_yml.php @@ -22,6 +22,8 @@ $env = $gen([ "enable_maintainer_zts", "enable_json", "enable_hash" => ["yes"], + "enable_phar" => ["yes"], + "enable_posix" => ["yes"] ]); foreach ($env as $e) { printf(" - %s\n", $e); @@ -31,11 +33,11 @@ foreach ($env as $e) { before_script: - make -f travis/pecl/Makefile php - - make -f travis/pecl/Makefile pecl PECL=raphf + - make -f travis/pecl/Makefile pharext/raphf-phpng + - make -f travis/pecl/Makefile ext PECL=pq - psql -U postgres -c "CREATE DATABASE test" script: - - make -f travis/pecl/Makefile ext PECL=pq - make -f travis/pecl/Makefile test sudo: false diff --git a/src/php_pq_callback.c b/src/php_pq_callback.c index 6b0213f..695d592 100644 --- a/src/php_pq_callback.c +++ b/src/php_pq_callback.c @@ -30,7 +30,10 @@ void php_pq_callback_dtor(php_pq_callback_t *cb) zend_fcall_info_args_clear(&cb->fci, 1); zval_ptr_dtor(&cb->fci.function_name); if (cb->fci.object) { - zend_objects_store_del(cb->fci.object); + zval tmp; + + ZVAL_OBJ(&tmp, cb->fci.object); + zval_ptr_dtor(&tmp); } cb->fci.size = 0; } @@ -62,6 +65,22 @@ zval *php_pq_callback_to_zval(php_pq_callback_t *cb, zval *tmp) return &cb->fci.function_name; } +zval *php_pq_callback_to_zval_no_addref(php_pq_callback_t *cb, zval *tmp) +{ + if (cb->fci.object) { + zval zo; + + array_init_size(tmp, 2); + ZVAL_OBJ(&zo, cb->fci.object); + add_next_index_zval(tmp, &zo); + add_next_index_zval(tmp, &cb->fci.function_name); + + return tmp; + } + + return &cb->fci.function_name; +} + zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb) { /* TODO: fixed in php7? diff --git a/src/php_pq_callback.h b/src/php_pq_callback.h index 23521a8..da71143 100644 --- a/src/php_pq_callback.h +++ b/src/php_pq_callback.h @@ -24,6 +24,7 @@ typedef struct php_pq_callback { extern void php_pq_callback_dtor(php_pq_callback_t *cb); extern void php_pq_callback_addref(php_pq_callback_t *cb); extern zval *php_pq_callback_to_zval(php_pq_callback_t *cb, zval *tmp); +extern zval *php_pq_callback_to_zval_no_addref(php_pq_callback_t *cb, zval *tmp); extern zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb); extern void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new); diff --git a/src/php_pq_misc.c b/src/php_pq_misc.c index 484d760..10defed 100644 --- a/src/php_pq_misc.c +++ b/src/php_pq_misc.c @@ -54,18 +54,23 @@ const char *php_pq_strmode(long mode) int php_pq_compare_index(const void *lptr, const void *rptr) { - const Bucket *l = *(const Bucket **) lptr; - const Bucket *r = *(const Bucket **) rptr; + zend_ulong l = ((const Bucket *) lptr)->h; + zend_ulong r = ((const Bucket *) rptr)->h; - if (l->h < r->h) { + if (l < r) { return -1; } - if (l->h > r->h) { + if (l > r) { return 1; } return 0; } +void php_pq_hash_ptr_dtor(zval *p) +{ + efree(Z_PTR_P(p)); +} + zend_class_entry *php_pqdt_class_entry; ZEND_BEGIN_ARG_INFO_EX(ai_pqdt_to_string, 0, 0, 0) @@ -89,7 +94,7 @@ static PHP_METHOD(pqdt, createFromFormat) { zend_error_handling zeh; char *fmt_str, *dt_str; - int fmt_len, dt_len; + size_t fmt_len, dt_len; zval *ztz = NULL; ZEND_RESULT_CODE rv; @@ -338,7 +343,7 @@ static ZEND_RESULT_CODE parse_array(ArrayParserState *a) } list = ecalloc(1, sizeof(*list)); - ZVAL_NEW_ARR(&list->arr); + array_init(&list->arr); if (a->list) { add_next_index_zval(&a->list->arr, &list->arr); @@ -354,8 +359,12 @@ static ZEND_RESULT_CODE parse_array(ArrayParserState *a) return FAILURE; } + /* step one level back up */ if (a->list->parent) { - a->list = a->list->parent; + HashTableList *l = a->list->parent; + + efree(a->list); + a->list = l; } return SUCCESS; @@ -386,9 +395,13 @@ HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_ php_error_docref(NULL, E_NOTICE, "Trailing input: '%s'", a.ptr); } - do { + while (a.list) { + HashTableList *l = a.list->parent; + ht = Z_ARRVAL(a.list->arr); - } while ((a.list = a.list->parent)); + efree(a.list); + a.list = l; + } return ht; } diff --git a/src/php_pq_misc.h b/src/php_pq_misc.h index 937d7ad..b25f871 100644 --- a/src/php_pq_misc.h +++ b/src/php_pq_misc.h @@ -41,6 +41,9 @@ extern const char *php_pq_strmode(long mode); /* compare array index */ extern int php_pq_compare_index(const void *lptr, const void *rptr); +/* free zval ptr values (as hash dtor) */ +extern void php_pq_hash_ptr_dtor(zval *p); + #define PHP_PQerrorMessage(c) php_pq_rtrim(PQerrorMessage((c))) #define PHP_PQresultErrorMessage(r) php_pq_rtrim(PQresultErrorMessage((r))) diff --git a/src/php_pq_object.c b/src/php_pq_object.c index bfab410..c7e04d6 100644 --- a/src/php_pq_object.c +++ b/src/php_pq_object.c @@ -18,6 +18,29 @@ #include "php_pq_object.h" +void *php_pq_object_create(zend_class_entry *ce, void *intern, size_t obj_size, zend_object_handlers *oh, HashTable *ph) +{ + php_pq_object_t *o = ecalloc(1, obj_size + zend_object_properties_size(ce)); + + zend_object_std_init(&o->zo, ce); + object_properties_init(&o->zo, ce); + o->zo.handlers = oh; + o->intern = intern; + o->prophandler = ph; + + zend_hash_init(&o->gc, 0, NULL, NULL, 0); + + return o; +} + +void php_pq_object_dtor(zend_object *o) +{ + php_pq_object_t *obj = PHP_PQ_OBJ(NULL, o); + + zend_hash_destroy(&obj->gc); + zend_object_std_dtor(o); +} + void php_pq_object_to_zval(void *o, zval *zv) { php_pq_object_t *obj = o; @@ -39,29 +62,44 @@ void php_pq_object_addref(void *o) ++GC_REFCOUNT(&obj->zo); } -void php_pq_object_delref(void *o TSRMLS_DC) +void php_pq_object_delref(void *o) { php_pq_object_t *obj = o; - zend_objects_store_del(&obj->zo); + zval tmp; + + /* this should gc immediately */ + ZVAL_OBJ(&tmp, &obj->zo); + zval_ptr_dtor(&tmp); } struct apply_pi_to_ht_arg { HashTable *ht; zval *object; php_pq_object_t *pq_obj; - unsigned addref:1; + unsigned gc:1; }; static int apply_pi_to_ht(zval *p, void *a) { zend_property_info *pi = Z_PTR_P(p); struct apply_pi_to_ht_arg *arg = a; - zval tmp_prop, *property = zend_read_property(arg->pq_obj->zo.ce, arg->object, pi->name->val, pi->name->len, 0, &tmp_prop); - if (arg->addref) { - Z_TRY_ADDREF_P(property); + if (arg->gc) { + php_pq_object_prophandler_t *handler; + + if ((handler = zend_hash_find_ptr(arg->pq_obj->prophandler, pi->name)) && handler->gc) { + zval member, return_value; + + ZVAL_STR(&member, pi->name); + ZVAL_ARR(&return_value, arg->ht); + handler->gc(arg->object, arg->pq_obj, &return_value); + } + } else { + zval tmp_prop, *property = NULL; + + property = zend_read_property(arg->pq_obj->zo.ce, arg->object, pi->name->val, pi->name->len, 0, &tmp_prop); + zend_hash_update(arg->ht, pi->name, property); } - zend_hash_update(arg->ht, pi->name, property); return ZEND_HASH_APPLY_KEEP; } @@ -76,7 +114,7 @@ HashTable *php_pq_object_debug_info(zval *object, int *temp) arg.object = object; arg.pq_obj = PHP_PQ_OBJ(object, NULL); - arg.addref = 1; + arg.gc = 0; zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg); @@ -90,10 +128,29 @@ HashTable *php_pq_object_properties(zval *object) arg.ht = zend_get_std_object_handlers()->get_properties(object); arg.object = object; arg.pq_obj = PHP_PQ_OBJ(object, NULL); - arg.addref = 1; + arg.gc = 0; + + zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg); + + return arg.ht; +} + +HashTable *php_pq_object_get_gc(zval *object, zval **table, int *n) +{ + struct apply_pi_to_ht_arg arg = {NULL}; + + arg.object = object; + arg.pq_obj = PHP_PQ_OBJ(object, NULL); + arg.ht = &arg.pq_obj->gc; + arg.gc = 1; + zend_hash_clean(arg.ht); + zend_hash_copy(arg.ht, zend_std_get_properties(object), NULL); zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg); + *table = NULL; + *n = 0; + return arg.ht; } @@ -111,17 +168,32 @@ zval *php_pq_object_read_prop(zval *object, zval *member, int type, void **cache php_pq_object_prophandler_t *handler; zval *return_value = NULL; + return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp); + if (!obj->intern) { - php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name); - return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp); - } else if (!(handler= zend_hash_find_ptr(obj->prophandler, Z_STR_P(member))) || !handler->read) { - return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp); + php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name->val); + } else if (!(handler = zend_hash_find_ptr(obj->prophandler, Z_STR_P(member))) || !handler->read) { + /* default handler */ } else if (type != BP_VAR_R) { php_error(E_WARNING, "Cannot access %s properties by reference or array key/index", ancestor(obj->zo.ce)->name->val); - return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp); } else { + handler->read(object, obj, tmp); + zend_get_std_object_handlers()->write_property(object, member, tmp, cache_slot); return_value = tmp; - handler->read(object, obj, return_value); + + /* + zval dtor; + + ZVAL_COPY_VALUE(&dtor, return_value); + + ZVAL_ZVAL(return_value, tmp, 0, 0); + zval_ptr_dtor(&dtor); + + */ + + if (cache_slot) { + *cache_slot = NULL; + } } return return_value; @@ -144,3 +216,7 @@ void php_pq_object_write_prop(zval *object, zval *member, zval *value, void **ca } } +void php_pq_object_prophandler_dtor(zval *zv) { + pefree(Z_PTR_P(zv), 1); +} + diff --git a/src/php_pq_object.h b/src/php_pq_object.h index 47ccbbf..2c7417a 100644 --- a/src/php_pq_object.h +++ b/src/php_pq_object.h @@ -13,10 +13,14 @@ #ifndef PHP_PQ_OBJECT_H #define PHP_PQ_OBJECT_H -typedef struct php_pq_object { - void *intern; - HashTable *prophandler; +#define PHP_PQ_OBJ_DECL(_intern_type) \ + _intern_type intern; \ + HashTable *prophandler; \ + HashTable gc; \ zend_object zo; + +typedef struct php_pq_object { + PHP_PQ_OBJ_DECL(void *) } php_pq_object_t; static inline void *PHP_PQ_OBJ(zval *zv, zend_object *zo) { @@ -31,17 +35,22 @@ typedef void (*php_pq_object_prophandler_func_t)(zval *object, void *o, zval *re typedef struct php_pq_object_prophandler { php_pq_object_prophandler_func_t read; php_pq_object_prophandler_func_t write; + php_pq_object_prophandler_func_t gc; } php_pq_object_prophandler_t; +extern void *php_pq_object_create(zend_class_entry *ce, void *intern, size_t obj_size, zend_object_handlers *oh, HashTable *ph); +extern void php_pq_object_dtor(zend_object *obj); extern void php_pq_object_to_zval(void *o, zval *zv); extern void php_pq_object_to_zval_no_addref(void *o, zval *zv); extern void php_pq_object_addref(void *o); extern void php_pq_object_delref(void *o); extern HashTable *php_pq_object_debug_info(zval *object, int *temp); extern HashTable *php_pq_object_properties(zval *object); +HashTable *php_pq_object_get_gc(zval *object, zval **table, int *n); extern zend_class_entry *ancestor(zend_class_entry *ce); extern zval *php_pq_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp); extern void php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot); +extern void php_pq_object_prophandler_dtor(zval *zv); #endif diff --git a/src/php_pq_params.c b/src/php_pq_params.c index ead7fac..0f7ba50 100644 --- a/src/php_pq_params.c +++ b/src/php_pq_params.c @@ -130,10 +130,16 @@ static int apply_to_param_from_array(zval *zparam, void *arg_ptr) ZVAL_LONG(&ztype, arg->type); zend_call_method_with_2_params(arg->zconv, NULL, NULL, "converttostring", &rv, zparam, &ztype); str = zval_get_string(&rv); + zval_ptr_dtor(&rv); goto append_string; } else { + again: switch (Z_TYPE_P(zparam)) { + case IS_REFERENCE: + ZVAL_DEREF(zparam); + goto again; + case IS_NULL: smart_str_appends(arg->buffer, "NULL"); break; @@ -209,7 +215,6 @@ static zend_string *array_param_to_string(php_pq_params_t *p, zval *zarr, Oid ty smart_str_appendc(arg.buffer, '{'); SEPARATE_ZVAL(zarr); zend_hash_apply_with_argument(Z_ARRVAL_P(zarr), apply_to_param_from_array, &arg); - zval_ptr_dtor(zarr); smart_str_appendc(arg.buffer, '}'); break; } @@ -238,7 +243,12 @@ static void php_pq_params_set_param(php_pq_params_t *p, unsigned index, zval *zp char tmp_str[64]; size_t tmp_len = 0; + again: switch (Z_TYPE_P(zpp)) { + case IS_REFERENCE: + ZVAL_DEREF(zpp); + goto again; + case IS_NULL: p->param.strings[index] = NULL; return; @@ -257,7 +267,7 @@ static void php_pq_params_set_param(php_pq_params_t *p, unsigned index, zval *zp break; case IS_ARRAY: - str = array_param_to_string(p, &tmp, type); + str = array_param_to_string(p, zpp, type); break; case IS_OBJECT: @@ -265,7 +275,6 @@ static void php_pq_params_set_param(php_pq_params_t *p, unsigned index, zval *zp break; } /* no break */ - default: str = zval_get_string(zpp); break; diff --git a/src/php_pqcancel.c b/src/php_pqcancel.c index 7105363..4d5d339 100644 --- a/src/php_pqcancel.c +++ b/src/php_pqcancel.c @@ -32,7 +32,7 @@ static void php_pqcancel_object_free(zend_object *o) { php_pqcancel_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { PQfreeCancel(obj->intern->cancel); @@ -40,26 +40,13 @@ static void php_pqcancel_object_free(zend_object *o) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor(o); - efree(obj); + php_pq_object_dtor(o); } php_pqcancel_object_t *php_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern) { - php_pqcancel_object_t *o; - - o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce)); - zend_object_std_init(&o->zo, ce); - object_properties_init(&o->zo, ce); - o->prophandler = &php_pqcancel_object_prophandlers; - - if (intern) { - o->intern = intern; - } - - o->zo.handlers = &php_pqcancel_object_handlers; - - return o; + return php_pq_object_create(ce, intern, sizeof(php_pqcancel_object_t), + &php_pqcancel_object_handlers, &php_pqcancel_object_prophandlers); } static zend_object *php_pqcancel_create_object(zend_class_entry *class_type TSRMLS_DC) @@ -74,6 +61,15 @@ static void php_pqcancel_object_read_connection(zval *object, void *o, zval *ret php_pq_object_to_zval(obj->intern->conn, return_value); } +static void php_pqcancel_object_gc_connection(zval *object, void *o, zval *return_value) +{ + php_pqcancel_object_t *obj = o; + zval zconn; + + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); +} + ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0) ZEND_END_ARG_INFO(); @@ -161,14 +157,15 @@ PHP_MINIT_FUNCTION(pqcancel) php_pqcancel_object_handlers.write_property = php_pq_object_write_prop; php_pqcancel_object_handlers.clone_obj = NULL; php_pqcancel_object_handlers.get_property_ptr_ptr = NULL; - php_pqcancel_object_handlers.get_gc = NULL; + php_pqcancel_object_handlers.get_gc = php_pq_object_get_gc; php_pqcancel_object_handlers.get_properties = php_pq_object_properties; php_pqcancel_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqcancel_object_prophandlers, 1, NULL, NULL, 1); + zend_hash_init(&php_pqcancel_object_prophandlers, 1, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqcancel_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcancel_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqcancel_object_read_connection; + ph.gc = php_pqcancel_object_gc_connection; zend_hash_str_add_mem(&php_pqcancel_object_prophandlers, ZEND_STRL("connection"), (void *) &ph, sizeof(ph)); return SUCCESS; diff --git a/src/php_pqcancel.h b/src/php_pqcancel.h index 8bbd7a9..fb0a69e 100644 --- a/src/php_pqcancel.h +++ b/src/php_pqcancel.h @@ -22,9 +22,7 @@ typedef struct php_pqcancel { } php_pqcancel_t; typedef struct php_pqcancel_object { - php_pqcancel_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqcancel_t *) } php_pqcancel_object_t; extern zend_class_entry *php_pqcancel_class_entry; diff --git a/src/php_pqconn.c b/src/php_pqconn.c index 3e4aed8..a7fca0e 100644 --- a/src/php_pqconn.c +++ b/src/php_pqconn.c @@ -35,8 +35,14 @@ zend_class_entry *php_pqconn_class_entry; static zend_object_handlers php_pqconn_object_handlers; static HashTable php_pqconn_object_prophandlers; +static void php_pq_callback_hash_dtor(zval *p) +{ + php_pq_callback_dtor(Z_PTR_P(p)); + efree(Z_PTR_P(p)); +} + /* -static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC) +static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id) { zval **evhs; @@ -46,21 +52,25 @@ static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *ty } */ -static ulong php_pqconn_add_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, php_pq_callback_t *cb TSRMLS_DC) +static zend_long php_pqconn_add_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, php_pq_callback_t *cb) { - ulong h; - HashTable *evhs; + zend_long h; + zval *zevhs; - if (!(evhs = zend_hash_str_find_ptr(&obj->intern->eventhandlers, type_str, type_len))) { - HashTable evh; + if (!(zevhs = zend_hash_str_find(&obj->intern->eventhandlers, type_str, type_len))) { + HashTable *evhs; + zval tmp; - zend_hash_init(&evh, 1, NULL, (dtor_func_t) php_pq_callback_dtor, 0); - evhs = zend_hash_str_add_mem(&obj->intern->eventhandlers, type_str, type_len, (void *) &evh, sizeof(evh)); + ALLOC_HASHTABLE(evhs); + zend_hash_init(evhs, 1, NULL, php_pq_callback_hash_dtor, 0); + + ZVAL_ARR(&tmp, evhs); + zevhs = zend_hash_str_add(&obj->intern->eventhandlers, type_str, type_len, &tmp); } php_pq_callback_addref(cb); - h = zend_hash_next_free_element(evhs); - zend_hash_index_update_ptr(evhs, h, (void *) cb); + h = zend_hash_next_free_element(Z_ARRVAL_P(zevhs)); + zend_hash_index_update_mem(Z_ARRVAL_P(zevhs), h, (void *) cb, sizeof(*cb)); return h; } @@ -69,7 +79,7 @@ static void php_pqconn_object_free(zend_object *o) { php_pqconn_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE conn(#%d) %p\n", obj->zv.handle, obj); + fprintf(stderr, "FREE conn(#%d) %p\n", obj->zo.handle, obj); #endif if (obj->intern) { php_pq_callback_dtor(&obj->intern->onevent); @@ -81,27 +91,14 @@ static void php_pqconn_object_free(zend_object *o) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor(o); - efree(obj); + php_pq_object_dtor(o); } php_pqconn_object_t *php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern) { - php_pqconn_object_t *o; - - o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce)); - zend_object_std_init(&o->zo, ce); - object_properties_init(&o->zo, ce); - o->prophandler = &php_pqconn_object_prophandlers; - - if (intern) { - o->intern = intern; - } - - o->zo.handlers = &php_pqconn_object_handlers; - - return o; + return php_pq_object_create(ce, intern, sizeof(php_pqconn_object_t), + &php_pqconn_object_handlers, &php_pqconn_object_prophandlers); } static zend_object *php_pqconn_create_object(zend_class_entry *class_type) @@ -147,6 +144,7 @@ static int apply_notify_listener(zval *p, void *arg) zend_fcall_info_argn(&listener->fci, 3, &zchannel, &zmessage, &zpid); zend_fcall_info_call(&listener->fci, &listener->fcc, NULL, NULL); + zend_fcall_info_args_clear(&listener->fci, 0); zval_ptr_dtor(&zchannel); zval_ptr_dtor(&zmessage); @@ -310,7 +308,7 @@ static void php_pqconn_object_read_options(zval *object, void *o, zval *return_v } } -static int apply_read_event_handler_ex(zval *p, void *arg) +static int apply_read_callback_ex(zval *p, void *arg) { HashTable *rv = arg; zval zcb; @@ -320,9 +318,9 @@ static int apply_read_event_handler_ex(zval *p, void *arg) return ZEND_HASH_APPLY_KEEP; } -static int apply_read_event_handlers(zval *p, int argc, va_list argv, zend_hash_key *key) +static int apply_read_callbacks(zval *p, int argc, va_list argv, zend_hash_key *key) { - HashTable *evhs = Z_PTR_P(p), *rv = va_arg(argv, HashTable *); + HashTable *evhs = Z_ARRVAL_P(p), *rv = va_arg(argv, HashTable *); zval entry, *entry_ptr; array_init_size(&entry, zend_hash_num_elements(evhs)); @@ -333,7 +331,7 @@ static int apply_read_event_handlers(zval *p, int argc, va_list argv, zend_hash_ entry_ptr = zend_hash_index_update(rv, key->h, &entry); } - zend_hash_apply_with_argument(evhs, apply_read_event_handler_ex, Z_ARRVAL_P(entry_ptr)); + zend_hash_apply_with_argument(evhs, apply_read_callback_ex, Z_ARRVAL_P(entry_ptr)); return ZEND_HASH_APPLY_KEEP; } @@ -342,7 +340,75 @@ static void php_pqconn_object_read_event_handlers(zval *object, void *o, zval *r php_pqconn_object_t *obj = o; array_init(return_value); - zend_hash_apply_with_arguments(&obj->intern->eventhandlers, apply_read_event_handlers, 1, Z_ARRVAL_P(return_value) TSRMLS_CC); + zend_hash_apply_with_arguments(&obj->intern->eventhandlers, apply_read_callbacks, 1, Z_ARRVAL_P(return_value)); +} + +static void php_pqconn_object_gc_event_handlers(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + zval *evhs; + + ZEND_HASH_FOREACH_VAL(&obj->intern->eventhandlers, evhs) + { + zval *evh; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(evhs), evh) + { + zval zcb; + + add_next_index_zval(return_value, php_pq_callback_to_zval_no_addref(Z_PTR_P(evh), &zcb)); + } + ZEND_HASH_FOREACH_END(); + } + ZEND_HASH_FOREACH_END(); +} + +static void php_pqconn_object_read_listeners(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + + array_init(return_value); + zend_hash_apply_with_arguments(&obj->intern->listeners, apply_read_callbacks, 1, Z_ARRVAL_P(return_value)); +} + +static void php_pqconn_object_gc_listeners(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + zval *listeners; + + ZEND_HASH_FOREACH_VAL(&obj->intern->listeners, listeners) + { + zval *listener; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(listeners), listener) + { + zval zcb; + + add_next_index_zval(return_value, php_pq_callback_to_zval_no_addref(Z_PTR_P(listener), &zcb)); + } + ZEND_HASH_FOREACH_END(); + } + ZEND_HASH_FOREACH_END(); +} + +static void php_pqconn_object_read_converters(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + + array_init(return_value); + zend_hash_copy(Z_ARRVAL_P(return_value), &obj->intern->converters, zval_add_ref); +} + +static void php_pqconn_object_gc_converters(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + zval *converter; + + ZEND_HASH_FOREACH_VAL(&obj->intern->converters, converter) + { + add_next_index_zval(return_value, converter); + } + ZEND_HASH_FOREACH_END(); } static void php_pqconn_object_read_def_fetch_type(zval *object, void *o, zval *return_value) @@ -435,6 +501,7 @@ static ZEND_RESULT_CODE php_pqconn_update_socket(zval *zobj, php_pqconn_object_t } zend_get_std_object_handlers()->write_property(zobj, &zmember, &zsocket, NULL); zval_ptr_dtor(&zsocket); + zval_ptr_dtor(&zmember); return retval; } @@ -602,7 +669,7 @@ static PHP_METHOD(pqconn, __construct) { zend_hash_init(&obj->intern->listeners, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&obj->intern->converters, 0, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_init(&obj->intern->eventhandlers, 0, NULL, (dtor_func_t) zend_hash_destroy, 0); + zend_hash_init(&obj->intern->eventhandlers, 0, NULL, ZVAL_PTR_DTOR, 0); if (flags & PHP_PQCONN_PERSISTENT) { zend_string *dsn = zend_string_init(dsn_str, dsn_len, 0); @@ -760,15 +827,21 @@ static PHP_METHOD(pqconn, unlistenAsync) { static void php_pqconn_add_listener(php_pqconn_object_t *obj, const char *channel_str, size_t channel_len, php_pq_callback_t *listener) { - zval *existing, tmp; + zval *existing; php_pq_callback_addref(listener); if ((existing = zend_hash_str_find(&obj->intern->listeners, channel_str, channel_len))) { zend_hash_next_index_insert_mem(Z_ARRVAL_P(existing), (void *) listener, sizeof(*listener)); } else { - ZVAL_NEW_ARR(&tmp); - zend_hash_next_index_insert_mem(Z_ARRVAL(tmp), (void *) listener, sizeof(*listener)); + zval tmp; + HashTable *ht; + + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, 0, NULL, php_pq_callback_hash_dtor, 0); + zend_hash_next_index_insert_mem(ht, (void *) listener, sizeof(*listener)); + + ZVAL_ARR(&tmp, ht); zend_hash_str_add(&obj->intern->listeners, channel_str, channel_len, &tmp); } } @@ -1880,11 +1953,11 @@ PHP_MINIT_FUNCTION(pqconn) php_pqconn_object_handlers.write_property = php_pq_object_write_prop; php_pqconn_object_handlers.clone_obj = NULL; php_pqconn_object_handlers.get_property_ptr_ptr = NULL; - php_pqconn_object_handlers.get_gc = NULL; + php_pqconn_object_handlers.get_gc = php_pq_object_get_gc; php_pqconn_object_handlers.get_properties = php_pq_object_properties; php_pqconn_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqconn_object_prophandlers, 20, NULL, NULL, 1); + zend_hash_init(&php_pqconn_object_prophandlers, 22, NULL, php_pq_object_prophandler_dtor, 1); zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_status; @@ -1950,7 +2023,21 @@ PHP_MINIT_FUNCTION(pqconn) zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_event_handlers; + ph.gc = php_pqconn_object_gc_event_handlers; zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "eventHandlers", sizeof("eventHandlers")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; + + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("listeners"), ZEND_ACC_PUBLIC); + ph.read = php_pqconn_object_read_listeners; + ph.gc = php_pqconn_object_gc_listeners; + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "listeners", sizeof("listeners")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; + + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("converters"), ZEND_ACC_PUBLIC); + ph.read = php_pqconn_object_read_converters; + ph.gc = php_pqconn_object_gc_converters; + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "converters", sizeof("converters")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_def_fetch_type; diff --git a/src/php_pqconn.h b/src/php_pqconn.h index 0514e0a..65c1278 100644 --- a/src/php_pqconn.h +++ b/src/php_pqconn.h @@ -18,6 +18,7 @@ #define PHP_PQCONN_PERSISTENT 0x02 #include +#include "php_pq_object.h" #include "php_pq_callback.h" #include "php_pq_params.h" @@ -38,9 +39,7 @@ typedef struct php_pqconn { } php_pqconn_t; typedef struct php_pqconn_object { - php_pqconn_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqconn_t *) } php_pqconn_object_t; typedef struct php_pqconn_resource_factory_data { diff --git a/src/php_pqconn_event.c b/src/php_pqconn_event.c index 07fb173..2b94dee 100644 --- a/src/php_pqconn_event.c +++ b/src/php_pqconn_event.c @@ -33,6 +33,7 @@ static int apply_event(zval *p, void *a) ZVAL_NULL(&rv); zend_fcall_info_args(&cb->fci, args); zend_fcall_info_call(&cb->fci, &cb->fcc, &rv, NULL); + zend_fcall_info_args_clear(&cb->fci, 0); zval_ptr_dtor(&rv); return ZEND_HASH_APPLY_KEEP; @@ -43,15 +44,15 @@ static void php_pqconn_event_connreset(PGEventConnReset *event) php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event); if (data) { - HashTable *evhs; + zval *zevhs; - if ((evhs = zend_hash_str_find_ptr(&data->obj->intern->eventhandlers, ZEND_STRS("reset")))) { + if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("reset")))) { zval args, connection; array_init(&args); php_pq_object_to_zval(data->obj, &connection); add_next_index_zval(&args, &connection); - zend_hash_apply_with_argument(evhs, apply_event, &args); + zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args); zval_ptr_dtor(&args); } } @@ -62,13 +63,11 @@ static void php_pqconn_event_resultcreate(PGEventResultCreate *event) php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event); if (data) { - php_pqres_object_t *obj; - HashTable *evhs; - - php_pqres_init_instance_data(event->result, data->obj, &obj); + php_pqres_object_t *obj = php_pqres_init_instance_data(event->result, data->obj); + zval *zevhs; /* event listener */ - if ((evhs = zend_hash_str_find_ptr(&data->obj->intern->eventhandlers, ZEND_STRL("result")))) { + if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("result")))) { zval args, connection, res; array_init(&args); @@ -76,7 +75,7 @@ static void php_pqconn_event_resultcreate(PGEventResultCreate *event) add_next_index_zval(&args, &connection); php_pq_object_to_zval(obj, &res); add_next_index_zval(&args, &res); - zend_hash_apply_with_argument(evhs, apply_event, &args); + zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args); zval_ptr_dtor(&args); } @@ -99,6 +98,8 @@ static void php_pqconn_event_resultdestroy(PGEventResultDestroy *event) if (obj) { obj->intern->res = NULL; + assert(GC_REFCOUNT(&obj->zo)); + php_pq_object_delref(obj); } } @@ -126,6 +127,7 @@ php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj) php_pqconn_event_data_t *data = emalloc(sizeof(*data)); data->obj = obj; + data->res = NULL; return data; } @@ -135,16 +137,16 @@ void php_pqconn_notice_recv(void *p, const PGresult *res) php_pqconn_event_data_t *data = p; if (data) { - HashTable *evhs; + zval *zevhs; - if ((evhs = zend_hash_str_find_ptr(&data->obj->intern->eventhandlers, ZEND_STRL("notice")))) { + if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("notice")))) { zval args, connection; array_init(&args); php_pq_object_to_zval(data->obj, &connection); add_next_index_zval(&args, &connection); add_next_index_string(&args, PHP_PQresultErrorMessage(res)); - zend_hash_apply_with_argument(evhs, apply_event, &args); + zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args); zval_ptr_dtor(&args); } } diff --git a/src/php_pqconn_event.h b/src/php_pqconn_event.h index f8aa4ab..b7513a6 100644 --- a/src/php_pqconn_event.h +++ b/src/php_pqconn_event.h @@ -17,9 +17,11 @@ #include #include "php_pqconn.h" +#include "php_pqres.h" typedef struct php_pqconn_event_data { php_pqconn_object_t *obj; + php_pqres_object_t *res; } php_pqconn_event_data_t; extern php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj); diff --git a/src/php_pqcopy.c b/src/php_pqcopy.c index 2c4b626..2413268 100644 --- a/src/php_pqcopy.c +++ b/src/php_pqcopy.c @@ -35,7 +35,7 @@ static void php_pqcopy_object_free(zend_object *o) { php_pqcopy_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { efree(obj->intern->expression); @@ -44,26 +44,13 @@ static void php_pqcopy_object_free(zend_object *o) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor(o); - efree(obj); + php_pq_object_dtor(o); } php_pqcopy_object_t *php_pqcopy_create_object_ex(zend_class_entry *ce, php_pqcopy_t *intern) { - php_pqcopy_object_t *o; - - o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce)); - zend_object_std_init(&o->zo, ce); - object_properties_init(&o->zo, ce); - o->prophandler = &php_pqcopy_object_prophandlers; - - if (intern) { - o->intern = intern; - } - - o->zo.handlers = &php_pqcopy_object_handlers; - - return o; + return php_pq_object_create(ce, intern, sizeof(php_pqcopy_object_t), + &php_pqcopy_object_handlers, &php_pqcopy_object_prophandlers); } static zend_object *php_pqcopy_create_object(zend_class_entry *class_type) @@ -78,6 +65,15 @@ static void php_pqcopy_object_read_connection(zval *object, void *o, zval *retur php_pq_object_to_zval(obj->intern->conn, return_value); } +static void php_pqcopy_object_gc_connection(zval *object, void *o, zval *return_value) +{ + php_pqcopy_object_t *obj = o; + zval zconn; + + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); +} + static void php_pqcopy_object_read_direction(zval *object, void *o, zval *return_value) { php_pqcopy_object_t *obj = o; @@ -326,15 +322,17 @@ PHP_MINIT_FUNCTION(pqcopy) php_pqcopy_object_handlers.write_property = php_pq_object_write_prop; php_pqcopy_object_handlers.clone_obj = NULL; php_pqcopy_object_handlers.get_property_ptr_ptr = NULL; - php_pqcopy_object_handlers.get_gc = NULL; + php_pqcopy_object_handlers.get_gc = php_pq_object_get_gc; php_pqcopy_object_handlers.get_properties = php_pq_object_properties; php_pqcopy_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqcopy_object_prophandlers, 4, NULL, NULL, 1); + zend_hash_init(&php_pqcopy_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqcopy_object_read_connection; + ph.gc = php_pqcopy_object_gc_connection; zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("expression"), ZEND_ACC_PUBLIC); ph.read = php_pqcopy_object_read_expression; diff --git a/src/php_pqcopy.h b/src/php_pqcopy.h index dbac9a3..decc817 100644 --- a/src/php_pqcopy.h +++ b/src/php_pqcopy.h @@ -35,9 +35,7 @@ typedef struct php_pqcopy { } php_pqcopy_t; typedef struct php_pqcopy_object { - php_pqcopy_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqcopy_t *) } php_pqcopy_object_t; extern zend_class_entry *php_pqcopy_class_entry; diff --git a/src/php_pqcur.c b/src/php_pqcur.c index be6443d..7a96994 100644 --- a/src/php_pqcur.c +++ b/src/php_pqcur.c @@ -152,7 +152,7 @@ static void php_pqcur_object_free(zend_object *o) { php_pqcur_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE cur(#%d) %p (conn: %p)\n", obj->zv.handle, obj, obj->intern->conn); + fprintf(stderr, "FREE cur(#%d) %p (conn: %p)\n", obj->zo.handle, obj, obj->intern->conn); #endif if (obj->intern) { cur_close(obj, 0, 1); @@ -162,26 +162,13 @@ static void php_pqcur_object_free(zend_object *o) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor(o); - efree(obj); + php_pq_object_dtor(o); } php_pqcur_object_t *php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern) { - php_pqcur_object_t *o; - - o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce)); - zend_object_std_init(&o->zo, ce); - object_properties_init(&o->zo, ce); - o->prophandler = &php_pqcur_object_prophandlers; - - if (intern) { - o->intern = intern; - } - - o->zo.handlers = &php_pqcur_object_handlers; - - return o; + return php_pq_object_create(ce, intern, sizeof(php_pqcur_object_t), + &php_pqcur_object_handlers, &php_pqcur_object_prophandlers); } static zend_object *php_pqcur_create_object(zend_class_entry *class_type) @@ -203,6 +190,15 @@ static void php_pqcur_object_read_connection(zval *object, void *o, zval *return php_pq_object_to_zval(obj->intern->conn, return_value); } +static void php_pqcur_object_gc_connection(zval *object, void *o, zval *return_value) +{ + php_pqcur_object_t *obj = o; + zval zconn; + + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); +} + static void php_pqcur_object_read_query(zval *object, void *o, zval *return_value) { php_pqcur_object_t *obj = o; @@ -438,11 +434,11 @@ PHP_MINIT_FUNCTION(pqcur) php_pqcur_object_handlers.write_property = php_pq_object_write_prop; php_pqcur_object_handlers.clone_obj = NULL; php_pqcur_object_handlers.get_property_ptr_ptr = NULL; - php_pqcur_object_handlers.get_gc = NULL; + php_pqcur_object_handlers.get_gc = php_pq_object_get_gc; php_pqcur_object_handlers.get_properties = php_pq_object_properties; php_pqcur_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqcur_object_prophandlers, 4, NULL, NULL, 1); + zend_hash_init(&php_pqcur_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("BINARY"), PHP_PQ_DECLARE_BINARY); zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("INSENSITIVE"), PHP_PQ_DECLARE_INSENSITIVE); @@ -456,7 +452,9 @@ PHP_MINIT_FUNCTION(pqcur) zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqcur_object_read_connection; + ph.gc = php_pqcur_object_gc_connection; zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC); ph.read = php_pqcur_object_read_query; diff --git a/src/php_pqcur.h b/src/php_pqcur.h index ea4353a..ab74e8d 100644 --- a/src/php_pqcur.h +++ b/src/php_pqcur.h @@ -32,9 +32,7 @@ typedef struct php_pqcur { } php_pqcur_t; typedef struct php_pqcur_object { - php_pqcur_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqcur_t *) } php_pqcur_object_t; extern zend_class_entry *php_pqcur_class_entry; diff --git a/src/php_pqexc.c b/src/php_pqexc.c index 63aa9d3..1f96662 100644 --- a/src/php_pqexc.c +++ b/src/php_pqexc.c @@ -53,10 +53,10 @@ zend_class_entry *exce(php_pqexc_type_t type) } } -zval *throw_exce(php_pqexc_type_t type, const char *fmt, ...) +zend_object *throw_exce(php_pqexc_type_t type, const char *fmt, ...) { char *msg; - zval *zexc; + zend_object *zexc; va_list argv; va_start(argv, fmt); @@ -75,6 +75,7 @@ PHP_MINIT_FUNCTION(pqexc) INIT_NS_CLASS_ENTRY(ce, "pq", "Exception", php_pqexc_methods); php_pqexc_interface_class_entry = zend_register_internal_interface(&ce); + zend_class_implements(php_pqexc_interface_class_entry, 1, zend_ce_throwable); zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT); zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("RUNTIME"), EX_RUNTIME); @@ -104,7 +105,7 @@ PHP_MINIT_FUNCTION(pqexc) memset(&ce, 0, sizeof(ce)); INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "DomainException", php_pqexc_methods); php_pqexc_domain_class_entry = zend_register_internal_class_ex(&ce, spl_ce_DomainException); - zend_class_implements(php_pqexc_domain_class_entry TSRMLS_CC, 1, php_pqexc_interface_class_entry); + zend_class_implements(php_pqexc_domain_class_entry, 1, php_pqexc_interface_class_entry); zend_declare_property_null(php_pqexc_domain_class_entry, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC); return SUCCESS; diff --git a/src/php_pqexc.h b/src/php_pqexc.h index de1be0f..2666dcf 100644 --- a/src/php_pqexc.h +++ b/src/php_pqexc.h @@ -27,7 +27,7 @@ typedef enum php_pqexc_type { } php_pqexc_type_t; extern zend_class_entry *exce(php_pqexc_type_t type); -extern zval *throw_exce(php_pqexc_type_t type, const char *fmt, ...); +extern zend_object *throw_exce(php_pqexc_type_t type, const char *fmt, ...); extern PHP_MINIT_FUNCTION(pqexc); diff --git a/src/php_pqlob.c b/src/php_pqlob.c index 5149472..01c0ec2 100644 --- a/src/php_pqlob.c +++ b/src/php_pqlob.c @@ -32,7 +32,7 @@ static void php_pqlob_object_free(zend_object *o) { php_pqlob_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->txn->zv.handle, obj->intern->txn); + fprintf(stderr, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->txn->zo.handle, obj->intern->txn); #endif if (obj->intern) { if (obj->intern->lofd) { @@ -47,26 +47,13 @@ static void php_pqlob_object_free(zend_object *o) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor(o); - efree(obj); + php_pq_object_dtor(o); } php_pqlob_object_t *php_pqlob_create_object_ex(zend_class_entry *ce, php_pqlob_t *intern) { - php_pqlob_object_t *o; - - o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce)); - zend_object_std_init(&o->zo, ce); - object_properties_init(&o->zo, ce); - o->prophandler = &php_pqlob_object_prophandlers; - - if (intern) { - o->intern = intern; - } - - o->zo.handlers = &php_pqlob_object_handlers; - - return o; + return php_pq_object_create(ce, intern, sizeof(php_pqlob_object_t), + &php_pqlob_object_handlers, &php_pqlob_object_prophandlers); } static zend_object *php_pqlob_create_object(zend_class_entry *class_type) @@ -81,6 +68,15 @@ static void php_pqlob_object_read_transaction(zval *object, void *o, zval *retur php_pq_object_to_zval(obj->intern->txn, return_value); } +static void php_pqlob_object_gc_transaction(zval *object, void *o, zval *return_value) +{ + php_pqlob_object_t *obj = o; + zval ztxn; + + php_pq_object_to_zval_no_addref(obj->intern->txn, &ztxn); + add_next_index_zval(return_value, &ztxn); +} + static void php_pqlob_object_read_oid(zval *object, void *o, zval *return_value) { php_pqlob_object_t *obj = o; @@ -101,7 +97,7 @@ static void php_pqlob_object_read_stream(zval *object, void *o, zval *return_val php_stream_to_zval(obj->intern->stream, &zstream); } - RETVAL_ZVAL(&zstream, 1, 1); + RETVAL_ZVAL(&zstream, 1, 0); } static size_t php_pqlob_stream_write(php_stream *stream, const char *buffer, size_t length TSRMLS_DC) @@ -209,6 +205,7 @@ static void php_pqlob_object_update_stream(zval *zpqlob, php_pqlob_object_t *obj php_stream_to_zval(obj->intern->stream, zstream); zend_get_std_object_handlers()->write_property(zpqlob, &zmember, zstream, NULL); + zval_ptr_dtor(&zmember); } ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct, 0, 0, 1) @@ -457,23 +454,25 @@ PHP_MINIT_FUNCTION(pqlob) php_pqlob_object_handlers.write_property = php_pq_object_write_prop; php_pqlob_object_handlers.clone_obj = NULL; php_pqlob_object_handlers.get_property_ptr_ptr = NULL; - php_pqlob_object_handlers.get_gc = NULL; + php_pqlob_object_handlers.get_gc = php_pq_object_get_gc; php_pqlob_object_handlers.get_properties = php_pq_object_properties; php_pqlob_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqlob_object_prophandlers, 3, NULL, NULL, 1); + zend_hash_init(&php_pqlob_object_prophandlers, 3, NULL, php_pq_object_prophandler_dtor, 1); zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC); ph.read = php_pqlob_object_read_transaction; + ph.gc = php_pqlob_object_gc_transaction; zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "transaction", sizeof("transaction")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; zend_declare_property_long(php_pqlob_class_entry, ZEND_STRL("oid"), InvalidOid, ZEND_ACC_PUBLIC); ph.read = php_pqlob_object_read_oid; - zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "oid", sizeof("oid"), (void *) &ph, sizeof(ph)); + zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "oid", sizeof("oid")-1, (void *) &ph, sizeof(ph)); zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("stream"), ZEND_ACC_PUBLIC); ph.read = php_pqlob_object_read_stream; - zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "stream", sizeof("stream"), (void *) &ph, sizeof(ph)); + zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "stream", sizeof("stream")-1, (void *) &ph, sizeof(ph)); zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("INVALID_OID"), InvalidOid); zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("R"), INV_READ); diff --git a/src/php_pqlob.h b/src/php_pqlob.h index c56049d..fc7fa13 100644 --- a/src/php_pqlob.h +++ b/src/php_pqlob.h @@ -24,9 +24,7 @@ typedef struct php_pqlob { } php_pqlob_t; typedef struct php_pqlob_object { - php_pqlob_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqlob_t *) } php_pqlob_object_t; extern zend_class_entry *php_pqlob_class_entry; diff --git a/src/php_pqres.c b/src/php_pqres.c index b83ee97..f2ddf98 100644 --- a/src/php_pqres.c +++ b/src/php_pqres.c @@ -43,31 +43,48 @@ static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval iter = ecalloc(1, sizeof(*iter)); iter->zi.funcs = &php_pqres_iterator_funcs; - iter->zi.data = PHP_PQ_OBJ(object, NULL); - php_pq_object_addref(iter->zi.data); + ZVAL_COPY(&iter->zi.data, object); + + zend_iterator_init(&iter->zi); zfetch_type = zend_read_property(ce, object, ZEND_STRL("fetchType"), 0, &tmp); iter->fetch_type = zval_get_long(zfetch_type); - +#if DBG_GC + fprintf(stderr, "INIT iter(#%d) %p res(#%d) %p\n", iter->zi.std.handle, iter, Z_OBJ_HANDLE_P(object), PHP_PQ_OBJ(object, NULL)); +#endif return (zend_object_iterator *) iter; } +static void php_pqres_internal_iterator_init(zval *zobj) +{ + php_pqres_object_t *obj = PHP_PQ_OBJ(zobj, NULL); + + obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(zobj), zobj, 0); + /* prevent cyclic dep */ + Z_DELREF_P(zobj); + obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter); + +} + static void php_pqres_iterator_dtor(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_object_t *obj = i->data; - if (!Z_IS_UNDEF(&iter->current_val)) { +#if DBG_GC + fprintf(stderr, "FREE iter(#%d) %p\n", iter->zi.std.handle, iter); +#endif + if (!Z_ISUNDEF(iter->current_val)) { zval_ptr_dtor(&iter->current_val); + ZVAL_UNDEF(&iter->current_val); } - php_pq_object_delref(obj); - efree(iter); + zval_ptr_dtor(&i->data); + zend_iterator_dtor(i); } static ZEND_RESULT_CODE php_pqres_iterator_valid(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_object_t *obj = i->data; + php_pqres_object_t *obj = PHP_PQ_OBJ(&i->data, NULL); switch (PQresultStatus(obj->intern->res)) { case PGRES_TUPLES_OK: @@ -101,7 +118,8 @@ zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv) ZVAL_LONG(&ztype, typ); zend_call_method_with_2_params(zconv, NULL, NULL, "convertfromstring", &rv, zv, &ztype); - ZVAL_ZVAL(&rv, zv, 1, 1); + zval_ptr_dtor(zv); + ZVAL_ZVAL(zv, &rv, 0, 0); return zv; } @@ -203,7 +221,7 @@ zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv) break; } - zend_sring_release(str); + zend_string_release(str); return zv; noconversion: @@ -264,19 +282,19 @@ static inline void php_pqres_add_col_to_zval(php_pqres_t *r, unsigned row, unsig zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval *data) { - int c, cols; + int c, cols = PQnfields(res); php_pqres_object_t *res_obj = PQresultInstanceData(res, php_pqconn_event); if (Z_TYPE_P(data) != IS_OBJECT && Z_TYPE_P(data) != IS_ARRAY) { if (PHP_PQRES_FETCH_OBJECT == fetch_type) { object_init(data); } else { - array_init(data); + array_init_size(data, cols); } } if (PQntuples(res) > row) { - for (c = 0, cols = PQnfields(res); c < cols; ++c) { + for (c = 0; c < cols; ++c) { php_pqres_add_col_to_zval(res_obj->intern, row, c, fetch_type, data); } } @@ -284,58 +302,47 @@ zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch return data; } -static void php_pqres_iterator_current(zend_object_iterator *i, zval ***data_ptr TSRMLS_DC) +static zval *php_pqres_iterator_current(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_object_t *obj = i->data; + php_pqres_object_t *obj = PHP_PQ_OBJ(&i->data, NULL); - if (!iter->current_val) { - iter->current_val = php_pqres_row_to_zval(obj->intern->res, iter->index, iter->fetch_type, NULL TSRMLS_CC); + if (Z_ISUNDEF(iter->current_val)) { + php_pqres_row_to_zval(obj->intern->res, iter->index, iter->fetch_type, &iter->current_val); } - *data_ptr = &iter->current_val; + return &iter->current_val; } -#if PHP_VERSION_ID >= 50500 -static void php_pqres_iterator_key(zend_object_iterator *i, zval *key TSRMLS_DC) +static void php_pqres_iterator_key(zend_object_iterator *i, zval *key) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; ZVAL_LONG(key, iter->index); } -#else -static int php_pqres_iterator_key(zend_object_iterator *i, char **key_str, uint *key_len, ulong *key_num TSRMLS_DC) -{ - php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - - *key_num = (ulong) iter->index; - - return HASH_KEY_IS_LONG; -} -#endif -static void php_pqres_iterator_invalidate(zend_object_iterator *i TSRMLS_DC) +static void php_pqres_iterator_invalidate(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - if (iter->current_val) { + if (!Z_ISUNDEF(iter->current_val)) { zval_ptr_dtor(&iter->current_val); - iter->current_val = NULL; + ZVAL_UNDEF(&iter->current_val); } } -static void php_pqres_iterator_next(zend_object_iterator *i TSRMLS_DC) +static void php_pqres_iterator_next(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_iterator_invalidate(i TSRMLS_CC); + php_pqres_iterator_invalidate(i); ++iter->index; } -static void php_pqres_iterator_rewind(zend_object_iterator *i TSRMLS_DC) +static void php_pqres_iterator_rewind(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_iterator_invalidate(i TSRMLS_CC); + php_pqres_iterator_invalidate(i); iter->index = 0; } @@ -355,9 +362,9 @@ static zend_object_iterator_funcs php_pqres_iterator_funcs = { php_pqres_iterator_invalidate }; -static int php_pqres_count_elements(zval *object, long *count TSRMLS_DC) +static ZEND_RESULT_CODE php_pqres_count_elements(zval *object, long *count) { - php_pqres_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(object, NULL); if (!obj->intern) { return FAILURE; @@ -369,39 +376,37 @@ static int php_pqres_count_elements(zval *object, long *count TSRMLS_DC) ZEND_RESULT_CODE php_pqres_success(PGresult *res TSRMLS_DC) { - zval *zexc; + zval zexc; switch (PQresultStatus(res)) { case PGRES_BAD_RESPONSE: case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: - zexc = throw_exce(EX_SQL TSRMLS_CC, "%s", PHP_PQresultErrorMessage(res)); - zend_update_property_string(Z_OBJCE_P(zexc), zexc, ZEND_STRL("sqlstate"), PQresultErrorField(res, PG_DIAG_SQLSTATE) TSRMLS_CC); + ZVAL_OBJ(&zexc, throw_exce(EX_SQL, "%s", PHP_PQresultErrorMessage(res))); + zend_update_property_string(Z_OBJCE(zexc), &zexc, ZEND_STRL("sqlstate"), PQresultErrorField(res, PG_DIAG_SQLSTATE)); return FAILURE; default: return SUCCESS; } } -void php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *conn_obj, php_pqres_object_t **ptr TSRMLS_DC) +php_pqres_object_t *php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *conn_obj) { php_pqres_object_t *obj; php_pqres_t *r = ecalloc(1, sizeof(*r)); r->res = res; zend_hash_init(&r->bound, 0, 0, ZVAL_PTR_DTOR, 0); - zend_hash_init(&r->converters, 0, 0, ZVAL_PTR_DTOR, 0); - zend_hash_copy(&r->converters, &conn_obj->intern->converters, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + zend_hash_init(&r->converters, zend_hash_num_elements(&conn_obj->intern->converters), 0, ZVAL_PTR_DTOR, 0); + zend_hash_copy(&r->converters, &conn_obj->intern->converters, (copy_ctor_func_t) zval_add_ref); r->auto_convert = conn_obj->intern->default_auto_convert; r->default_fetch_type = conn_obj->intern->default_fetch_type; - php_pqres_create_object_ex(php_pqres_class_entry, r, &obj TSRMLS_CC); + obj = php_pqres_create_object_ex(php_pqres_class_entry, r); PQresultSetInstanceData(res, php_pqconn_event, obj); - if (ptr) { - *ptr = obj; - } + return obj; } php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res) @@ -409,12 +414,10 @@ php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res) return res->iter ? res->iter->fetch_type : res->default_fetch_type; } -static void php_pqres_object_free(void *o TSRMLS_DC) +static void php_pqres_object_free(zend_object *o) { - php_pqres_object_t *obj = o; -#if DBG_GC - fprintf(stderr, "FREE res(#%d) %p\n", obj->zv.handle, obj); -#endif + php_pqres_object_t *obj = PHP_PQ_OBJ(NULL, o); + if (obj->intern) { if (obj->intern->res) { PQresultSetInstanceData(obj->intern->res, php_pqconn_event, NULL); @@ -423,7 +426,8 @@ static void php_pqres_object_free(void *o TSRMLS_DC) } if (obj->intern->iter) { - php_pqres_iterator_dtor((zend_object_iterator *) obj->intern->iter TSRMLS_CC); + ZVAL_NULL(&obj->intern->iter->zi.data); + php_pqres_iterator_dtor((zend_object_iterator *) obj->intern->iter); obj->intern->iter = NULL; } @@ -433,170 +437,117 @@ static void php_pqres_object_free(void *o TSRMLS_DC) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern, php_pqres_object_t **ptr TSRMLS_DC) +php_pqres_object_t *php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern) { - php_pqres_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqres_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqres_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqres_object_handlers; - - return o->zv; + return php_pq_object_create(ce, intern, sizeof(php_pqres_object_t), + &php_pqres_object_handlers, &php_pqres_object_prophandlers); } -static zend_object_value php_pqres_create_object(zend_class_entry *class_type TSRMLS_DC) +static zend_object *php_pqres_create_object(zend_class_entry *class_type) { - return php_pqres_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + return &php_pqres_create_object_ex(class_type, NULL)->zo; } -static void php_pqres_object_read_status(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_status(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(PQresultStatus(obj->intern->res)); } -static void php_pqres_object_read_status_message(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_status_message(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; - RETVAL_STRING(PQresStatus(PQresultStatus(obj->intern->res))+sizeof("PGRES"), 1); + RETVAL_STRING(PQresStatus(PQresultStatus(obj->intern->res))+sizeof("PGRES")); } -static void php_pqres_object_read_error_message(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_error_message(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; char *error = PHP_PQresultErrorMessage(obj->intern->res); if (error) { - RETVAL_STRING(error, 1); + RETVAL_STRING(error); } else { RETVAL_NULL(); } } -static void php_pqres_object_read_num_rows(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_num_rows(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(PQntuples(obj->intern->res)); } -static void php_pqres_object_read_num_cols(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_num_cols(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(PQnfields(obj->intern->res)); } -static void php_pqres_object_read_affected_rows(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_affected_rows(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(atoi(PQcmdTuples(obj->intern->res))); } -static void php_pqres_object_read_fetch_type(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_fetch_type(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(php_pqres_fetch_type(obj->intern)); } -static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value) { php_pqres_object_t *obj = o; - zval *zfetch_type = value; - - if (Z_TYPE_P(value) != IS_LONG) { - if (Z_REFCOUNT_P(value) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zfetch_type, 1, 0); - convert_to_long(tmp); - zfetch_type = tmp; - } else { - convert_to_long_ex(&zfetch_type); - } - } if (!obj->intern->iter) { - obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(object), object, 0 TSRMLS_CC); - obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter TSRMLS_CC); - } - obj->intern->iter->fetch_type = Z_LVAL_P(zfetch_type); - - if (zfetch_type != value) { - zval_ptr_dtor(&zfetch_type); + php_pqres_internal_iterator_init(object); } + obj->intern->iter->fetch_type = zval_get_long(value); } -static void php_pqres_object_read_auto_conv(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_auto_conv(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(obj->intern->auto_convert); } -static void php_pqres_object_write_auto_conv(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqres_object_write_auto_conv(zval *object, void *o, zval *value) { php_pqres_object_t *obj = o; - zval *zauto_conv = value; - - if (Z_TYPE_P(value) != IS_LONG) { - if (Z_REFCOUNT_P(value) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zauto_conv, 1, 0); - convert_to_long(tmp); - zauto_conv = tmp; - } else { - convert_to_long_ex(&zauto_conv); - } - } - obj->intern->auto_convert = Z_LVAL_P(zauto_conv); - - if (zauto_conv != value) { - zval_ptr_dtor(&zauto_conv); - } + obj->intern->auto_convert = zval_get_long(value); } -static ZEND_RESULT_CODE php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC) +static ZEND_RESULT_CODE php_pqres_iteration(zval *zobj, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval *row TSRMLS_DC) { ZEND_RESULT_CODE rv; php_pqres_fetch_t orig_fetch; if (!obj) { - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_PQ_OBJ(zobj, NULL); } if (obj->intern->iter) { - obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter TSRMLS_CC); + obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter); } else { - obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC); - obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter TSRMLS_CC); + php_pqres_internal_iterator_init(zobj); } orig_fetch = obj->intern->iter->fetch_type; obj->intern->iter->fetch_type = fetch_type; - if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter TSRMLS_CC))) { - obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter, row TSRMLS_CC); + if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter))) { + zval *tmp = obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter); + ZVAL_COPY_VALUE(row, tmp); } obj->intern->iter->fetch_type = orig_fetch; @@ -608,7 +559,7 @@ typedef struct php_pqres_col { int num; } php_pqres_col_t; -static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col TSRMLS_DC) +static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col) { long index = -1; char *name = NULL; @@ -646,11 +597,11 @@ static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres } if (!col->name) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column at index %ld", index); + php_error_docref(NULL, E_WARNING, "Failed to find column at index %ld", index); return FAILURE; } if (col->num == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column with name '%s'", name); + php_error_docref(NULL, E_WARNING, "Failed to find column with name '%s'", name); return FAILURE; } return SUCCESS; @@ -665,28 +616,28 @@ static PHP_METHOD(pqres, bind) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z", &zcol, &zref); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z/z", &zcol, &zref); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { php_pqres_col_t col; - if (SUCCESS != column_nn(obj, zcol, &col TSRMLS_CC)) { + if (SUCCESS != column_nn(obj, zcol, &col)) { RETVAL_FALSE; } else { - Z_ADDREF_P(zref); + Z_TRY_ADDREF_P(zref); - if (SUCCESS != zend_hash_index_update(&obj->intern->bound, col.num, (void *) &zref, sizeof(zval *), NULL)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to bind column %s@%d", col.name, col.num); + if (!zend_hash_index_update(&obj->intern->bound, col.num, zref)) { + php_error_docref(NULL, E_WARNING, "Failed to bind column %s@%d", col.name, col.num); RETVAL_FALSE; } else { - zend_hash_sort(&obj->intern->bound, zend_qsort, php_pq_compare_index, 0 TSRMLS_CC); + zend_hash_sort(&obj->intern->bound, php_pq_compare_index, 0); RETVAL_TRUE; } } @@ -694,23 +645,20 @@ static PHP_METHOD(pqres, bind) { } } -static int apply_bound(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +static int apply_bound(zval *zbound, int argc, va_list argv, zend_hash_key *key) { - zval **zvalue, **zbound = p; - zval **zrow = va_arg(argv, zval **); + zval *zvalue; + zval *zrow = va_arg(argv, zval *); ZEND_RESULT_CODE *rv = va_arg(argv, ZEND_RESULT_CODE *); - if (SUCCESS != zend_hash_index_find(Z_ARRVAL_PP(zrow), key->h, (void *) &zvalue)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column ad index %lu", key->h); + if (!(zvalue = zend_hash_index_find(Z_ARRVAL_P(zrow), key->h))) { + php_error_docref(NULL, E_WARNING, "Failed to find column ad index %lu", key->h); *rv = FAILURE; return ZEND_HASH_APPLY_STOP; } else { - zval_dtor(*zbound); - ZVAL_COPY_VALUE(*zbound, *zvalue); - ZVAL_NULL(*zvalue); - zval_ptr_dtor(zvalue); - Z_ADDREF_P(*zbound); - *zvalue = *zbound; + ZVAL_DEREF(zbound); + zval_dtor(zbound); + ZVAL_COPY(zbound, zvalue); *rv = SUCCESS; return ZEND_HASH_APPLY_KEEP; } @@ -722,29 +670,27 @@ static PHP_METHOD(pqres, fetchBound) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { - zval **row = NULL; + zval row; - if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row TSRMLS_CC) && row) { - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - zend_hash_apply_with_arguments(&obj->intern->bound TSRMLS_CC, apply_bound, 2, row, &rv); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row)) { + zend_hash_apply_with_arguments(&obj->intern->bound, apply_bound, 2, &row, &rv); - if (SUCCESS != rv) { - zval_ptr_dtor(row); - } else { - RETVAL_ZVAL(*row, 1, 0); + if (SUCCESS == rv) { + RETVAL_ZVAL(&row, 1, 0); } } + zend_restore_error_handling(&zeh); } } } @@ -754,49 +700,47 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqres, fetchRow) { zend_error_handling zeh; - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - long fetch_type = -1; + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + zend_long fetch_type = -1; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { - zval **row = NULL; + zval row; if (fetch_type == -1) { fetch_type = php_pqres_fetch_type(obj->intern); } - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - php_pqres_iteration(getThis(), obj, fetch_type, &row TSRMLS_CC); - zend_restore_error_handling(&zeh TSRMLS_CC); - - if (row) { - RETVAL_ZVAL(*row, 1, 0); + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == php_pqres_iteration(getThis(), obj, fetch_type, &row)) { + RETVAL_ZVAL(&row, 1, 0); } + zend_restore_error_handling(&zeh); } } } -static zval **column_at(zval *row, int col TSRMLS_DC) +static zval *column_at(zval *row, int col) { - zval **data = NULL; + zval *data = NULL; HashTable *ht = HASH_OF(row); int count = zend_hash_num_elements(ht); if (col >= count) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Column index %d exceeds column count %d", col, count); + php_error_docref(NULL, E_WARNING, "Column index %d exceeds column count %d", col, count); } else { zend_hash_internal_pointer_reset(ht); while (col-- > 0) { zend_hash_move_forward(ht); } - zend_hash_get_current_data(ht, (void *) &data); + data = zend_hash_get_current_data(ht); } return data; } @@ -810,38 +754,38 @@ static PHP_METHOD(pqres, fetchCol) { zval *zcol = NULL, *zref; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z/!", &zref, &zcol); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z|z/!", &zref, &zcol); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { - zval **row = NULL; + zval row; - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - php_pqres_iteration(getThis(), obj, php_pqres_fetch_type(obj->intern), &row TSRMLS_CC); - if (row) { + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == php_pqres_iteration(getThis(), obj, php_pqres_fetch_type(obj->intern), &row)) { php_pqres_col_t col; - if (SUCCESS != column_nn(obj, zcol, &col TSRMLS_CC)) { + if (SUCCESS != column_nn(obj, zcol, &col)) { RETVAL_FALSE; } else { - zval **zres = column_at(*row, col.num TSRMLS_CC); + zval *zres = column_at(&row, col.num); if (!zres) { RETVAL_FALSE; } else { + ZVAL_DEREF(zref); zval_dtor(zref); - ZVAL_ZVAL(zref, *zres, 1, 0); + ZVAL_ZVAL(zref, zres, 1, 0); RETVAL_TRUE; } } } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); } } } @@ -854,28 +798,29 @@ static PHP_METHOD(pqres, fetchAllCols) { zval *zcol = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &zcol); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z!", &zcol); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { php_pqres_col_t col; - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - if (SUCCESS == column_nn(obj, zcol, &col TSRMLS_CC)) { + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == column_nn(obj, zcol, &col)) { int r, rows = PQntuples(obj->intern->res); + zval tmp; array_init(return_value); for (r = 0; r < rows; ++r) { - add_next_index_zval(return_value, php_pqres_get_col(obj->intern, r, col.num TSRMLS_CC)); + add_next_index_zval(return_value, php_pqres_get_col(obj->intern, r, col.num, &tmp)); } } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); } } } @@ -886,12 +831,11 @@ struct apply_to_col_arg { ZEND_RESULT_CODE status; }; -static int apply_to_col(void *p, void *a TSRMLS_DC) +static int apply_to_col(zval *c, void *a) { - zval **c = p; struct apply_to_col_arg *arg = a; - if (SUCCESS != column_nn(arg->obj, *c, arg->cols TSRMLS_CC)) { + if (SUCCESS != column_nn(arg->obj, c, arg->cols)) { arg->status = FAILURE; return ZEND_HASH_APPLY_STOP; } else { @@ -901,7 +845,7 @@ static int apply_to_col(void *p, void *a TSRMLS_DC) } } -static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashTable *ht TSRMLS_DC) +static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashTable *ht) { struct apply_to_col_arg arg = {NULL}; php_pqres_col_t *tmp; @@ -909,7 +853,7 @@ static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashT arg.obj = obj; arg.cols = ecalloc(zend_hash_num_elements(ht), sizeof(*tmp)); tmp = arg.cols; - zend_hash_apply_with_argument(ht, apply_to_col, &arg TSRMLS_CC); + zend_hash_apply_with_argument(ht, apply_to_col, &arg); if (SUCCESS == arg.status) { return tmp; @@ -927,18 +871,18 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqres, map) { zend_error_handling zeh; zval *zkeys = 0, *zvals = 0; - long fetch_type = -1; + zend_long fetch_type = -1; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/!z/!l", &zkeys, &zvals, &fetch_type); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z/!z/!l", &zkeys, &zvals, &fetch_type); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { int ks = 0, vs = 0; php_pqres_col_t def = {PQfname(obj->intern->res, 0), 0}, *keys = NULL, *vals = NULL; @@ -947,7 +891,7 @@ static PHP_METHOD(pqres, map) { convert_to_array(zkeys); if ((ks = zend_hash_num_elements(Z_ARRVAL_P(zkeys)))) { - keys = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zkeys) TSRMLS_CC); + keys = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zkeys)); } else { ks = 1; keys = &def; @@ -960,7 +904,7 @@ static PHP_METHOD(pqres, map) { convert_to_array(zvals); if ((vs = zend_hash_num_elements(Z_ARRVAL_P(zvals)))) { - vals = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zvals) TSRMLS_CC); + vals = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zvals)); } } @@ -970,7 +914,7 @@ static PHP_METHOD(pqres, map) { if (keys) { int rows, r; - zval **cur; + zval *cur; switch (fetch_type) { case PHP_PQRES_FETCH_ARRAY: @@ -983,30 +927,32 @@ static PHP_METHOD(pqres, map) { } for (r = 0, rows = PQntuples(obj->intern->res); r < rows; ++r) { int k, v; + zval *ptr; - cur = &return_value; + cur = return_value; for (k = 0; k < ks; ++k) { char *key = PQgetvalue(obj->intern->res, r, keys[k].num); int len = PQgetlength(obj->intern->res, r, keys[k].num); - if (SUCCESS != zend_symtable_find(HASH_OF(*cur), key, len + 1, (void *) &cur)) { - zval *tmp; + if (!(ptr = zend_symtable_str_find(HASH_OF(cur), key, len))) { + zval tmp; - MAKE_STD_ZVAL(tmp); switch (fetch_type) { case PHP_PQRES_FETCH_ARRAY: case PHP_PQRES_FETCH_ASSOC: - array_init(tmp); + array_init(&tmp); break; case PHP_PQRES_FETCH_OBJECT: - object_init(tmp); + object_init(&tmp); break; } - if (SUCCESS != zend_symtable_update(HASH_OF(*cur), key, len + 1, (void *) &tmp, sizeof(zval *), (void *) &cur)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create map"); + if (!(ptr = zend_symtable_str_update(HASH_OF(cur), key, len, &tmp))) { + throw_exce(EX_RUNTIME, "Failed to create map"); goto err; } + cur = ptr; } + cur = ptr; } if (vals && vs) { for (v = 0; v < vs; ++v) { @@ -1015,18 +961,18 @@ static PHP_METHOD(pqres, map) { switch (fetch_type) { case PHP_PQRES_FETCH_ARRAY: - add_index_stringl(*cur, vals[v].num, val, len, 1); + add_index_stringl(cur, vals[v].num, val, len); break; case PHP_PQRES_FETCH_ASSOC: - add_assoc_stringl(*cur, vals[v].name, val, len, 1); + add_assoc_stringl(cur, vals[v].name, val, len); break; case PHP_PQRES_FETCH_OBJECT: - add_property_stringl(*cur, vals[v].name, val, len, 1); + add_property_stringl(cur, vals[v].name, val, len); break; } } } else { - php_pqres_row_to_zval(obj->intern->res, r, fetch_type, cur TSRMLS_CC); + php_pqres_row_to_zval(obj->intern->res, r, fetch_type, cur); } } } @@ -1047,19 +993,21 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqres, fetchAll) { zend_error_handling zeh; - long fetch_type = -1; + zend_long fetch_type = -1; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { int r, rows = PQntuples(obj->intern->res); + zval tmp; if (fetch_type == -1) { fetch_type = php_pqres_fetch_type(obj->intern); @@ -1067,7 +1015,8 @@ static PHP_METHOD(pqres, fetchAll) { array_init(return_value); for (r = 0; r < rows; ++r) { - add_next_index_zval(return_value, php_pqres_row_to_zval(obj->intern->res, r, fetch_type, NULL TSRMLS_CC)); + ZVAL_NULL(&tmp); + add_next_index_zval(return_value, php_pqres_row_to_zval(obj->intern->res, r, fetch_type, &tmp)); } } } @@ -1079,15 +1028,15 @@ static PHP_METHOD(pqres, count) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { long count; - if (SUCCESS != php_pqres_count_elements(getThis(), &count TSRMLS_CC)) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + if (SUCCESS != php_pqres_count_elements(getThis(), &count)) { + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { RETVAL_LONG(count); } @@ -1100,15 +1049,15 @@ static PHP_METHOD(pqres, desc) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { int p, params; @@ -1145,89 +1094,90 @@ PHP_MINIT_FUNCTION(pqres) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Result", php_pqres_methods); - php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqres_class_entry->create_object = php_pqres_create_object; - php_pqres_class_entry->iterator_funcs.funcs = &php_pqres_iterator_funcs; php_pqres_class_entry->get_iterator = php_pqres_iterator_init; - zend_class_implements(php_pqres_class_entry TSRMLS_CC, 2, zend_ce_traversable, spl_ce_Countable); + zend_class_implements(php_pqres_class_entry, 2, zend_ce_traversable, spl_ce_Countable); memcpy(&php_pqres_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqres_object_handlers.offset = XtOffsetOf(php_pqres_object_t, zo); + php_pqres_object_handlers.free_obj = php_pqres_object_free; php_pqres_object_handlers.read_property = php_pq_object_read_prop; php_pqres_object_handlers.write_property = php_pq_object_write_prop; php_pqres_object_handlers.clone_obj = NULL; php_pqres_object_handlers.get_property_ptr_ptr = NULL; - php_pqres_object_handlers.get_gc = NULL; + php_pqres_object_handlers.get_gc = php_pq_object_get_gc; php_pqres_object_handlers.get_debug_info = php_pq_object_debug_info; php_pqres_object_handlers.get_properties = php_pq_object_properties; php_pqres_object_handlers.count_elements = php_pqres_count_elements; - zend_hash_init(&php_pqres_object_prophandlers, 8, NULL, NULL, 1); + zend_hash_init(&php_pqres_object_prophandlers, 8, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_status; - zend_hash_add(&php_pqres_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "status", sizeof("status")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_status_message; - zend_hash_add(&php_pqres_object_prophandlers, "statusMessage", sizeof("statusMessage"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "statusMessage", sizeof("statusMessage")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_error_message; - zend_hash_add(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_num_rows; - zend_hash_add(&php_pqres_object_prophandlers, "numRows", sizeof("numRows"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numRows", sizeof("numRows")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_num_cols; - zend_hash_add(&php_pqres_object_prophandlers, "numCols", sizeof("numCols"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numCols", sizeof("numCols")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_affected_rows; - zend_hash_add(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_fetch_type; ph.write = php_pqres_object_write_fetch_type; - zend_hash_add(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_auto_conv; ph.write = php_pqres_object_write_auto_conv; - zend_hash_add(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR); #ifdef HAVE_PGRES_COPY_BOTH - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH); #endif #ifdef HAVE_PGRES_SINGLE_TUPLE - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE); #endif - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME); #if PHP_PQ_HAVE_PHP_JSON_H - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON); #endif - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL); return SUCCESS; } diff --git a/src/php_pqres.h b/src/php_pqres.h index e0ed25e..acc03cc 100644 --- a/src/php_pqres.h +++ b/src/php_pqres.h @@ -48,14 +48,12 @@ typedef struct php_pqres { } php_pqres_t; typedef struct php_pqres_object { - php_pqres_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqres_t *) } php_pqres_object_t; extern ZEND_RESULT_CODE php_pqres_success(PGresult *res); -extern void php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *obj, php_pqres_object_t **ptr); -extern zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval **data_ptr); +extern php_pqres_object_t *php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *obj); +extern zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval *data); extern zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv); extern php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res); diff --git a/src/php_pqstm.c b/src/php_pqstm.c index 6d61a19..dff5375 100644 --- a/src/php_pqstm.c +++ b/src/php_pqstm.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include "php_pq.h" #include "php_pq_misc.h" @@ -29,7 +29,7 @@ zend_class_entry *php_pqstm_class_entry; static zend_object_handlers php_pqstm_object_handlers; static HashTable php_pqstm_object_prophandlers; -static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_bool silent TSRMLS_DC) +static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_bool silent) { if (obj->intern->allocated) { char *quoted_name = PQescapeIdentifier(obj->intern->conn->intern->conn, obj->intern->name, strlen(obj->intern->name)); @@ -42,19 +42,19 @@ static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_ smart_str_0(&cmd); if (async) { - if (PQsendQuery(obj->intern->conn->intern->conn, cmd.c)) { + if (PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) { obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } else if (!silent) { - throw_exce(EX_IO TSRMLS_CC, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } } else { PGresult *res; - if ((res = PQexec(obj->intern->conn->intern->conn, cmd.c))) { + if ((res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) { PHP_PQclear(res); } else if (!silent) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } } @@ -66,17 +66,17 @@ static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_ } } -static void php_pqstm_object_free(void *o TSRMLS_DC) +static void php_pqstm_object_free(zend_object *o) { - php_pqstm_object_t *obj = o; + php_pqstm_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { if (obj->intern->conn->intern) { php_pq_callback_dtor(&obj->intern->conn->intern->onevent); - php_pqstm_deallocate(obj, 0, 1 TSRMLS_CC); - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pqstm_deallocate(obj, 0, 1); + php_pq_object_delref(obj->intern->conn); } efree(obj->intern->name); efree(obj->intern->query); @@ -87,60 +87,51 @@ static void php_pqstm_object_free(void *o TSRMLS_DC) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern, php_pqstm_object_t **ptr TSRMLS_DC) +php_pqstm_object_t *php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern) { - php_pqstm_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqstm_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqstm_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqstm_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqstm_object_t), + &php_pqstm_object_handlers, &php_pqstm_object_prophandlers); +} - return o->zv; +static zend_object *php_pqstm_create_object(zend_class_entry *class_type) +{ + return &php_pqstm_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqstm_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqstm_object_read_name(zval *object, void *o, zval *return_value) { - return php_pqstm_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqstm_object_t *obj = o; + + RETVAL_STRING(obj->intern->name); } -static void php_pqstm_object_read_name(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_read_connection(zval *object, void *o, zval *return_value) { php_pqstm_object_t *obj = o; - RETVAL_STRING(obj->intern->name, 1); + php_pq_object_to_zval(obj->intern->conn, return_value); } -static void php_pqstm_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_gc_connection(zval *object, void *o, zval *return_value) { php_pqstm_object_t *obj = o; + zval zconn; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static void php_pqstm_object_read_query(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_read_query(zval *object, void *o, zval *return_value) { php_pqstm_object_t *obj = o; - RETVAL_STRING(obj->intern->query, 1); + RETVAL_STRING(obj->intern->query); } -static void php_pqstm_object_read_types(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_read_types(zval *object, void *o, zval *return_value) { int i; php_pqstm_object_t *obj = o; @@ -151,11 +142,11 @@ static void php_pqstm_object_read_types(zval *object, void *o, zval *return_valu } } -php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC) +php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params) { php_pqstm_t *stm = ecalloc(1, sizeof(*stm)); - php_pq_object_addref(conn TSRMLS_CC); + php_pq_object_addref(conn); stm->conn = conn; stm->name = estrdup(name); stm->params = params; @@ -178,33 +169,33 @@ static PHP_METHOD(pqstm, __construct) { zend_error_handling zeh; zval *zconn, *ztypes = NULL; char *name_str, *query_str; - int name_len, *query_len; + size_t name_len, *query_len; zend_bool async = 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oss|a/!b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &query_str, &query_len, &ztypes, &async); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "Oss|a/!b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &query_str, &query_len, &ztypes, &async); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (obj->intern) { - throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\Statement already initialized"); + throw_exce(EX_BAD_METHODCALL, "pq\\Statement already initialized"); } else if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - php_pq_params_t *params = php_pq_params_init(&conn_obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL TSRMLS_CC); + php_pq_params_t *params = php_pq_params_init(&conn_obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL); if (async) { - rv = php_pqconn_prepare_async(zconn, conn_obj, name_str, query_str, params TSRMLS_CC); + rv = php_pqconn_prepare_async(zconn, conn_obj, name_str, query_str, params); } else { - rv = php_pqconn_prepare(zconn, conn_obj, name_str, query_str, params TSRMLS_CC); + rv = php_pqconn_prepare(zconn, conn_obj, name_str, query_str, params); } if (SUCCESS == rv) { - obj->intern = php_pqstm_init(conn_obj, name_str, query_str, params TSRMLS_CC); + obj->intern = php_pqstm_init(conn_obj, name_str, query_str, params); } } } @@ -214,27 +205,26 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind, 0, 0, 2) ZEND_ARG_INFO(1, param_ref) ZEND_END_ARG_INFO(); static PHP_METHOD(pqstm, bind) { - long param_no; - zval **param_ref; + zend_long param_no; + zval *param_ref; zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lZ", ¶m_no, ¶m_ref); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "lz", ¶m_no, ¶m_ref); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(param_ref); - Z_ADDREF_PP(param_ref); - zend_hash_index_update(&obj->intern->bound, param_no, (void *) param_ref, sizeof(zval *), NULL); - zend_hash_sort(&obj->intern->bound, zend_qsort, php_pq_compare_index, 0 TSRMLS_CC); + Z_ADDREF_P(param_ref); + zend_hash_index_update(&obj->intern->bound, param_no, param_ref); + zend_hash_sort(&obj->intern->bound, php_pq_compare_index, 0); } } } @@ -247,17 +237,17 @@ static PHP_METHOD(pqstm, exec) { zval *zparams = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!", &zparams); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|a/!", &zparams); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { PGresult *res; @@ -266,10 +256,10 @@ static PHP_METHOD(pqstm, exec) { php_pq_params_set_params(obj->intern->params, NULL); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); - } else if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + throw_exce(EX_RUNTIME, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + } else if (SUCCESS == php_pqres_success(res)) { + php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -285,17 +275,17 @@ static PHP_METHOD(pqstm, execAsync) { php_pq_callback_t resolver = {{0}}; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!f", &zparams, &resolver.fci, &resolver.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|a/!f", &zparams, &resolver.fci, &resolver.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { int rc; @@ -304,17 +294,17 @@ static PHP_METHOD(pqstm, execAsync) { php_pq_params_set_params(obj->intern->params, NULL); if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); #if HAVE_PQSETSINGLEROWMODE } else if (obj->intern->conn->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn->intern->conn)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); #endif } else { - php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); + php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver); obj->intern->conn->intern->poller = PQconsumeInput; } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -325,24 +315,24 @@ static PHP_METHOD(pqstm, desc) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { PGresult *res = PQdescribePrepared(obj->intern->conn->intern->conn, obj->intern->name); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { + if (SUCCESS == php_pqres_success(res)) { int p, params; array_init(return_value); @@ -351,7 +341,7 @@ static PHP_METHOD(pqstm, desc) { } } PHP_PQclear(res); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -365,23 +355,23 @@ static PHP_METHOD(pqstm, descAsync) { php_pq_callback_t resolver = {{0}}; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &resolver.fci, &resolver.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "f", &resolver.fci, &resolver.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else if (!PQsendDescribePrepared(obj->intern->conn->intern->conn, obj->intern->name)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to describe statement: %s", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to describe statement: %s", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); + php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver); obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -391,17 +381,17 @@ static zend_always_inline void php_pqstm_deallocate_handler(INTERNAL_FUNCTION_PA zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else { - php_pqstm_deallocate(obj, async, 0 TSRMLS_CC); + php_pqstm_deallocate(obj, async, 0); } } } @@ -425,20 +415,20 @@ static zend_always_inline void php_pqstm_prepare_handler(INTERNAL_FUNCTION_PARAM zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { if (async) { - rv = php_pqconn_prepare_async(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params TSRMLS_CC); + rv = php_pqconn_prepare_async(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params); } else { - rv = php_pqconn_prepare(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params TSRMLS_CC); + rv = php_pqconn_prepare(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params); } if (SUCCESS == rv) { @@ -488,35 +478,39 @@ PHP_MINIT_FUNCTION(pqstm) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Statement", php_pqstm_methods); - php_pqstm_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqstm_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqstm_class_entry->create_object = php_pqstm_create_object; memcpy(&php_pqstm_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqstm_object_handlers.offset = XtOffsetOf(php_pqstm_object_t, zo); + php_pqstm_object_handlers.free_obj = php_pqstm_object_free; php_pqstm_object_handlers.read_property = php_pq_object_read_prop; php_pqstm_object_handlers.write_property = php_pq_object_write_prop; php_pqstm_object_handlers.clone_obj = NULL; php_pqstm_object_handlers.get_property_ptr_ptr = NULL; - php_pqstm_object_handlers.get_gc = NULL; + php_pqstm_object_handlers.get_gc = php_pq_object_get_gc; php_pqstm_object_handlers.get_properties = php_pq_object_properties; php_pqstm_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqstm_object_prophandlers, 2, NULL, NULL, 1); + zend_hash_init(&php_pqstm_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_name; - zend_hash_add(&php_pqstm_object_prophandlers, "name", sizeof("name"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "name", sizeof("name")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_connection; - zend_hash_add(&php_pqstm_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqstm_object_gc_connection; + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_query; - zend_hash_add(&php_pqstm_object_prophandlers, "query", sizeof("query"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "query", sizeof("query")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("types"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("types"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_types; - zend_hash_add(&php_pqstm_object_prophandlers, "types", sizeof("types"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "types", sizeof("types")-1, (void *) &ph, sizeof(ph)); return SUCCESS; } diff --git a/src/php_pqstm.h b/src/php_pqstm.h index 61afa42..79e6aa7 100644 --- a/src/php_pqstm.h +++ b/src/php_pqstm.h @@ -26,9 +26,7 @@ typedef struct php_pqstm { } php_pqstm_t; typedef struct php_pqstm_object { - php_pqstm_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqstm_t *) } php_pqstm_object_t; extern zend_class_entry *php_pqstm_class_entry; diff --git a/src/php_pqtxn.c b/src/php_pqtxn.c index e0574e8..5b12545 100644 --- a/src/php_pqtxn.c +++ b/src/php_pqtxn.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include #include @@ -47,11 +47,11 @@ const char *php_pq_isolation_level(long *isolation) } } -static void php_pqtxn_object_free(void *o TSRMLS_DC) +static void php_pqtxn_object_free(zend_object *o) { - php_pqtxn_object_t *obj = o; + php_pqtxn_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { if (obj->intern->open && obj->intern->conn->intern) { @@ -61,90 +61,68 @@ static void php_pqtxn_object_free(void *o TSRMLS_DC) PHP_PQclear(res); } } - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pq_object_delref(obj->intern->conn); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern, php_pqtxn_object_t **ptr TSRMLS_DC) +php_pqtxn_object_t *php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern) { - php_pqtxn_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqtxn_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqtxn_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqtxn_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqtxn_object_t), + &php_pqtxn_object_handlers, &php_pqtxn_object_prophandlers); +} - return o->zv; +static zend_object *php_pqtxn_create_object(zend_class_entry *class_type) +{ + return &php_pqtxn_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqtxn_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqtxn_object_read_connection(zval *object, void *o, zval *return_value) { - return php_pqtxn_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqtxn_object_t *obj = o; + + php_pq_object_to_zval(obj->intern->conn, return_value); } -static void php_pqtxn_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_gc_connection(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; + zval zconn; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static void php_pqtxn_object_read_isolation(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_read_isolation(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; RETVAL_LONG(obj->intern->isolation); } -static void php_pqtxn_object_read_readonly(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_read_readonly(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; RETVAL_BOOL(obj->intern->readonly); } -static void php_pqtxn_object_read_deferrable(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_read_deferrable(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; RETVAL_BOOL(obj->intern->deferrable); } -static void php_pqtxn_object_write_isolation(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqtxn_object_write_isolation(zval *object, void *o, zval *value) { php_pqtxn_object_t *obj = o; php_pqtxn_isolation_t orig = obj->intern->isolation; - zval *zisolation = value; PGresult *res; - if (Z_TYPE_P(zisolation) != IS_LONG) { - if (Z_REFCOUNT_P(value) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zisolation, 1, 0); - convert_to_long(tmp); - zisolation = tmp; - } else { - convert_to_long_ex(&zisolation); - } - } - - switch ((obj->intern->isolation = Z_LVAL_P(zisolation))) { + switch ((obj->intern->isolation = zval_get_long(value))) { case PHP_PQTXN_READ_COMMITTED: res = PQexec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL READ COMMITED"); break; @@ -160,17 +138,13 @@ static void php_pqtxn_object_write_isolation(zval *object, void *o, zval *value break; } - if (zisolation != value) { - zval_ptr_dtor(&zisolation); - } - if (res) { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } -static void php_pqtxn_object_write_readonly(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqtxn_object_write_readonly(zval *object, void *o, zval *value) { php_pqtxn_object_t *obj = o; PGresult *res; @@ -182,12 +156,12 @@ static void php_pqtxn_object_write_readonly(zval *object, void *o, zval *value T } if (res) { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } -static void php_pqtxn_object_write_deferrable(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqtxn_object_write_deferrable(zval *object, void *o, zval *value) { php_pqtxn_object_t *obj = o; PGresult *res; @@ -199,7 +173,7 @@ static void php_pqtxn_object_write_deferrable(zval *object, void *o, zval *value } if (res) { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } @@ -215,19 +189,19 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, __construct) { zend_error_handling zeh; zval *zconn; - long isolation = PHP_PQTXN_READ_COMMITTED; + zend_long isolation = PHP_PQTXN_READ_COMMITTED; zend_bool async = 0, readonly = 0, deferrable = 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|blbb", &zconn, php_pqconn_class_entry, &async, &isolation, &readonly, &deferrable); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|blbb", &zconn, php_pqconn_class_entry, &async, &isolation, &readonly, &deferrable); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { switch (ZEND_NUM_ARGS()) { @@ -244,17 +218,17 @@ static PHP_METHOD(pqtxn, __construct) { } if (async) { - rv = php_pqconn_start_transaction_async(zconn, conn_obj, isolation, readonly, deferrable TSRMLS_CC); + rv = php_pqconn_start_transaction_async(zconn, conn_obj, isolation, readonly, deferrable); } else { - rv = php_pqconn_start_transaction(zconn, conn_obj, isolation, readonly, deferrable TSRMLS_CC); + rv = php_pqconn_start_transaction(zconn, conn_obj, isolation, readonly, deferrable); } if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); obj->intern = ecalloc(1, sizeof(*obj->intern)); - php_pq_object_addref(conn_obj TSRMLS_CC); + php_pq_object_addref(conn_obj); obj->intern->conn = conn_obj; obj->intern->open = 1; obj->intern->isolation = isolation; @@ -271,17 +245,17 @@ static PHP_METHOD(pqtxn, savepoint) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { PGresult *res; smart_str cmd = {0}; @@ -291,12 +265,12 @@ static PHP_METHOD(pqtxn, savepoint) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to create %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } @@ -311,17 +285,17 @@ static PHP_METHOD(pqtxn, savepointAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { smart_str cmd = {0}; @@ -330,8 +304,8 @@ static PHP_METHOD(pqtxn, savepointAsync) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - if (!PQsendQuery(obj->intern->conn->intern->conn, cmd.c)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to create %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + if (!PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) { + throw_exce(EX_IO, "Failed to create %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } smart_str_free(&cmd); @@ -345,22 +319,23 @@ static PHP_METHOD(pqtxn, commit) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transacation not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transacation not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { PGresult *res; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { res = PQexec(obj->intern->conn->intern->conn, "COMMIT"); } else { smart_str_appends(&cmd, "RELEASE SAVEPOINT \""); @@ -368,14 +343,14 @@ static PHP_METHOD(pqtxn, commit) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "commit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "commit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - if (!cmd.c) { + if (SUCCESS == php_pqres_success(res)) { + if (!just_release_sp) { obj->intern->open = 0; } } @@ -383,7 +358,7 @@ static PHP_METHOD(pqtxn, commit) { } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -394,22 +369,23 @@ static PHP_METHOD(pqtxn, commitAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { int rc; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { rc = PQsendQuery(obj->intern->conn->intern->conn, "COMMIT"); } else { smart_str_appends(&cmd, "RELEASE SAVEPOINT \""); @@ -417,17 +393,17 @@ static PHP_METHOD(pqtxn, commitAsync) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - rc = PQsendQuery(obj->intern->conn->intern->conn, cmd.c); + rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "commmit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "commmit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (!cmd.c) { + if (!just_release_sp) { obj->intern->open = 0; } obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } smart_str_free(&cmd); @@ -441,22 +417,23 @@ static PHP_METHOD(pqtxn, rollback) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { PGresult *res; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { res = PQexec(obj->intern->conn->intern->conn, "ROLLBACK"); } else { smart_str_appends(&cmd, "ROLLBACK TO SAVEPOINT \""); @@ -464,14 +441,14 @@ static PHP_METHOD(pqtxn, rollback) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - if (!cmd.c) { + if (SUCCESS == php_pqres_success(res)) { + if (!just_release_sp) { obj->intern->open = 0; } } @@ -479,7 +456,7 @@ static PHP_METHOD(pqtxn, rollback) { } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -490,22 +467,23 @@ static PHP_METHOD(pqtxn, rollbackAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { int rc; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { rc = PQsendQuery(obj->intern->conn->intern->conn, "ROLLBACK"); } else { smart_str_appends(&cmd, "ROLLBACK TO SAVEPOINT \""); @@ -513,20 +491,20 @@ static PHP_METHOD(pqtxn, rollbackAsync) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - rc = PQsendQuery(obj->intern->conn->intern->conn, cmd.c); + rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (!cmd.c) { + if (!just_release_sp) { obj->intern->open = 0; } obj->intern->conn->intern->poller = PQconsumeInput; } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -537,29 +515,29 @@ static PHP_METHOD(pqtxn, exportSnapshot) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { PGresult *res = PQexec(obj->intern->conn->intern->conn, "SELECT pg_export_snapshot()"); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - RETVAL_STRING(PQgetvalue(res, 0, 0), 1); + if (SUCCESS == php_pqres_success(res)) { + RETVAL_STRING(PQgetvalue(res, 0, 0)); } PHP_PQclear(res); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -570,20 +548,20 @@ static PHP_METHOD(pqtxn, exportSnapshotAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!PQsendQuery(obj->intern->conn->intern->conn, "SELECT pg_export_snapshot()")) { - throw_exce(EX_IO TSRMLS_CC, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -594,25 +572,25 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, importSnapshot) { zend_error_handling zeh; char *snapshot_str; - int snapshot_len; + size_t snapshot_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &snapshot_str, &snapshot_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &snapshot_str, &snapshot_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (obj->intern->isolation < PHP_PQTXN_REPEATABLE_READ) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); + throw_exce(EX_RUNTIME, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); } else { char *sid = PQescapeLiteral(obj->intern->conn->intern->conn, snapshot_str, snapshot_len); if (!sid) { - throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_ESCAPE, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { PGresult *res; smart_str cmd = {0}; @@ -621,17 +599,17 @@ static PHP_METHOD(pqtxn, importSnapshot) { smart_str_appends(&cmd, sid); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -643,25 +621,25 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, importSnapshotAsync) { zend_error_handling zeh; char *snapshot_str; - int snapshot_len; + size_t snapshot_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &snapshot_str, &snapshot_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &snapshot_str, &snapshot_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (obj->intern->isolation < PHP_PQTXN_REPEATABLE_READ) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); + throw_exce(EX_RUNTIME, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); } else { char *sid = PQescapeLiteral(obj->intern->conn->intern->conn, snapshot_str, snapshot_len); if (!sid) { - throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_ESCAPE, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { smart_str cmd = {0}; @@ -669,14 +647,14 @@ static PHP_METHOD(pqtxn, importSnapshotAsync) { smart_str_appends(&cmd, sid); smart_str_0(&cmd); - if (!PQsendQuery(obj->intern->conn->intern->conn, cmd.c)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + if (!PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) { + throw_exce(EX_IO, "Failed to %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { obj->intern->conn->intern->poller = PQconsumeInput; } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -688,36 +666,35 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, openLOB) { zend_error_handling zeh; - long mode = INV_WRITE|INV_READ, loid; + zend_long mode = INV_WRITE|INV_READ, loid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &loid, &mode); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &loid, &mode); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { int lofd = lo_open(obj->intern->conn->intern->conn, loid, mode); if (lofd < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to open large object with oid=%u with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to open large object with oid=%lu with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { php_pqlob_t *lob = ecalloc(1, sizeof(*lob)); lob->lofd = lofd; lob->loid = loid; - php_pq_object_addref(obj TSRMLS_CC); + php_pq_object_addref(obj); lob->txn = obj; - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqlob_create_object_ex(php_pqlob_class_entry, lob, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqlob_create_object_ex(php_pqlob_class_entry, lob)->zo); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -727,28 +704,28 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, createLOB) { zend_error_handling zeh; - long mode = INV_WRITE|INV_READ; + zend_long mode = INV_WRITE|INV_READ; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &mode); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { Oid loid = lo_creat(obj->intern->conn->intern->conn, mode); if (loid == InvalidOid) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { int lofd = lo_open(obj->intern->conn->intern->conn, loid, mode); if (lofd < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to open large object with oid=%u with mode '%s': %s", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to open large object with oid=%lu with mode '%s': %s", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { php_pqlob_t *lob = ecalloc(1, sizeof(*lob)); @@ -757,12 +734,11 @@ static PHP_METHOD(pqtxn, createLOB) { php_pq_object_addref(obj TSRMLS_CC); lob->txn = obj; - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqlob_create_object_ex(php_pqlob_class_entry, lob, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqlob_create_object_ex(php_pqlob_class_entry, lob)->zo); } } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -772,26 +748,26 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, unlinkLOB) { zend_error_handling zeh; - long loid; + zend_long loid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &loid); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l", &loid); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { int rc = lo_unlink(obj->intern->conn->intern->conn, loid); if (rc != 1) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to unlink LOB (oid=%u): %s", loid, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to unlink LOB (oid=%lu): %s", loid, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -803,19 +779,19 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, importLOB) { zend_error_handling zeh; char *path_str; - int path_len; - long oid = InvalidOid; + size_t path_len; + zend_long oid = InvalidOid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &path_str, &path_len, &oid); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &path_str, &path_len, &oid); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { if (oid == InvalidOid) { oid = lo_import(obj->intern->conn->intern->conn, path_str); @@ -824,12 +800,12 @@ static PHP_METHOD(pqtxn, importLOB) { } if (oid == InvalidOid) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to import LOB from '%s' (%s)", path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to import LOB from '%s' (%s)", path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { RETVAL_LONG(oid); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -841,27 +817,27 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, exportLOB) { zend_error_handling zeh; char *path_str; - int path_len; - long oid; + size_t path_len; + zend_long oid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lp", &oid, &path_str, &path_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "lp", &oid, &path_str, &path_len); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { int rc = lo_export(obj->intern->conn->intern->conn, oid, path_str); if (rc == -1) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to export LOB (oid=%u) to '%s' (%s)", oid, path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to export LOB (oid=%lu) to '%s' (%s)", oid, path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -898,43 +874,47 @@ PHP_MINIT_FUNCTION(pqtxn) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Transaction", php_pqtxn_methods); - php_pqtxn_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqtxn_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqtxn_class_entry->create_object = php_pqtxn_create_object; memcpy(&php_pqtxn_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqtxn_object_handlers.offset = XtOffsetOf(php_pqtxn_object_t, zo); + php_pqtxn_object_handlers.free_obj = php_pqtxn_object_free; php_pqtxn_object_handlers.read_property = php_pq_object_read_prop; php_pqtxn_object_handlers.write_property = php_pq_object_write_prop; php_pqtxn_object_handlers.clone_obj = NULL; php_pqtxn_object_handlers.get_property_ptr_ptr = NULL; - php_pqtxn_object_handlers.get_gc = NULL; + php_pqtxn_object_handlers.get_gc = php_pq_object_get_gc; php_pqtxn_object_handlers.get_properties = php_pq_object_properties; php_pqtxn_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqtxn_object_prophandlers, 4, NULL, NULL, 1); + zend_hash_init(&php_pqtxn_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_connection; - zend_hash_add(&php_pqtxn_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqtxn_object_gc_connection; + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; - zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_isolation; ph.write = php_pqtxn_object_write_isolation; - zend_hash_add(&php_pqtxn_object_prophandlers, "isolation", sizeof("isolation"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "isolation", sizeof("isolation")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_readonly; ph.write = php_pqtxn_object_write_readonly; - zend_hash_add(&php_pqtxn_object_prophandlers, "readonly", sizeof("readonly"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "readonly", sizeof("readonly")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_deferrable; ph.write = php_pqtxn_object_write_deferrable; - zend_hash_add(&php_pqtxn_object_prophandlers, "deferrable", sizeof("deferrable"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "deferrable", sizeof("deferrable")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC); - zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC); - zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC); + zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED); + zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ); + zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE); return SUCCESS; } diff --git a/src/php_pqtxn.h b/src/php_pqtxn.h index 4873d8e..82e4970 100644 --- a/src/php_pqtxn.h +++ b/src/php_pqtxn.h @@ -32,9 +32,7 @@ typedef struct php_pqtxn { } php_pqtxn_t; typedef struct php_pqtxn_object { - php_pqtxn_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqtxn_t *) } php_pqtxn_object_t; extern const char *php_pq_isolation_level(long *isolation); diff --git a/src/php_pqtypes.c b/src/php_pqtypes.c index 6cf5741..a95c257 100644 --- a/src/php_pqtypes.c +++ b/src/php_pqtypes.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include "php_pq.h" #include "php_pq_misc.h" @@ -28,158 +28,116 @@ zend_class_entry *php_pqtypes_class_entry; static zend_object_handlers php_pqtypes_object_handlers; static HashTable php_pqtypes_object_prophandlers; -static void php_pqtypes_object_free(void *o TSRMLS_DC) +static void php_pqtypes_object_free(zend_object *o) { - php_pqtypes_object_t *obj = o; + php_pqtypes_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE types(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE types(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { zend_hash_destroy(&obj->intern->types); - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pq_object_delref(obj->intern->conn); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern, php_pqtypes_object_t **ptr TSRMLS_DC) +php_pqtypes_object_t *php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern) { - php_pqtypes_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqtypes_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqtypes_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqtypes_object_handlers; - - return o->zv; + return php_pq_object_create(ce, intern, sizeof(php_pqtypes_object_t), + &php_pqtypes_object_handlers, &php_pqtypes_object_prophandlers); } -static zend_object_value php_pqtypes_create_object(zend_class_entry *class_type TSRMLS_DC) +static zend_object *php_pqtypes_create_object(zend_class_entry *class_type) { - return php_pqtypes_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + return &php_pqtypes_create_object_ex(class_type, NULL)->zo; } -static void php_pqtypes_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtypes_object_read_connection(zval *object, void *o, zval *return_value) { php_pqtypes_object_t *obj = o; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval(obj->intern->conn, return_value); +} +static void php_pqtypes_object_gc_connection(zval *object, void *o, zval *return_value) +{ + php_pqtypes_object_t *obj = o; + zval zconn; + + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static int has_dimension(HashTable *ht, zval *member, char **key_str, int *key_len, ulong *index TSRMLS_DC) +static int has_dimension(HashTable *ht, zval *member, zend_string **key, zend_long *index) { - long lval = 0; - zval *tmp = member; - - switch (Z_TYPE_P(member)) { - default: - convert_to_string_ex(&tmp); - /* no break */ - case IS_STRING: - if (!is_numeric_string(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &lval, NULL, 0)) { - int exists = zend_hash_exists(ht, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 1); - - if (key_str) { - *key_str = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); - if (key_len) { - *key_len = Z_STRLEN_P(tmp) + 1; - } - } - if (member != tmp) { - zval_ptr_dtor(&tmp); - } + if (Z_TYPE_P(member) == IS_LONG) { + *index = Z_LVAL_P(member); + + check_index: + return zend_hash_index_exists(ht, *index); + } else { + zend_string *str = zval_get_string(member); - return exists; + if (is_numeric_str_function(str, index, NULL)) { + zend_string_release(str); + goto check_index; } - break; - case IS_LONG: - lval = Z_LVAL_P(member); - break; - } - if (member != tmp) { - zval_ptr_dtor(&tmp); - } - if (index) { - *index = lval; + if (zend_hash_exists(ht, str)) { + *key = str; + return 1; + } + + zend_string_release(str); + return 0; } - return zend_hash_index_exists(ht, lval); } -static int php_pqtypes_object_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC) +static int php_pqtypes_object_has_dimension(zval *object, zval *member, int check_empty) { - php_pqtypes_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); - char *key_str = NULL; - int key_len = 0; - ulong index = 0; - - if (check_empty) { - if (has_dimension(&obj->intern->types, member, &key_str, &key_len, &index TSRMLS_CC)) { - zval **data; - - if (key_str && key_len) { - if (SUCCESS == zend_hash_find(&obj->intern->types, key_str, key_len, (void *) &data)) { - efree(key_str); - return Z_TYPE_PP(data) != IS_NULL; - } - efree(key_str); - key_str = NULL; - } else { - if (SUCCESS == zend_hash_index_find(&obj->intern->types, index, (void *) &data)) { - return Z_TYPE_PP(data) != IS_NULL; + php_pqtypes_object_t *obj = PHP_PQ_OBJ(object, NULL); + zend_string *key = NULL; + zend_long index = 0; + + if (has_dimension(&obj->intern->types, member, &key, &index)) { + if (check_empty) { + zval *data; + + if (key) { + if ((data = zend_hash_find(&obj->intern->types, key))) { + zend_string_release(key); + return Z_TYPE_P(data) != IS_NULL; } + zend_string_release(key); + } else if ((data = zend_hash_index_find(&obj->intern->types, index))) { + return Z_TYPE_P(data) != IS_NULL; } + } else { + return 1; } - if (key_str) { - efree(key_str); - } - } else { - return has_dimension(&obj->intern->types, member, NULL, NULL, NULL TSRMLS_CC); } return 0; } -static zval *php_pqtypes_object_read_dimension(zval *object, zval *member, int type TSRMLS_DC) +static zval *php_pqtypes_object_read_dimension(zval *object, zval *member, int type, zval *rv) { - ulong index = 0; - char *key_str = NULL; - int key_len = 0; - php_pqtypes_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); - - if (has_dimension(&obj->intern->types, member, &key_str, &key_len, &index TSRMLS_CC)) { - zval **data; - - if (key_str && key_len) { - if (SUCCESS == zend_hash_find(&obj->intern->types, key_str, key_len, (void *) &data)) { - efree(key_str); - return *data; - } + php_pqtypes_object_t *obj = PHP_PQ_OBJ(object, NULL); + zend_string *key = NULL; + zend_long index = 0; + zval *data = NULL; + + if (has_dimension(&obj->intern->types, member, &key, &index)) { + if (key) { + data = zend_hash_find(&obj->intern->types, key); + zend_string_release(key); } else { - if (SUCCESS == zend_hash_index_find(&obj->intern->types, index, (void *) &data)) { - return *data; - } + data = zend_hash_index_find(&obj->intern->types, index); } } - if (key_str) { - efree(key_str); - } - - return NULL; + return data; } ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct, 0, 0, 1) @@ -191,32 +149,27 @@ static PHP_METHOD(pqtypes, __construct) { zval *zconn, *znsp = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a!", &zconn, php_pqconn_class_entry, &znsp); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|a!", &zconn, php_pqconn_class_entry, &znsp); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - php_pqtypes_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zval *retval = NULL; + php_pqtypes_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); obj->intern = ecalloc(1, sizeof(*obj->intern)); obj->intern->conn = conn_obj; - php_pq_object_addref(conn_obj TSRMLS_CC); + php_pq_object_addref(conn_obj); zend_hash_init(&obj->intern->types, 512, NULL, ZVAL_PTR_DTOR, 0); if (znsp) { - zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", &retval, znsp); + zend_call_method_with_1_params(getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", NULL, znsp); } else { - zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", &retval); - } - - if (retval) { - zval_ptr_dtor(&retval); + zend_call_method_with_0_params(getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", NULL); } } } @@ -231,18 +184,17 @@ static PHP_METHOD(pqtypes, __construct) { # define PHP_PQ_OID_TEXT 25 #endif -static int apply_nsp(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +static int apply_nsp(zval *zp, int argc, va_list argv, zend_hash_key *key) { - zval **zp = p; unsigned pcount, tcount; php_pq_params_t *params = va_arg(argv, php_pq_params_t *); smart_str *str = va_arg(argv, smart_str *); tcount = php_pq_params_add_type_oid(params, PHP_PQ_OID_TEXT); - pcount = php_pq_params_add_param(params, *zp); + pcount = php_pq_params_add_param(params, zp); if (tcount != pcount) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Param/Type count mismatch"); + php_error_docref(NULL, E_WARNING, "Param/Type count mismatch"); return ZEND_HASH_APPLY_STOP; } if (pcount > 1) { @@ -262,15 +214,15 @@ static PHP_METHOD(pqtypes, refresh) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H/!", &nsp); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|H/!", &nsp); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtypes_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtypes_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Types not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Types not initialized"); } else { PGresult *res; @@ -278,39 +230,39 @@ static PHP_METHOD(pqtypes, refresh) { res = PQexec(obj->intern->conn->intern->conn, PHP_PQ_TYPES_QUERY " and nspname in ('public', 'pg_catalog')"); } else { smart_str str = {0}; - php_pq_params_t *params = php_pq_params_init(&obj->intern->conn->intern->converters, NULL, NULL TSRMLS_CC); + php_pq_params_t *params = php_pq_params_init(&obj->intern->conn->intern->converters, NULL, NULL); smart_str_appends(&str, PHP_PQ_TYPES_QUERY " and nspname in("); zend_hash_apply_with_arguments(nsp TSRMLS_CC, apply_nsp, 2, params, &str); smart_str_appendc(&str, ')'); smart_str_0(&str); - res = PQexecParams(obj->intern->conn->intern->conn, str.c, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0); + res = PQexecParams(obj->intern->conn->intern->conn, smart_str_v(&str), params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0); smart_str_free(&str); php_pq_params_free(¶ms); } if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { + if (SUCCESS == php_pqres_success(res)) { int r, rows; for (r = 0, rows = PQntuples(res); r < rows; ++r) { - zval *row = php_pqres_row_to_zval(res, r, PHP_PQRES_FETCH_OBJECT, NULL TSRMLS_CC); - long oid = atol(PQgetvalue(res, r, 0 )); - char *name = PQgetvalue(res, r, 1); + zval tmp, *row; + ZVAL_NULL(&tmp); + row = php_pqres_row_to_zval(res, r, PHP_PQRES_FETCH_OBJECT, &tmp); Z_ADDREF_P(row); - zend_hash_index_update(&obj->intern->types, oid, (void *) &row, sizeof(zval *), NULL); - zend_hash_update(&obj->intern->types, name, strlen(name) + 1, (void *) &row, sizeof(zval *), NULL); + zend_hash_index_update(&obj->intern->types, atol(PQgetvalue(res, r, 0 )), row); + zend_hash_str_update(&obj->intern->types, PQgetvalue(res, r, 1), PQgetlength(res, r, 1), row); } } PHP_PQclear(res); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -334,7 +286,7 @@ PHP_MINIT_FUNCTION(pqtypes) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Types", php_pqtypes_methods); - php_pqtypes_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqtypes_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqtypes_class_entry->create_object = php_pqtypes_create_object; /* @@ -342,11 +294,13 @@ PHP_MINIT_FUNCTION(pqtypes) */ memcpy(&php_pqtypes_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqtypes_object_handlers.offset = XtOffsetOf(php_pqtypes_object_t, zo); + php_pqtypes_object_handlers.free_obj = php_pqtypes_object_free; php_pqtypes_object_handlers.read_property = php_pq_object_read_prop; php_pqtypes_object_handlers.write_property = php_pq_object_write_prop; php_pqtypes_object_handlers.clone_obj = NULL; php_pqtypes_object_handlers.get_property_ptr_ptr = NULL; - php_pqtypes_object_handlers.get_gc = NULL; + php_pqtypes_object_handlers.get_gc = php_pq_object_get_gc; php_pqtypes_object_handlers.get_properties = php_pq_object_properties; php_pqtypes_object_handlers.get_debug_info = php_pq_object_debug_info; php_pqtypes_object_handlers.has_dimension = php_pqtypes_object_has_dimension; @@ -354,14 +308,16 @@ PHP_MINIT_FUNCTION(pqtypes) php_pqtypes_object_handlers.unset_dimension = NULL; php_pqtypes_object_handlers.write_dimension = NULL; - zend_hash_init(&php_pqtypes_object_prophandlers, 1, NULL, NULL, 1); + zend_hash_init(&php_pqtypes_object_prophandlers, 1, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqtypes_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqtypes_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqtypes_object_read_connection; - zend_hash_add(&php_pqtypes_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqtypes_object_gc_connection; + zend_hash_str_add_mem(&php_pqtypes_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; # undef PHP_PQ_TYPE -# define PHP_PQ_TYPE(name, oid) zend_declare_class_constant_long(php_pqtypes_class_entry, ZEND_STRL(name), oid TSRMLS_CC); +# define PHP_PQ_TYPE(name, oid) zend_declare_class_constant_long(php_pqtypes_class_entry, ZEND_STRL(name), oid); # include "php_pq_type.h" return SUCCESS; diff --git a/src/php_pqtypes.h b/src/php_pqtypes.h index 1c5da1f..9e9d6d6 100644 --- a/src/php_pqtypes.h +++ b/src/php_pqtypes.h @@ -22,9 +22,7 @@ typedef struct php_pqtypes { } php_pqtypes_t; typedef struct php_pqtypes_object { - php_pqtypes_t *intern; - HashTable *prophandler; - zend_object zo; + PHP_PQ_OBJ_DECL(php_pqtypes_t *) } php_pqtypes_object_t; extern zend_class_entry *php_pqtypes_class_entry; diff --git a/tests/async001.phpt b/tests/async001.phpt index d1aa35b..7272272 100644 --- a/tests/async001.phpt +++ b/tests/async001.phpt @@ -38,11 +38,12 @@ while (true) { break 2; } } +$s[] = $c->status; printf("\n%s\n", implode(",", $s)); ?> DONE --EXPECTREGEX-- Test (WP(RP)*)+S -(2,)*3(,\d)*,4 +2(,\d)*,0 DONE diff --git a/tests/async002.phpt b/tests/async002.phpt index 4cc19c8..bd09863 100644 --- a/tests/async002.phpt +++ b/tests/async002.phpt @@ -40,6 +40,7 @@ function complete($c) { break 2; } } + $s[] = $c->status; printf("\n%s\n", implode(",", $s)); } @@ -54,7 +55,7 @@ DONE --EXPECTREGEX-- Test (WP(RP)*)+S -(2,)*3(,\d)*,4 +2(,\d)*,0 (WP(RP)*)+S -(2,)*3(,\d)*,4 +2(,\d)*,0 DONE diff --git a/tests/async003.phpt b/tests/async003.phpt index 9872642..9eb44df 100644 --- a/tests/async003.phpt +++ b/tests/async003.phpt @@ -16,7 +16,7 @@ do { while ($c->busy) { $r = array($c->socket); $w = $e = null; - if (stream_select($r, $w, $e, null)) { + if (stream_select($r, $w, $e, 1, 1000)) { $c->poll(); } } diff --git a/tests/basic002.phpt b/tests/basic002.phpt index 2afb785..e43b27d 100644 --- a/tests/basic002.phpt +++ b/tests/basic002.phpt @@ -13,12 +13,13 @@ $s = $c->prepare("test1", "SELECT \$1",array($t["text"]->oid)); $r = $s->exec(array("fooo")); printf("%s\n", $r->errorMessage); -$r->fetchCol($val); -printf("%s\n", $val); +var_dump($r->fetchCol($val)); +var_dump($val); ?> DONE --EXPECT-- Test -fooo +bool(true) +string(4) "fooo" DONE diff --git a/tests/bound002.phpt b/tests/bound002.phpt index 3633902..cedda91 100644 --- a/tests/bound002.phpt +++ b/tests/bound002.phpt @@ -24,22 +24,22 @@ DONE Test array(3) { [0]=> - &int(2) + int(2) [1]=> - &int(4) + int(4) [2]=> - &int(6) + int(6) } int(2) int(4) int(6) array(3) { [0]=> - &int(3) + int(3) [1]=> - &int(6) + int(6) [2]=> - &int(9) + int(9) } int(3) int(6) diff --git a/tests/lob002.phpt b/tests/lob002.phpt index 3625d89..1eacfbc 100644 --- a/tests/lob002.phpt +++ b/tests/lob002.phpt @@ -35,7 +35,7 @@ int(488) bool(true) Warning: ftruncate(): Can't truncate this stream! in %s on line %d -string(123) "