Merge branch 'v1.0.x'
authorMichael Wallner <mike@php.net>
Tue, 3 May 2016 12:49:28 +0000 (14:49 +0200)
committerMichael Wallner <mike@php.net>
Tue, 3 May 2016 12:56:28 +0000 (14:56 +0200)
17 files changed:
1  2 
src/php_pq_callback.c
src/php_pq_callback.h
src/php_pq_misc.c
src/php_pq_misc.h
src/php_pq_module.c
src/php_pqcancel.c
src/php_pqconn.c
src/php_pqconn.h
src/php_pqconn_event.c
src/php_pqcopy.c
src/php_pqcur.c
src/php_pqlob.c
src/php_pqres.c
src/php_pqres.h
src/php_pqstm.c
src/php_pqtxn.c
src/php_pqtypes.c

@@@ -47,73 -44,98 +47,116 @@@ void php_pq_callback_addref(php_pq_call
        }
  }
  
 -zval *php_pq_callback_to_zval(php_pq_callback_t *cb)
 +zval *php_pq_callback_to_zval(php_pq_callback_t *cb, zval *tmp)
  {
 -      zval *zcb;
 -
        php_pq_callback_addref(cb);
  
 -      if (cb->fci.object_ptr) {
 -              MAKE_STD_ZVAL(zcb);
 -              array_init_size(zcb, 2);
 -              add_next_index_zval(zcb, cb->fci.object_ptr);
 -              add_next_index_zval(zcb, cb->fci.function_name);
 -      } else {
 -              zcb = cb->fci.function_name;
 +      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 zcb;
 +      return &cb->fci.function_name;
  }
  
 -zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb TSRMLS_DC)
 +zval *php_pq_callback_to_zval_no_addref(php_pq_callback_t *cb, zval *tmp)
  {
-       if (cb->fci.size > 0 && Z_TYPE_P(cb->fci.function_name) == IS_OBJECT) {
-               const zend_function *closure = zend_get_closure_method_def(cb->fci.function_name);
 +      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?
+       if (php_pq_callback_is_enabled(cb)) {
+               const zend_function *closure;
+               const zend_execute_data *ex;
  
-               if (closure->type == ZEND_USER_FUNCTION) {
-                       zend_execute_data *ex = EG(current_execute_data);
+               if (Z_TYPE_P(cb->fci.function_name) != IS_OBJECT) {
+                       return 0;
+               }
 -              closure = zend_get_closure_method_def(cb->fci.function_name TSRMLS_CC);
++              closure = zend_get_closure_method_def(cb->fci.function_name);
+               if (closure->type != ZEND_USER_FUNCTION) {
+                       return 0;
+               }
  
-                       while (ex) {
-                               if (ex->op_array == &closure->op_array) {
-                                       return 1;
-                               }
-                               ex = ex->prev_execute_data;
+               for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
+                       if (ex->op_array == &closure->op_array) {
+                               return 1;
                        }
                }
        }
 -
+       if (!php_pq_callback_is_recurrent(cb)) {
+               return 0;
+       }
 -      return php_pq_callback_is_locked(cb->recursion TSRMLS_CC);
++      return php_pq_callback_is_locked(cb->recursion);
 +      */
 +      return 0;
  }
  
--void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new TSRMLS_DC)
++void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new)
  {
-       if (new && new->fci.size > 0 && php_pq_callback_is_locked(old TSRMLS_CC)) {
-               new->recursion = emalloc(sizeof(*old));
-               memcpy(new->recursion, old, sizeof(*old));
-       } else if (new && new->fci.size > 0) {
 -      if (php_pq_callback_is_locked(old TSRMLS_CC)) {
 -              php_pq_callback_recurse_ex(old, new TSRMLS_CC);
++      if (php_pq_callback_is_locked(old)) {
++              php_pq_callback_recurse_ex(old, new);
+       } else {
                php_pq_callback_dtor(old);
-               php_pq_callback_addref(new);
+               if (php_pq_callback_is_enabled(new)) {
+                       php_pq_callback_addref(new);
+                       memcpy(old, new, sizeof(*old));
+                       new->fci.size = 0;
+               }
+       }
+ }
+ extern zend_bool php_pq_callback_is_enabled(php_pq_callback_t *cb)
+ {
+       return cb && cb->fci.size > 0;
+ }
+ extern zend_bool php_pq_callback_is_recurrent(php_pq_callback_t *cb)
+ {
+       return cb && cb->recursion != NULL;
+ }
 -extern void php_pq_callback_disable(php_pq_callback_t *cb TSRMLS_DC)
++extern void php_pq_callback_disable(php_pq_callback_t *cb)
+ {
+       if (php_pq_callback_is_enabled(cb)) {
 -              php_pq_callback_recurse_ex(cb, NULL TSRMLS_CC);
++              php_pq_callback_recurse_ex(cb, NULL);
+       }
+ }
 -extern void php_pq_callback_recurse_ex(php_pq_callback_t *old, php_pq_callback_t *new TSRMLS_DC)
++extern void php_pq_callback_recurse_ex(php_pq_callback_t *old, php_pq_callback_t *new)
+ {
+       php_pq_callback_t *tmp = emalloc(sizeof(*tmp));
+       if (new) {
+               memcpy(tmp, old, sizeof(*tmp));
                memcpy(old, new, sizeof(*old));
-               new->fci.size = 0;
+               old->recursion = tmp;
+               php_pq_callback_addref(old);
 -              php_pq_callback_disable(tmp TSRMLS_CC);
++              php_pq_callback_disable(tmp);
        } else {
-               php_pq_callback_dtor(old);
+               memcpy(tmp, old, sizeof(*tmp));
+               memset(old, 0, sizeof(*old));
+               old->recursion = tmp;
        }
  }
  
@@@ -23,10 -23,13 +23,14 @@@ 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);
 -extern zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb TSRMLS_DC);
 -extern void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new TSRMLS_DC);
 +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);
+ extern zend_bool php_pq_callback_is_enabled(php_pq_callback_t *cb);
 -extern void php_pq_callback_disable(php_pq_callback_t *cb TSRMLS_DC);
 -extern void php_pq_callback_recurse_ex(php_pq_callback_t *old, php_pq_callback_t *new TSRMLS_DC);
++extern void php_pq_callback_disable(php_pq_callback_t *cb);
++extern void php_pq_callback_recurse_ex(php_pq_callback_t *old, php_pq_callback_t *new);
+ extern zend_bool php_pq_callback_is_recurrent(php_pq_callback_t *cb);
  
  #endif
  
  #undef PHP_PQ_TYPE
  #include "php_pq_type.h"
  
 -              TSRMLS_FETCH();
 -              php_pq_object_delref(o TSRMLS_CC);
+ /* clear result object associated with a result handle */
+ void php_pq_clear_res(PGresult *r) {
+       php_pq_object_t *o = PQresultInstanceData(r, php_pqconn_event);
+       if (o) {
 -                      TSRMLS_FETCH_FROM_CTX(evdata->ts);
 -
 -                      if (php_pq_callback_is_locked(&evdata->obj->intern->onevent TSRMLS_CC)) {
 -                              php_pq_callback_disable(&evdata->obj->intern->onevent TSRMLS_CC);
++              php_pq_object_delref(o);
+       } else {
+               PQclear(r);
+       }
+ }
+ /* clear any asynchronous results */
+ void php_pq_clear_conn(PGconn *conn) {
+       PGresult *r;
+       php_pqconn_event_data_t *evdata = PQinstanceData(conn, php_pqconn_event);
+       while ((r = PQgetResult(conn))) {
+               php_pq_clear_res(r);
+       }
+       if (evdata && evdata->obj) {
+               if (php_pq_callback_is_enabled(&evdata->obj->intern->onevent)) {
++                      if (php_pq_callback_is_locked(&evdata->obj->intern->onevent)) {
++                              php_pq_callback_disable(&evdata->obj->intern->onevent);
+                       } else {
+                               php_pq_callback_dtor(&evdata->obj->intern->onevent);
+                       }
+               }
+       }
+ }
+ /* safe wrappers to clear any asynchronous wrappers before querying synchronously */
+ PGresult *php_pq_exec(PGconn *conn, const char *query) {
+       php_pq_clear_conn(conn);
+       return PQexec(conn, query);
+ }
+ PGresult *php_pq_exec_params(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat) {
+       php_pq_clear_conn(conn);
+       return PQexecParams(conn, command, nParams, paramTypes, paramValues, paramLengths, paramFormats, resultFormat);
+ }
+ PGresult *php_pq_prepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes) {
+       php_pq_clear_conn(conn);
+       return PQprepare(conn, stmtName, query, nParams, paramTypes);
+ }
+ PGresult *php_pq_exec_prepared(PGconn *conn, const char *stmtName, int nParams, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat) {
+       php_pq_clear_conn(conn);
+       return PQexecPrepared(conn, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat);
+ }
  char *php_pq_rtrim(char *e)
  {
        size_t l = strlen(e);
@@@ -370,7 -443,7 +421,7 @@@ static ZEND_RESULT_CODE parse_array(Arr
        return SUCCESS;
  }
  
--HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ TSRMLS_DC)
++HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ)
  {
        HashTable *ht = NULL;
        ArrayParserState a = {0};
  
  #include <libpq-fe.h>
  
--#if PHP_VERSION_ID < 50500
--#undef SUCCESS
--#undef FAILURE
--typedef enum {
--      SUCCESS = 0,
--      FAILURE = -1
--} ZEND_RESULT_CODE;
--#endif
--
  #include "php_pqres.h"
  
 -/* TSRM morony */
 -#if PHP_VERSION_ID >= 50700
 -#     define z_is_true(z) zend_is_true(z TSRMLS_CC)
 -#else
 -#     define z_is_true zend_is_true
 -#endif
 +#define z_is_true zend_is_true
 +#define smart_str_s(ss) (ss)->s
 +#define smart_str_v(ss) (ss)->s->val
 +#define smart_str_l(ss) (ss)->s->len
 +
+ /* clear result object associated with a result handle */
+ extern void php_pq_clear_res(PGresult *r);
+ /* clear any asynchronous results */
+ extern void php_pq_clear_conn(PGconn *conn);
+ /* safe wrappers to clear any asynchronous wrappers before querying synchronously */
+ extern PGresult *php_pq_exec(PGconn *conn, const char *query);
+ extern PGresult *php_pq_exec_params(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
+ extern PGresult *php_pq_prepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);
+ extern PGresult *php_pq_exec_prepared(PGconn *conn, const char *stmtName, int nParams, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
  /* trim LF from EOL */
  extern char *php_pq_rtrim(char *e);
  
Simple merge
@@@ -40,34 -40,43 +40,34 @@@ static void php_pqcancel_object_free(ze
                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_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern, php_pqcancel_object_t **ptr TSRMLS_DC)
 +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_std_init((zend_object *) o, ce TSRMLS_CC);
 -      object_properties_init((zend_object *) o, ce);
 -      o->prophandler = &php_pqcancel_object_prophandlers;
 -
 -      if (ptr) {
 -              *ptr = o;
 -      }
 -
 -      if (intern) {
 -              o->intern = intern;
 -      }
 -
 -      o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqcancel_object_free, NULL TSRMLS_CC);
 -      o->zv.handlers = &php_pqcancel_object_handlers;
 +      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)
 -      return o->zv;
++static zend_object *php_pqcancel_create_object(zend_class_entry *class_type)
 +{
 +      return &php_pqcancel_create_object_ex(class_type, NULL)->zo;
  }
  
 -static zend_object_value php_pqcancel_create_object(zend_class_entry *class_type TSRMLS_DC)
 +static void php_pqcancel_object_read_connection(zval *object, void *o, zval *return_value)
  {
 -      return php_pqcancel_create_object_ex(class_type, NULL, NULL TSRMLS_CC);
 +      php_pqcancel_object_t *obj = o;
 +
 +      php_pq_object_to_zval(obj->intern->conn, return_value);
  }
  
 -static void php_pqcancel_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC)
 +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(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);
  }
  
  ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct, 0, 0, 1)
@@@ -549,10 -560,10 +549,10 @@@ php_resource_factory_ops_t *php_pqconn_
        return &php_pqconn_resource_factory_ops;
  }
  
 -static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle TSRMLS_DC)
 +static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle)
  {
        PGresult *res = PQexec(*handle, "");
-       PHP_PQclear(res);
+       php_pq_clear_res(res);
  
        if (CONNECTION_OK != PQstatus(*handle)) {
                PQreset(*handle);
@@@ -580,13 -591,13 +580,13 @@@ static inline PGresult *unlisten(PGcon
        return res;
  }
  
 -static int apply_unlisten(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
 +static int apply_unlisten(zval *p, int argc, va_list argv, zend_hash_key *key)
  {
        php_pqconn_object_t *obj = va_arg(argv, php_pqconn_object_t *);
 -      PGresult *res = unlisten(obj->intern->conn, key->arKey, key->nKeyLength - 1 TSRMLS_CC);
 +      PGresult *res = unlisten(obj->intern->conn, key->key->val, key->key->len);
  
        if (res) {
-               PHP_PQclear(res);
+               php_pq_clear_res(res);
        }
  
        return ZEND_HASH_APPLY_REMOVE;
@@@ -646,21 -657,21 +646,21 @@@ ZEND_END_ARG_INFO()
  static PHP_METHOD(pqconn, __construct) {
        zend_error_handling zeh;
        char *dsn_str = "";
 -      int dsn_len = 0;
 -      long flags = 0;
 +      size_t dsn_len = 0;
 +      zend_long flags = 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, "|sl", &dsn_str, &dsn_len, &flags);
 -      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(), "|sl", &dsn_str, &dsn_len, &flags);
-       zend_restore_error_handling(&zeh TSRMLS_CC);
++      zend_restore_error_handling(&zeh);
  
        if (SUCCESS == rv) {
 -              php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 +              php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
  
                if (obj->intern) {
 -                      throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\Connection already initialized");
 +                      throw_exce(EX_BAD_METHODCALL, "pq\\Connection already initialized");
                } else {
 -                      php_pqconn_event_data_t *evdata =  php_pqconn_event_data_init(obj TSRMLS_CC);
 +                      php_pqconn_event_data_t *evdata =  php_pqconn_event_data_init(obj);
                        php_pqconn_resource_factory_data_t rfdata = {dsn_str, flags};
  
                        obj->intern = ecalloc(1, sizeof(*obj->intern));
@@@ -729,18 -738,18 +729,18 @@@ static PHP_METHOD(pqconn, resetAsync) 
        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_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 +              php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
  
                if (!obj->intern) {
--                      throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
++                      throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
                } else {
                        if (!PQresetStart(obj->intern->conn)) {
--                              throw_exce(EX_IO TSRMLS_CC, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj->intern->conn));
++                              throw_exce(EX_IO, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj->intern->conn));
                        } else {
                                obj->intern->poller = (int (*)(PGconn*)) PQresetPoll;
                        }
@@@ -757,24 -766,24 +757,24 @@@ static PHP_METHOD(pqconn, unlisten
  {
        zend_error_handling zeh;
        char *channel_str;
 -      int channel_len;
 +      size_t channel_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", &channel_str, &channel_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", &channel_str, &channel_len);
 +      zend_restore_error_handling(&zeh);
  
        if (SUCCESS == rv) {
 -              php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 +              php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
  
                if (!obj->intern) {
 -                      throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
 -              } else if (SUCCESS == zend_hash_del(&obj->intern->listeners, channel_str, channel_len + 1)) {
 -                      PGresult *res = unlisten(obj->intern->conn, channel_str, channel_len TSRMLS_CC);
 +                      throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
 +              } else if (SUCCESS == zend_hash_str_del(&obj->intern->listeners, channel_str, channel_len)) {
 +                      PGresult *res = unlisten(obj->intern->conn, channel_str, channel_len);
  
                        if (res) {
 -                              php_pqres_success(res TSRMLS_CC);
 +                              php_pqres_success(res);
-                               PHP_PQclear(res);
+                               php_pq_clear_res(res);
                        }
                }
        }
@@@ -879,22 -882,22 +879,22 @@@ static PHP_METHOD(pqconn, listen) 
                                smart_str_appends(&cmd, quoted_channel);
                                smart_str_0(&cmd);
  
-                               res = PQexec(obj->intern->conn, smart_str_v(&cmd));
 -                              res = php_pq_exec(obj->intern->conn, cmd.c);
++                              res = php_pq_exec(obj->intern->conn, smart_str_v(&cmd));
  
                                smart_str_free(&cmd);
                                PQfreemem(quoted_channel);
  
                                if (!res) {
 -                                      throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
 +                                      throw_exce(EX_RUNTIME, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
                                } else {
 -                                      if (SUCCESS == php_pqres_success(res TSRMLS_CC)) {
 +                                      if (SUCCESS == php_pqres_success(res)) {
                                                obj->intern->poller = PQconsumeInput;
 -                                              php_pqconn_add_listener(obj, channel_str, channel_len, &listener TSRMLS_CC);
 +                                              php_pqconn_add_listener(obj, channel_str, channel_len, &listener);
                                        }
-                                       PHP_PQclear(res);
+                                       php_pq_clear_res(res);
                                }
  
 -                              php_pqconn_notify_listeners(obj TSRMLS_CC);
 +                              php_pqconn_notify_listeners(obj);
                        }
                }
        }
@@@ -911,20 -914,20 +911,20 @@@ static PHP_METHOD(pqconn, listenAsync) 
        php_pq_callback_t listener = {{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, "sf", &channel_str, &channel_len, &listener.fci, &listener.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(), "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc);
 +      zend_restore_error_handling(&zeh);
  
        if (SUCCESS == rv) {
 -              php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 +              php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
  
                if (!obj->intern) {
--                      throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
++                      throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
                } else {
                        char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len);
  
                        if (!quoted_channel) {
--                              throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
++                              throw_exce(EX_ESCAPE, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
                        } else {
                                smart_str cmd = {0};
  
@@@ -973,13 -976,13 +973,13 @@@ static PHP_METHOD(pqconn, notify) 
                        res = PQexecParams(obj->intern->conn, "select pg_notify($1, $2)", 2, NULL, (const char *const*) params, NULL, NULL, 0);
  
                        if (!res) {
 -                              throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn));
 +                              throw_exce(EX_RUNTIME, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn));
                        } else {
 -                              php_pqres_success(res TSRMLS_CC);
 +                              php_pqres_success(res);
-                               PHP_PQclear(res);
+                               php_pq_clear_res(res);
                        }
  
 -                      php_pqconn_notify_listeners(obj TSRMLS_CC);
 +                      php_pqconn_notify_listeners(obj);
                }
        }
  }
@@@ -1051,30 -1054,30 +1051,30 @@@ ZEND_END_ARG_INFO()
  static PHP_METHOD(pqconn, exec) {
        zend_error_handling zeh;
        char *query_str;
 -      int query_len;
 +      size_t query_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", &query_str, &query_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", &query_str, &query_len);
 +      zend_restore_error_handling(&zeh);
  
        if (SUCCESS == rv) {
 -              php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 +              php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
  
                if (!obj->intern) {
 -                      throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
 +                      throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
                } else {
-                       PGresult *res = PQexec(obj->intern->conn, query_str);
+                       PGresult *res = php_pq_exec(obj->intern->conn, query_str);
  
                        if (!res) {
 -                              throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->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);
 +                              throw_exce(EX_RUNTIME, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
 +                      } else if (SUCCESS == php_pqres_success(res)) {
 +                              php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value);
                        } else {
-                               PHP_PQclear(res);
+                               php_pq_clear_res(res);
                        }
  
 -                      php_pqconn_notify_listeners(obj TSRMLS_CC);
 +                      php_pqconn_notify_listeners(obj);
                }
        }
  }
@@@ -1173,15 -1176,15 +1173,15 @@@ static PHP_METHOD(pqconn, execParams) 
                        php_pq_params_free(&params);
  
                        if (!res) {
 -                              throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
 +                              throw_exce(EX_RUNTIME, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->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);
 +                              if (SUCCESS == php_pqres_success(res)) {
 +                                      php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value);
                                } else {
-                                       PHP_PQclear(res);
+                                       php_pq_clear_res(res);
                                }
  
 -                              php_pqconn_notify_listeners(obj TSRMLS_CC);
 +                              php_pqconn_notify_listeners(obj);
                        }
                }
        }
@@@ -1241,18 -1244,18 +1241,18 @@@ ZEND_RESULT_CODE php_pqconn_prepare(zva
        ZEND_RESULT_CODE rv;
  
        if (!obj) {
 -              obj = zend_object_store_get_object(object TSRMLS_CC);
 +              obj = PHP_PQ_OBJ(object, NULL);
        }
  
-       res = PQprepare(obj->intern->conn, name, query, params->type.count, params->type.oids);
+       res = php_pq_prepare(obj->intern->conn, name, query, params->type.count, params->type.oids);
  
        if (!res) {
                rv = FAILURE;
 -              throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn));
 +              throw_exce(EX_RUNTIME, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn));
        } else {
 -              rv = php_pqres_success(res TSRMLS_CC);
 +              rv = php_pqres_success(res);
-               PHP_PQclear(res);
+               php_pq_clear_res(res);
 -              php_pqconn_notify_listeners(obj TSRMLS_CC);
 +              php_pqconn_notify_listeners(obj);
        }
  
        return rv;
@@@ -1293,7 -1297,7 +1293,7 @@@ static PHP_METHOD(pqconn, prepare) 
        }
  }
  
--ZEND_RESULT_CODE php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC)
++ZEND_RESULT_CODE php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params)
  {
        ZEND_RESULT_CODE rv;
  
@@@ -1354,18 -1359,18 +1354,18 @@@ ZEND_RESULT_CODE php_pqconn_declare(zva
        ZEND_RESULT_CODE rv;
  
        if (!obj) {
 -              obj = zend_object_store_get_object(object TSRMLS_CC);
 +              obj = PHP_PQ_OBJ(object, NULL);
        }
  
-       res = PQexec(obj->intern->conn, decl);
+       res = php_pq_exec(obj->intern->conn, decl);
  
        if (!res) {
                rv = FAILURE;
 -              throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
 +              throw_exce(EX_RUNTIME, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
        } else {
 -              rv = php_pqres_success(res TSRMLS_CC);
 +              rv = php_pqres_success(res);
-               PHP_PQclear(res);
+               php_pq_clear_res(res);
 -              php_pqconn_notify_listeners(obj TSRMLS_CC);
 +              php_pqconn_notify_listeners(obj);
        }
  
        return rv;
@@@ -1578,7 -1585,7 +1578,7 @@@ ZEND_RESULT_CODE php_pqconn_start_trans
        }
  
        if (!conn_obj->intern) {
--              throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
++              throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
        } else {
                PGresult *res;
                smart_str cmd = {0};
                smart_str_appends(&cmd, " DEFERRABLE");
                smart_str_0(&cmd);
  
-               res = PQexec(conn_obj->intern->conn, smart_str_v(&cmd));
 -              res = php_pq_exec(conn_obj->intern->conn, cmd.c);
++              res = php_pq_exec(conn_obj->intern->conn, smart_str_v(&cmd));
  
                if (!res) {
 -                      throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn));
 +                      throw_exce(EX_RUNTIME, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn));
                } else {
 -                      rv = php_pqres_success(res TSRMLS_CC);
 +                      rv = php_pqres_success(res);
-                       PHP_PQclear(res);
+                       php_pq_clear_res(res);
 -                      php_pqconn_notify_listeners(conn_obj TSRMLS_CC);
 +                      php_pqconn_notify_listeners(conn_obj);
                }
  
                smart_str_free(&cmd);
@@@ -1783,17 -1793,19 +1783,17 @@@ static PHP_METHOD(pqconn, on) 
        php_pq_callback_t cb = {{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, "sf", &type_str, &type_len, &cb.fci, &cb.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(), "sf", &type_str, &type_len, &cb.fci, &cb.fcc);
 +      zend_restore_error_handling(&zeh);
  
        if (SUCCESS == rv) {
 -              php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 +              php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
  
                if (!obj->intern) {
--                      throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
++                      throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized");
                } else {
 -                      php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 -
 -                      RETVAL_LONG(php_pqconn_add_eventhandler(obj, type_str, type_len, &cb TSRMLS_CC));
 +                      RETVAL_LONG(php_pqconn_add_eventhandler(obj, type_str, type_len, &cb));
                }
        }
  }
@@@ -1957,148 -1969,132 +1957,148 @@@ PHP_MINIT_FUNCTION(pqconn
        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 TSRMLS_CC);
 +      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_status;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "status", sizeof("status")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_transaction_status;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC);
        ph.read = NULL; /* forward to std prophandler */
 -      zend_hash_add(&php_pqconn_object_prophandlers, "socket", sizeof("socket"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "socket", sizeof("socket")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_error_message;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_busy;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "busy", sizeof("busy"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "busy", sizeof("busy")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_encoding;
        ph.write = php_pqconn_object_write_encoding;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "encoding", sizeof("encoding"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "encoding", sizeof("encoding")-1, (void *) &ph, sizeof(ph));
        ph.write = NULL;
  
 -      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_unbuffered;
        ph.write = php_pqconn_object_write_unbuffered;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "unbuffered", sizeof("unbuffered"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "unbuffered", sizeof("unbuffered")-1, (void *) &ph, sizeof(ph));
        ph.write = NULL;
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("db"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_db;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "db", sizeof("db"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "db", sizeof("db")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_user;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "user", sizeof("user"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "user", sizeof("user")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_pass;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "pass", sizeof("pass"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "pass", sizeof("pass")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_host;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "host", sizeof("host"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "host", sizeof("host")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_port;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "port", sizeof("port"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "port", sizeof("port")-1, (void *) &ph, sizeof(ph));
  
  #if HAVE_PQCONNINFO
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("params"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("params"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_params;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "params", sizeof("params"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "params", sizeof("params")-1, (void *) &ph, sizeof(ph));
  #endif
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_options;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "options", sizeof("options"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "options", sizeof("options")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_event_handlers;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "eventHandlers", sizeof("eventHandlers"), (void *) &ph, sizeof(ph), NULL);
 -
 -      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
 +      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;
        ph.write = php_pqconn_object_write_def_fetch_type;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "defaultFetchType", sizeof("defaultFetchType"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultFetchType", sizeof("defaultFetchType")-1, (void *) &ph, sizeof(ph));
        ph.write = NULL;
  
 -      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_def_txn_isolation;
        ph.write = php_pqconn_object_write_def_txn_isolation;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation")-1, (void *) &ph, sizeof(ph));
        ph.write = NULL;
  
 -      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_def_txn_readonly;
        ph.write = php_pqconn_object_write_def_txn_readonly;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly")-1, (void *) &ph, sizeof(ph));
        ph.write = NULL;
  
--      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
++      zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_def_txn_deferrable;
        ph.write = php_pqconn_object_write_def_txn_deferrable;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable")-1, (void *) &ph, sizeof(ph));
        ph.write = NULL;
  
 -      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC);
        ph.read = php_pqconn_object_read_def_auto_conv;
        ph.write = php_pqconn_object_write_def_auto_conv;
 -      zend_hash_add(&php_pqconn_object_prophandlers, "defaultAutoConvert", sizeof("defaultAutoConvert"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultAutoConvert", sizeof("defaultAutoConvert")-1, (void *) &ph, sizeof(ph));
        ph.write = NULL;
  
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC);
 -
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC);
 -
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC);
 -
 -      zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice") TSRMLS_CC);
 -      zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result") TSRMLS_CC);
 -      zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset") TSRMLS_CC);
 -
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV);
  
 -      return SUCCESS;
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN);
 +
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK);
 +
 +      zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice"));
 +      zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result"));
 +      zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset"));
 +
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("ASYNC"), 0x1);
 +      zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("PERSISTENT"), 0x2);
 +
 +      PHP_PQ_G->connection.name = zend_string_init(ZEND_STRL("pq\\Connection"), 1);
 +
 +      return php_persistent_handle_provide(PHP_PQ_G->connection.name, php_pqconn_get_resource_factory_ops(), NULL, NULL);
  }
  
  /*
@@@ -18,8 -18,8 +18,9 @@@
  #define PHP_PQCONN_PERSISTENT 0x02
  
  #include <ext/raphf/php_raphf.h>
 +#include "php_pq_object.h"
  #include "php_pq_callback.h"
+ #include "php_pq_object.h"
  #include "php_pq_params.h"
  
  typedef struct php_pqconn {
@@@ -80,12 -86,12 +80,12 @@@ static void php_pqconn_event_resultcrea
                }
  
                /* async callback */
-               if (data->obj->intern->onevent.fci.size > 0) {
+               if (php_pq_callback_is_enabled(&data->obj->intern->onevent)) {
 -                      zval *res = NULL;
 +                      zval res;
  
 -                      php_pq_object_to_zval(obj, &res TSRMLS_CC);
 -                      zend_fcall_info_argn(&data->obj->intern->onevent.fci TSRMLS_CC, 1, &res);
 -                      zend_fcall_info_call(&data->obj->intern->onevent.fci, &data->obj->intern->onevent.fcc, NULL, NULL TSRMLS_CC);
 +                      php_pq_object_to_zval(obj, &res);
 +                      zend_fcall_info_argn(&data->obj->intern->onevent.fci, 1, &res);
 +                      zend_fcall_info_call(&data->obj->intern->onevent.fci, &data->obj->intern->onevent.fcc, NULL, NULL);
                        zval_ptr_dtor(&res);
                }
  
@@@ -141,21 -150,21 +141,21 @@@ static PHP_METHOD(pqcopy, __construct) 
                        smart_str_appendl(&cmd, opt_str, opt_len);
                        smart_str_0(&cmd);
  
-                       res = PQexec(conn_obj->intern->conn, smart_str_v(&cmd));
 -                      res = php_pq_exec(conn_obj->intern->conn, cmd.c);
++                      res = php_pq_exec(conn_obj->intern->conn, smart_str_v(&cmd));
  
                        if (!res) {
 -                              throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to start %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn));
 +                              throw_exce(EX_RUNTIME, "Failed to start %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn));
                        } else {
 -                              if (SUCCESS == php_pqres_success(res TSRMLS_CC)) {
 +                              if (SUCCESS == php_pqres_success(res)) {
                                        obj->intern = ecalloc(1, sizeof(*obj->intern));
                                        obj->intern->direction = direction;
                                        obj->intern->expression = estrdup(expr_str);
                                        obj->intern->options = estrdup(opt_str);
                                        obj->intern->conn = conn_obj;
 -                                      php_pq_object_addref(conn_obj TSRMLS_CC);
 +                                      php_pq_object_addref(conn_obj);
                                }
  
-                               PHP_PQclear(res);
+                               php_pq_clear_res(res);
                        }
  
                        smart_str_free(&cmd);
@@@ -220,10 -229,10 +220,10 @@@ static PHP_METHOD(pqcopy, end) 
                                PGresult *res = PQgetResult(obj->intern->conn->intern->conn);
  
                                if (!res) {
 -                                      throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
 +                                      throw_exce(EX_RUNTIME, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
                                } else {
 -                                      php_pqres_success(res TSRMLS_CC);
 +                                      php_pqres_success(res);
-                                       PHP_PQclear(res);
+                                       php_pq_clear_res(res);
                                }
                        }
  
@@@ -240,17 -249,17 +240,17 @@@ static PHP_METHOD(pqcopy, get) 
        zval *zdata;
        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", &zdata);
 -      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() TSRMLS_CC, "z", &zdata);
++      rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zdata);
 +      zend_restore_error_handling(&zeh);
  
        if (SUCCESS == rv) {
 -              php_pqcopy_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 +              php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
  
                if (!obj->intern) {
 -                      throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\COPY not initialized");
 +                      throw_exce(EX_UNINITIALIZED, "pq\\COPY not initialized");
                } else if (obj->intern->direction != PHP_PQCOPY_TO_STDOUT) {
 -                      throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\COPY was not intialized with TO_STDOUT");
 +                      throw_exce(EX_RUNTIME, "pq\\COPY was not intialized with TO_STDOUT");
                } else {
                        PGresult *res;
                        char *buffer = NULL;
                                res = PQgetResult(obj->intern->conn->intern->conn);
  
                                if (!res) {
 -                                      throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
 +                                      throw_exce(EX_RUNTIME, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
                                } else {
 -                                      php_pqres_success(res TSRMLS_CC);
 +                                      php_pqres_success(res);
-                                       PHP_PQclear(res);
+                                       php_pq_clear_res(res);
                                        RETVAL_FALSE;
                                }
                                break;
diff --cc src/php_pqcur.c
@@@ -40,17 -40,17 +40,17 @@@ static void cur_close(php_pqcur_object_
                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 close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
 +                              throw_exce(EX_IO, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
                        }
                } else {
-                       if ((res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) {
-                               PHP_PQclear(res);
 -                      if ((res = php_pq_exec(obj->intern->conn->intern->conn, cmd.c))) {
++                      if ((res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) {
+                               php_pq_clear_res(res);
                        } else if (!silent) {
 -                              throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
 +                              throw_exce(EX_RUNTIME, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn));
                        }
                }
  
@@@ -133,12 -133,12 +133,12 @@@ static void cur_fetch_or_move(INTERNAL_
                                        obj->intern->conn->intern->poller = PQconsumeInput;
                                }
                        } else {
-                               PGresult *res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
 -                              PGresult *res = php_pq_exec(obj->intern->conn->intern->conn, cmd.c);
++                              PGresult *res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
  
                                if (!res) {
 -                                      throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", 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);
 +                                      throw_exce(EX_RUNTIME, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", 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);
  
                                }
                        }
@@@ -438,31 -445,29 +438,31 @@@ PHP_MINIT_FUNCTION(pqcur
        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 TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("INSENSITIVE"), PHP_PQ_DECLARE_INSENSITIVE TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("WITH_HOLD"), PHP_PQ_DECLARE_WITH_HOLD TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("SCROLL"), PHP_PQ_DECLARE_SCROLL TSRMLS_CC);
 -      zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("NO_SCROLL"), PHP_PQ_DECLARE_NO_SCROLL TSRMLS_CC);
 +      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);
 +      zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("WITH_HOLD"), PHP_PQ_DECLARE_WITH_HOLD);
 +      zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("SCROLL"), PHP_PQ_DECLARE_SCROLL);
 +      zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("NO_SCROLL"), PHP_PQ_DECLARE_NO_SCROLL);
  
 -      zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC);
        ph.read = php_pqcur_object_read_name;
 -      zend_hash_add(&php_pqcur_object_prophandlers, "name", sizeof("name"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "name", sizeof("name")-1, (void *) &ph, sizeof(ph));
  
 -      zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC);
 +      zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC);
        ph.read = php_pqcur_object_read_connection;
 -      zend_hash_add(&php_pqcur_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL);
 +      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 TSRMLS_CC);
 +      zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC);
        ph.read = php_pqcur_object_read_query;
 -      zend_hash_add(&php_pqcur_object_prophandlers, "query", sizeof("query"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "query", sizeof("query")-1, (void *) &ph, sizeof(ph));
  
--      zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("flags"), ZEND_ACC_PUBLIC TSRMLS_CC);
++      zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("flags"), ZEND_ACC_PUBLIC);
        ph.read = php_pqcur_object_read_flags;
 -      zend_hash_add(&php_pqcur_object_prophandlers, "flags", sizeof("flags"), (void *) &ph, sizeof(ph), NULL);
 +      zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "flags", sizeof("flags")-1, (void *) &ph, sizeof(ph));
  
        return SUCCESS;
  }
diff --cc src/php_pqlob.c
@@@ -84,23 -93,24 +84,23 @@@ static void php_pqlob_object_read_oid(z
        RETVAL_LONG(obj->intern->loid);
  }
  
 -static void php_pqlob_object_update_stream(zval *this_ptr, php_pqlob_object_t *obj, zval **zstream TSRMLS_DC);
 +static void php_pqlob_object_update_stream(zval *this_ptr, php_pqlob_object_t *obj, zval *zstream);
  
 -static void php_pqlob_object_read_stream(zval *object, void *o, zval *return_value TSRMLS_DC)
 +static void php_pqlob_object_read_stream(zval *object, void *o, zval *return_value)
  {
        php_pqlob_object_t *obj = o;
 +      zval zstream;
  
        if (!obj->intern->stream) {
 -              zval *zstream;
 -
 -              php_pqlob_object_update_stream(object, obj, &zstream TSRMLS_CC);
 -              RETVAL_ZVAL(zstream, 1, 1);
 +              php_pqlob_object_update_stream(object, obj, &zstream);
        } else {
 -              RETVAL_RESOURCE(obj->intern->stream);
 -              zend_list_addref(obj->intern->stream);
 +              php_stream_to_zval(obj->intern->stream, &zstream);
        }
 +
 +      RETVAL_ZVAL(&zstream, 1, 0);
  }
  
--static size_t php_pqlob_stream_write(php_stream *stream, const char *buffer, size_t length TSRMLS_DC)
++static size_t php_pqlob_stream_write(php_stream *stream, const char *buffer, size_t length)
  {
        php_pqlob_object_t *obj = stream->abstract;
        int written = 0;
                written = lo_write(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, buffer, length);
  
                if (written < 0) {
--                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write to LOB with oid=%u (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
++                      php_error_docref(NULL, E_WARNING, "Failed to write to LOB with oid=%u (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
                }
  
--              php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC);
++              php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
        }
  
        return written;
  }
  
--static size_t php_pqlob_stream_read(php_stream *stream, char *buffer, size_t length TSRMLS_DC)
++static size_t php_pqlob_stream_read(php_stream *stream, char *buffer, size_t length)
  {
        php_pqlob_object_t *obj = stream->abstract;
        int read = 0;
                        read = lo_read(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, buffer, length);
  
                        if (read < 0) {
--                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to read from LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
++                              php_error_docref(NULL, E_WARNING, "Failed to read from LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
                        }
                }
  
--              php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC);
++              php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
        }
  
        return read;
  }
  
--static ZEND_RESULT_CODE php_pqlob_stream_close(php_stream *stream, int close_handle TSRMLS_DC)
++static ZEND_RESULT_CODE php_pqlob_stream_close(php_stream *stream, int close_handle)
  {
        return SUCCESS;
  }
  
--static int php_pqlob_stream_flush(php_stream *stream TSRMLS_DC)
++static int php_pqlob_stream_flush(php_stream *stream)
  {
        return SUCCESS;
  }
  
--static ZEND_RESULT_CODE php_pqlob_stream_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC)
++static ZEND_RESULT_CODE php_pqlob_stream_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset)
  {
        ZEND_RESULT_CODE rv = FAILURE;
        php_pqlob_object_t *obj = stream->abstract;
                int position = lo_lseek(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, offset, whence);
  
                if (position < 0) {
--                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
++                      php_error_docref(NULL, E_WARNING, "Failed to seek offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn));
                        rv = FAILURE;
                } else {
                        *newoffset = position;
                        rv = SUCCESS;
                }
  
--              php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC);
++              php_pqconn_notify_listeners(obj->intern->txn->intern->conn);
        }
  
        return rv;
diff --cc src/php_pqres.c
@@@ -374,9 -387,9 +374,9 @@@ static ZEND_RESULT_CODE php_pqres_count
        }
  }
  
--ZEND_RESULT_CODE php_pqres_success(PGresult *res TSRMLS_DC)
++ZEND_RESULT_CODE php_pqres_success(PGresult *res)
  {
 -      zval *zexc;
 +      zval zexc;
  
        switch (PQresultStatus(res)) {
        case PGRES_BAD_RESPONSE:
@@@ -522,14 -574,31 +522,14 @@@ static void php_pqres_object_read_auto_
        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 *zobj, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval *row TSRMLS_DC)
 -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)
  {
        ZEND_RESULT_CODE rv;
        php_pqres_fetch_t orig_fetch;
diff --cc src/php_pqres.h
@@@ -59,17 -62,9 +59,9 @@@ extern php_pqres_fetch_t php_pqres_fetc
  
  #include "php_pq_object.h"
  #include "php_pqconn_event.h"
- #define PHP_PQclear(_r) do { \
-       php_pqres_object_t *_o = PQresultInstanceData((_r), php_pqconn_event); \
-       if (_o) { \
-               php_pq_object_delref(_o); \
-       } else { \
-               PQclear(_r); \
-       } \
- } while(0)
  
  extern zend_class_entry *php_pqres_class_entry;
 -extern zend_object_value php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern, php_pqres_object_t **ptr TSRMLS_DC);
 +extern php_pqres_object_t *php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern);
  
  extern PHP_MINIT_FUNCTION(pqres);
  extern PHP_MSHUTDOWN_FUNCTION(pqres);
diff --cc src/php_pqstm.c
@@@ -51,10 -51,10 +51,10 @@@ static void php_pqstm_deallocate(php_pq
                        } else {
                                PGresult *res;
  
-                               if ((res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) {
-                                       PHP_PQclear(res);
 -                              if ((res = php_pq_exec(obj->intern->conn->intern->conn, cmd.c))) {
++                              if ((res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) {
+                                       php_pq_clear_res(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));
                                }
                        }
  
@@@ -340,8 -350,8 +340,8 @@@ static PHP_METHOD(pqstm, desc) 
                                                add_next_index_long(return_value, PQparamtype(res, p));
                                        }
                                }
-                               PHP_PQclear(res);
+                               php_pq_clear_res(res);
 -                              php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC);
 +                              php_pqconn_notify_listeners(obj->intern->conn);
                        }
                }
        }
diff --cc src/php_pqtxn.c
@@@ -55,13 -55,13 +55,13 @@@ static void php_pqtxn_object_free(zend_
  #endif
        if (obj->intern) {
                if (obj->intern->open && obj->intern->conn->intern) {
-                       PGresult *res = PQexec(obj->intern->conn->intern->conn, "ROLLBACK");
+                       PGresult *res = php_pq_exec(obj->intern->conn->intern->conn, "ROLLBACK");
  
                        if (res) {
-                               PHP_PQclear(res);
+                               php_pq_clear_res(res);
                        }
                }
 -              php_pq_object_delref(obj->intern->conn TSRMLS_CC);
 +              php_pq_object_delref(obj->intern->conn);
                efree(obj->intern);
                obj->intern = NULL;
        }
@@@ -120,17 -129,30 +120,17 @@@ static void php_pqtxn_object_write_isol
  {
        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");
+               res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL READ COMMITED");
                break;
        case PHP_PQTXN_REPEATABLE_READ:
-               res = PQexec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
+               res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
                break;
        case PHP_PQTXN_SERIALIZABLE:
-               res = PQexec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
+               res = php_pq_exec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
                break;
        default:
                obj->intern->isolation = orig;
                break;
        }
  
 -      if (zisolation != value) {
 -              zval_ptr_dtor(&zisolation);
 -      }
 -
        if (res) {
 -              php_pqres_success(res TSRMLS_CC);
 +              php_pqres_success(res);
-               PHP_PQclear(res);
+               php_pq_clear_res(res);
        }
  }
  
@@@ -156,8 -182,8 +156,8 @@@ static void php_pqtxn_object_write_read
        }
  
        if (res) {
 -              php_pqres_success(res TSRMLS_CC);
 +              php_pqres_success(res);
-               PHP_PQclear(res);
+               php_pq_clear_res(res);
        }
  }
  
@@@ -173,8 -199,8 +173,8 @@@ static void php_pqtxn_object_write_defe
        }
  
        if (res) {
 -              php_pqres_success(res TSRMLS_CC);
 +              php_pqres_success(res);
-               PHP_PQclear(res);
+               php_pq_clear_res(res);
        }
  }
  
@@@ -265,13 -291,13 +265,13 @@@ static PHP_METHOD(pqtxn, savepoint) 
                        smart_str_appends(&cmd, "\"");
                        smart_str_0(&cmd);
  
-                       res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
 -                      res = php_pq_exec(obj->intern->conn->intern->conn, cmd.c);
++                      res = php_pq_exec(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);
+                               php_pq_clear_res(res);
                        }
  
                        smart_str_free(&cmd);
@@@ -333,17 -359,16 +333,17 @@@ static PHP_METHOD(pqtxn, commit) 
                } 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");
+                               res = php_pq_exec(obj->intern->conn->intern->conn, "COMMIT");
                        } else {
                                smart_str_appends(&cmd, "RELEASE SAVEPOINT \"");
                                smart_str_append_unsigned(&cmd, obj->intern->savepoint--);
                                smart_str_appends(&cmd, "\"");
                                smart_str_0(&cmd);
  
-                               res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
 -                              res = php_pq_exec(obj->intern->conn->intern->conn, cmd.c);
++                              res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
                        }
  
                        if (!res) {
@@@ -431,17 -455,16 +431,17 @@@ static PHP_METHOD(pqtxn, rollback) 
                } 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");
+                               res = php_pq_exec(obj->intern->conn->intern->conn, "ROLLBACK");
                        } else {
                                smart_str_appends(&cmd, "ROLLBACK TO SAVEPOINT \"");
                                smart_str_append_unsigned(&cmd, obj->intern->savepoint--);
                                smart_str_appends(&cmd, "\"");
                                smart_str_0(&cmd);
  
-                               res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
 -                              res = php_pq_exec(obj->intern->conn->intern->conn, cmd.c);
++                              res = php_pq_exec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
                        }
  
                        if (!res) {
@@@ -515,29 -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()");
+                       PGresult *res = php_pq_exec(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_pq_clear_res(res);
                        }
  
 -                      php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC);
 +                      php_pqconn_notify_listeners(obj->intern->conn);
                }
        }
  }
@@@ -599,13 -621,13 +599,13 @@@ static PHP_METHOD(pqtxn, importSnapshot
                                smart_str_appends(&cmd, sid);
                                smart_str_0(&cmd);
  
-                               res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd));
 -                              res = php_pq_exec(obj->intern->conn->intern->conn, cmd.c);
++                              res = php_pq_exec(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);
+                                       php_pq_clear_res(res);
                                }
  
                                smart_str_free(&cmd);
@@@ -731,10 -754,11 +731,10 @@@ static PHP_METHOD(pqtxn, createLOB) 
  
                                        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);
                                }
                        }
  
@@@ -230,17 -275,17 +230,17 @@@ static PHP_METHOD(pqtypes, refresh) 
                        PGresult *res;
  
                        if (!nsp || !zend_hash_num_elements(nsp)) {
-                               res = PQexec(obj->intern->conn->intern->conn, PHP_PQ_TYPES_QUERY " and nspname in ('public', 'pg_catalog')");
+                               res = php_pq_exec(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);
++                              zend_hash_apply_with_arguments(nsp, apply_nsp, 2, params, &str);
                                smart_str_appendc(&str, ')');
                                smart_str_0(&str);
  
-                               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);
 -                              res = php_pq_exec_params(obj->intern->conn->intern->conn, str.c, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0);
++                              res = php_pq_exec_params(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(&params);
                                        }
                                }
  
-                               PHP_PQclear(res);
+                               php_pq_clear_res(res);
 -                              php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC);
 +                              php_pqconn_notify_listeners(obj->intern->conn);
                        }
                }
        }
@@@ -293,7 -338,7 +293,7 @@@ PHP_MINIT_FUNCTION(pqtypes
        php_pqtypes_class_entry->create_object = php_pqtypes_create_object;
  
        /*
--      zend_class_implements(php_pqtypes_class_entry TSRMLS_CC, 1, zend_ce_arrayaccess);
++      zend_class_implements(php_pqtypes_class_entry, 1, zend_ce_arrayaccess);
        */
  
        memcpy(&php_pqtypes_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));