From 47a56359523da57ec619c4dab5027553fa54631d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sun, 14 Mar 2021 17:05:43 +0100 Subject: [PATCH 01/14] Convert resources to objects in ext/pgsql --- NEWS | 6 + UPGRADING | 14 + ext/pgsql/pgsql.c | 1114 +++++++++-------- ext/pgsql/pgsql.stub.php | 383 ++---- ext/pgsql/pgsql_arginfo.h | 164 ++- ext/pgsql/php_pgsql.h | 113 +- ext/pgsql/tests/00version.phpt | 1 - ext/pgsql/tests/02connection.phpt | 3 +- ext/pgsql/tests/12pg_insert_9.phpt | 2 +- ext/pgsql/tests/13pg_select_9.phpt | 1 + ext/pgsql/tests/17result.phpt | 4 +- ext/pgsql/tests/22pg_fetch_object.phpt | 4 +- .../tests/28large_object_import_oid.phpt | 2 +- ext/pgsql/tests/80_bug36625.phpt | 3 +- ext/pgsql/tests/bug60244.phpt | 4 +- ext/pgsql/tests/bug72197.phpt | 2 +- ext/pgsql/tests/no_link_open.phpt | 2 +- ext/pgsql/tests/skipif.inc | 2 +- 18 files changed, 887 insertions(+), 937 deletions(-) diff --git a/NEWS b/NEWS index 71b40db355132..2f80c442e4f5a 100644 --- a/NEWS +++ b/NEWS @@ -98,6 +98,12 @@ PHP NEWS . PDO SQLite: . Fixed bug #38334 (Proper data-type support for PDO_SQLITE). (Nikita) +- PgSQL: + . Convert resource to object \PgSql. (Máté) + . Convert resource to object \PgSqlResult. (Máté) + . Convert resource to object \PgSqlLob. (Máté) + . Convert resource to object \PgsqlString. (Máté) + - PSpell: . Convert resource to object \PSpell\Dictionary. (Sara) . Convert resource to object \PSpell\Config. (Sara) diff --git a/UPGRADING b/UPGRADING index 318d91e791ef0..ec0f59e1a8cdd 100644 --- a/UPGRADING +++ b/UPGRADING @@ -120,6 +120,20 @@ PHP 8.1 UPGRADE NOTES types. You can restore the previous behavior by enabling the PDO::ATTR_STRINGIFY_FETCHES option. +- PgSQL: + . The PgSQL functions now accept and return, respectively, PgSql objects + instead of "pgsql link" resources. Return value checks using is_resource() + should be replaced with checks for `false`. + . The PgSQL functions now accept and return, respectively, PgSqlResult + objects instead of "pgsql result" resources. Return value checks using + is_resource() should be replaced with checks for `false`. + . The PgSQL functions now accept and return, respectively, PgSqlLob + objects instead of "pgsql large object" resources. Return value checks + using is_resource() should be replaced with checks for `false`. + . The PgSQL functions now accept and return, respectively, PgSqlString + objects instead of "pgsql string" resources. Return value checks + using is_resource() should be replaced with checks for `false`. + - PSpell: . The PSpell functions now accept and return, respectively, PSpell\Dictionary objects instead of "pspell" resources. Return value checks using is_resource() diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index e2694430953a1..3b127204fe52b 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -39,6 +39,7 @@ #include "php_pgsql.h" #include "php_globals.h" #include "zend_exceptions.h" +#include "Zend/zend_interfaces.h" #include "pgsql_arginfo.h" #ifdef HAVE_PGSQL @@ -74,10 +75,28 @@ #define CHECK_DEFAULT_LINK(x) \ if ((x) == NULL) { \ - zend_throw_error(NULL, "No PostgreSQL link opened yet"); \ + zend_throw_error(NULL, "No PostgreSQL connection opened yet"); \ + RETURN_THROWS(); \ + } +#define FETCH_DEFAULT_LINK() (PGG(default_link) ? pgsql_link_from_obj(Z_OBJ_P(PGG(default_link))) : NULL) + +#define CHECK_PGSQL_LINK(link_handle) \ + if (link_handle->conn == NULL) { \ + zend_throw_error(NULL, "PostgreSQL connection has already been closed"); \ + RETURN_THROWS(); \ + } + +#define CHECK_PGSQL_RESULT(result_handle) \ + if (result_handle->result == NULL) { \ + zend_throw_error(NULL, "PostgreSQL result has already been closed"); \ + RETURN_THROWS(); \ + } + +#define CHECK_PGSQL_LOB(lob) \ + if (lob->conn == NULL) { \ + zend_throw_error(NULL, "PostgreSQL large object has already been closed"); \ RETURN_THROWS(); \ } -#define FETCH_DEFAULT_LINK() PGG(default_link) #ifndef HAVE_PQFREEMEM #define PQfreemem free @@ -112,6 +131,129 @@ ZEND_TSRMLS_CACHE_DEFINE() ZEND_GET_MODULE(pgsql) #endif +static int le_plink; + +static zend_class_entry *pgsql_link_ce, *pgsql_result_ce, *pgsql_lob_ce; +static zend_object_handlers pgsql_link_object_handlers, pgsql_result_object_handlers, pgsql_lob_object_handlers; + +static inline pgsql_link_handle *pgsql_link_from_obj(zend_object *obj) { + return (pgsql_link_handle *)((char *)(obj) - XtOffsetOf(pgsql_link_handle, std)); +} + +#define Z_PGSQL_LINK_P(zv) pgsql_link_from_obj(Z_OBJ_P(zv)) + +static zend_object *pgsql_link_create_object(zend_class_entry *class_type) { + pgsql_link_handle *intern = zend_object_alloc(sizeof(pgsql_link_handle), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &pgsql_link_object_handlers; + + return &intern->std; +} + +static zend_function *pgsql_link_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct PgSql, use pg_connect() or pg_pconnect() instead"); + return NULL; +} + +static void pgsql_link_free(pgsql_link_handle *link) +{ + PGresult *res; + zval *hash; + + while ((res = PQgetResult(link->conn))) { + PQclear(res); + } + PQfinish(link->conn); + PGG(num_links)--; + + /* Remove connection hash for this link */ + hash = zend_hash_index_find(&PGG(hashes), (uintptr_t) link->conn); + if (hash) { + zend_hash_index_del(&PGG(hashes), (uintptr_t) link->conn); + zend_hash_del(&PGG(regular_list), Z_STR_P(hash)); + } + + link->conn = NULL; +} + +static void pgsql_link_free_obj(zend_object *obj) +{ + pgsql_link_handle *link = pgsql_link_from_obj(obj); + + if (link->conn) { + pgsql_link_free(link); + } + + zend_object_std_dtor(&link->std); +} + +static inline pgsql_result_handle *pgsql_result_from_obj(zend_object *obj) { + return (pgsql_result_handle *)((char *)(obj) - XtOffsetOf(pgsql_result_handle, std)); +} + +#define Z_PGSQL_RESULT_P(zv) pgsql_result_from_obj(Z_OBJ_P(zv)) + +static zend_object *pgsql_result_create_object(zend_class_entry *class_type) { + pgsql_result_handle *intern = zend_object_alloc(sizeof(pgsql_result_handle), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &pgsql_result_object_handlers; + + return &intern->std; +} + +static zend_function *pgsql_result_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct PgSqlResult, use a dedicated function instead"); + return NULL; +} + +static void pgsql_result_free(pgsql_result_handle *pg_result) +{ + PQclear(pg_result->result); + pg_result->result = NULL; +} + +static void pgsql_result_free_obj(zend_object *obj) +{ + pgsql_result_handle *pg_result = pgsql_result_from_obj(obj); + + if (pg_result->result) { + pgsql_result_free(pg_result); + } + + zend_object_std_dtor(&pg_result->std); +} + +static inline pgLofp *pgsql_lob_from_obj(zend_object *obj) { + return (pgLofp *)((char *)(obj) - XtOffsetOf(pgLofp, std)); +} + +#define Z_PGSQL_LOB_P(zv) pgsql_lob_from_obj(Z_OBJ_P(zv)) + +static zend_object *pgsql_lob_create_object(zend_class_entry *class_type) { + pgLofp *intern = zend_object_alloc(sizeof(pgLofp), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &pgsql_lob_object_handlers; + + return &intern->std; +} + +static zend_function *pgsql_lob_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct PgSqlLob, use pg_lo_open() instead"); + return NULL; +} + +static void pgsql_lob_free_obj(zend_object *obj) +{ + pgLofp *lofp = pgsql_lob_from_obj(obj); + + zend_object_std_dtor(&lofp->std); +} static int le_link, le_plink, le_result, le_lofp; /* Compatibility definitions */ @@ -139,42 +281,17 @@ static zend_string *_php_pgsql_trim_message(const char *message) zend_string_release(msgbuf); \ } \ -/* {{{ php_pgsql_set_default_link */ -static void php_pgsql_set_default_link(zend_resource *res) +static void php_pgsql_set_default_link(zval *link) { - GC_ADDREF(res); + GC_ADDREF(Z_OBJ_P(link)); if (PGG(default_link) != NULL) { - zend_list_delete(PGG(default_link)); + pgsql_link_free(FETCH_DEFAULT_LINK()); } - PGG(default_link) = res; + PGG(default_link) = link; } -/* }}} */ -/* {{{ _close_pgsql_link */ -static void _close_pgsql_link(zend_resource *rsrc) -{ - PGconn *link = (PGconn *)rsrc->ptr; - PGresult *res; - zval *hash; - - while ((res = PQgetResult(link))) { - PQclear(res); - } - PQfinish(link); - PGG(num_links)--; - - /* Remove connection hash for this link */ - hash = zend_hash_index_find(&PGG(hashes), (uintptr_t) link); - if (hash) { - zend_hash_index_del(&PGG(hashes), (uintptr_t) link); - zend_hash_del(&EG(regular_list), Z_STR_P(hash)); - } -} -/* }}} */ - -/* {{{ _close_pgsql_plink */ static void _close_pgsql_plink(zend_resource *rsrc) { PGconn *link = (PGconn *)rsrc->ptr; @@ -187,9 +304,7 @@ static void _close_pgsql_plink(zend_resource *rsrc) PGG(num_persistent)--; PGG(num_links)--; } -/* }}} */ -/* {{{ _php_pgsql_notice_handler */ static void _php_pgsql_notice_handler(void *resource_id, const char *message) { if (PGG(ignore_notices)) { @@ -210,9 +325,7 @@ static void _php_pgsql_notice_handler(void *resource_id, const char *message) } add_next_index_str(notices, trimmed_message); } -/* }}} */ -/* {{{ _rollback_transactions */ static int _rollback_transactions(zval *el) { PGconn *link; @@ -242,25 +355,12 @@ static int _rollback_transactions(zval *el) return 0; } -/* }}} */ -/* {{{ _free_ptr */ static void _free_ptr(zend_resource *rsrc) { pgLofp *lofp = (pgLofp *)rsrc->ptr; efree(lofp); } -/* }}} */ - -/* {{{ _free_result */ -static void _free_result(zend_resource *rsrc) -{ - pgsql_result_handle *pg_result = (pgsql_result_handle *)rsrc->ptr; - - PQclear(pg_result->result); - efree(pg_result); -} -/* }}} */ static void release_string(zval *zv) { @@ -289,7 +389,6 @@ static bool _php_pgsql_identifier_is_escaped(const char *identifier, size_t len) /* Escaped properly */ return true; } -/* }}} */ /* {{{ PHP_INI */ PHP_INI_BEGIN() @@ -300,9 +399,7 @@ STD_PHP_INI_BOOLEAN( "pgsql.auto_reset_persistent", "0", PHP_INI_SYSTEM, OnUpda STD_PHP_INI_BOOLEAN( "pgsql.ignore_notice", "0", PHP_INI_ALL, OnUpdateBool, ignore_notices, zend_pgsql_globals, pgsql_globals) STD_PHP_INI_BOOLEAN( "pgsql.log_notice", "0", PHP_INI_ALL, OnUpdateBool, log_notices, zend_pgsql_globals, pgsql_globals) PHP_INI_END() -/* }}} */ -/* {{{ PHP_GINIT_FUNCTION */ static PHP_GINIT_FUNCTION(pgsql) { #if defined(COMPILE_DL_PGSQL) && defined(ZTS) @@ -312,8 +409,8 @@ static PHP_GINIT_FUNCTION(pgsql) /* Initialize notice message hash at MINIT only */ zend_hash_init(&pgsql_globals->notices, 0, NULL, ZVAL_PTR_DTOR, 1); zend_hash_init(&pgsql_globals->hashes, 0, NULL, ZVAL_PTR_DTOR, 1); + zend_hash_init(&pgsql_globals->regular_list, 0, NULL, ZVAL_PTR_DTOR, 1); } -/* }}} */ static void php_libpq_version(char *buf, size_t len) { @@ -329,17 +426,50 @@ static void php_libpq_version(char *buf, size_t len) } } -/* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(pgsql) { char buf[16]; REGISTER_INI_ENTRIES(); - le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number); le_plink = zend_register_list_destructors_ex(NULL, _close_pgsql_plink, "pgsql link persistent", module_number); - le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number); - le_lofp = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql large object", module_number); + + pgsql_link_ce = register_class_PgSql(); + pgsql_link_ce->create_object = pgsql_link_create_object; + pgsql_link_ce->serialize = zend_class_serialize_deny; + pgsql_link_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&pgsql_link_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + pgsql_link_object_handlers.offset = XtOffsetOf(pgsql_link_handle, std); + pgsql_link_object_handlers.free_obj = pgsql_link_free_obj; + pgsql_link_object_handlers.get_constructor = pgsql_link_get_constructor; + pgsql_link_object_handlers.clone_obj = NULL; + pgsql_link_object_handlers.compare = zend_objects_not_comparable; + + pgsql_result_ce = register_class_PgSqlResult(); + pgsql_result_ce->create_object = pgsql_result_create_object; + pgsql_result_ce->serialize = zend_class_serialize_deny; + pgsql_result_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&pgsql_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + pgsql_result_object_handlers.offset = XtOffsetOf(pgsql_result_handle, std); + pgsql_result_object_handlers.free_obj = pgsql_result_free_obj; + pgsql_result_object_handlers.get_constructor = pgsql_result_get_constructor; + pgsql_result_object_handlers.clone_obj = NULL; + pgsql_result_object_handlers.compare = zend_objects_not_comparable; + + pgsql_lob_ce = register_class_PgSqlLob(); + pgsql_lob_ce->create_object = pgsql_lob_create_object; + pgsql_lob_ce->serialize = zend_class_serialize_deny; + pgsql_lob_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&pgsql_lob_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + pgsql_lob_object_handlers.offset = XtOffsetOf(pgLofp, std); + pgsql_lob_object_handlers.free_obj = pgsql_lob_free_obj; + pgsql_lob_object_handlers.get_constructor = pgsql_lob_get_constructor; + pgsql_lob_object_handlers.clone_obj = NULL; + pgsql_lob_object_handlers.compare = zend_objects_not_comparable; + /* libpq version */ php_libpq_version(buf, sizeof(buf)); REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION", buf, CONST_CS | CONST_PERSISTENT); @@ -445,20 +575,17 @@ PHP_MINIT_FUNCTION(pgsql) REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT); return SUCCESS; } -/* }}} */ -/* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(pgsql) { UNREGISTER_INI_ENTRIES(); zend_hash_destroy(&PGG(notices)); zend_hash_destroy(&PGG(hashes)); + zend_hash_destroy(&PGG(regular_list)); return SUCCESS; } -/* }}} */ -/* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(pgsql) { PGG(default_link) = NULL; @@ -467,9 +594,7 @@ PHP_RINIT_FUNCTION(pgsql) zend_hash_init(&PGG(table_oids), 0, NULL, release_string, 0); return SUCCESS; } -/* }}} */ -/* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(pgsql) { /* clean up notice messages */ @@ -477,13 +602,12 @@ PHP_RSHUTDOWN_FUNCTION(pgsql) zend_hash_clean(&PGG(hashes)); zend_hash_destroy(&PGG(field_oids)); zend_hash_destroy(&PGG(table_oids)); + zend_hash_clean(&PGG(regular_list)); /* clean up persistent connection */ zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions); return SUCCESS; } -/* }}} */ -/* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(pgsql) { char buf[256]; @@ -505,13 +629,12 @@ PHP_MINFO_FUNCTION(pgsql) DISPLAY_INI_ENTRIES(); } -/* }}} */ -/* {{{ php_pgsql_do_connect */ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) { char *connstring; size_t connstring_len; + pgsql_link_handle *link; PGconn *pgsql; smart_str str = {0}; zend_long connect_type = 0; @@ -581,7 +704,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) PQreset(le->ptr); } if (le->ptr == NULL || PQstatus(le->ptr) == CONNECTION_BAD) { - php_error_docref(NULL, E_WARNING,"PostgreSQL link lost, unable to reconnect"); + php_error_docref(NULL, E_WARNING,"PostgreSQL connection lost, unable to reconnect"); zend_hash_del(&EG(persistent_list), str.s); goto err; } @@ -593,9 +716,12 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) PQclear(pg_result); } } - RETVAL_RES(zend_register_resource(pgsql, le_plink)); + + object_init_ex(return_value, pgsql_link_ce); + link = Z_PGSQL_LINK_P(return_value); + link->conn = pgsql; } else { /* Non persistent connection */ - zend_resource *index_ptr, new_index_ptr; + zval *index_ptr, new_index_ptr; /* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual pgsql link sits. @@ -603,18 +729,11 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) * and add a pointer to it with hashed_details as the key. */ if (!(connect_type & PGSQL_CONNECT_FORCE_NEW) - && (index_ptr = zend_hash_find_ptr(&EG(regular_list), str.s)) != NULL) { - zend_resource *link; + && (index_ptr = zend_hash_find_ptr(&PGG(regular_list), str.s)) != NULL) { + php_pgsql_set_default_link(index_ptr); + GC_ADDREF(Z_OBJ_P(index_ptr)); + ZVAL_COPY(return_value, index_ptr); - if (index_ptr->type != le_index_ptr) { - goto err; - } - - link = (zend_resource *)index_ptr->ptr; - ZEND_ASSERT(link->ptr && (link->type == le_link || link->type == le_plink)); - php_pgsql_set_default_link(link); - GC_ADDREF(link); - RETVAL_RES(link); goto cleanup; } if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) { @@ -643,13 +762,13 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) } } - /* add it to the list */ - RETVAL_RES(zend_register_resource(pgsql, le_link)); + object_init_ex(return_value, pgsql_link_ce); + link = Z_PGSQL_LINK_P(return_value); + link->conn = pgsql; /* add it to the hash */ - new_index_ptr.ptr = (void *) Z_RES_P(return_value); - new_index_ptr.type = le_index_ptr; - zend_hash_update_mem(&EG(regular_list), str.s, (void *) &new_index_ptr, sizeof(zend_resource)); + ZVAL_COPY(&new_index_ptr, return_value); + zend_hash_update_mem(&PGG(regular_list), str.s, (void *) &new_index_ptr, sizeof(zval)); /* Keep track of link => hash mapping, so we can remove the hash entry from regular_list * when the connection is closed. This uses the address of the connection rather than the @@ -663,10 +782,10 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) PGG(num_links)++; } /* set notice processor */ - if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_RESOURCE) { - PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)(zend_uintptr_t)Z_RES_HANDLE_P(return_value)); + if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_OBJECT) { + PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)(zend_uintptr_t)Z_OBJ_P(return_value)->handle); } - php_pgsql_set_default_link(Z_RES_P(return_value)); + php_pgsql_set_default_link(return_value); cleanup: smart_str_free(&str); @@ -689,16 +808,17 @@ PHP_FUNCTION(pg_connect) PHP_FUNCTION(pg_connect_poll) { zval *pgsql_link; + pgsql_link_handle *pgsql_handle; PGconn *pgsql; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql_handle = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(pgsql_handle); + pgsql = pgsql_handle->conn; ret = PQconnectPoll(pgsql); @@ -717,30 +837,27 @@ PHP_FUNCTION(pg_pconnect) PHP_FUNCTION(pg_close) { zval *pgsql_link = NULL; - zend_resource *link; + pgsql_link_handle *link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } if (!pgsql_link) { - link = PGG(default_link); + link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); - zend_list_delete(link); + pgsql_link_free(link); PGG(default_link) = NULL; RETURN_TRUE; } - link = Z_RES_P(pgsql_link); - if (zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); - if (link == PGG(default_link)) { - zend_list_delete(link); + if (link == FETCH_DEFAULT_LINK()) { PGG(default_link) = NULL; } - zend_list_close(link); + pgsql_link_free(link); RETURN_TRUE; } @@ -754,15 +871,15 @@ PHP_FUNCTION(pg_close) #define PHP_PG_HOST 6 #define PHP_PG_VERSION 7 -/* {{{ php_pgsql_get_link_info */ +/* php_pgsql_get_link_info */ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { - zend_resource *link; + pgsql_link_handle *link; zval *pgsql_link = NULL; PGconn *pgsql; char *result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } @@ -770,12 +887,11 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; switch(entry_type) { case PHP_PG_DBNAME: @@ -830,67 +946,59 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type RETURN_EMPTY_STRING(); } } -/* }}} */ -/* {{{ Get the database name */ +/* Get the database name */ PHP_FUNCTION(pg_dbname) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_DBNAME); } -/* }}} */ -/* {{{ Get the error message string */ +/* Get the error message string */ PHP_FUNCTION(pg_last_error) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_ERROR_MESSAGE); } -/* }}} */ -/* {{{ Get the options associated with the connection */ +/* Get the options associated with the connection */ PHP_FUNCTION(pg_options) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_OPTIONS); } -/* }}} */ -/* {{{ Return the port number associated with the connection */ +/* Return the port number associated with the connection */ PHP_FUNCTION(pg_port) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_PORT); } -/* }}} */ -/* {{{ Return the tty name associated with the connection */ +/* Return the tty name associated with the connection */ PHP_FUNCTION(pg_tty) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_TTY); } -/* }}} */ -/* {{{ Returns the host name associated with the connection */ +/* Returns the host name associated with the connection */ PHP_FUNCTION(pg_host) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_HOST); } -/* }}} */ -/* {{{ Returns an array with client, protocol and server version (when available) */ +/* Returns an array with client, protocol and server version (when available) */ PHP_FUNCTION(pg_version) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_VERSION); } -/* }}} */ -/* {{{ Returns the value of a server parameter */ +/* Returns the value of a server parameter */ PHP_FUNCTION(pg_parameter_status) { zval *pgsql_link = NULL; - zend_resource *link; + pgsql_link_handle *link; PGconn *pgsql; char *param; size_t len; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "rs", &pgsql_link, ¶m, &len) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "Os", &pgsql_link, pgsql_link_ce, ¶m, &len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", ¶m, &len) == FAILURE) { RETURN_THROWS(); } @@ -898,12 +1006,11 @@ PHP_FUNCTION(pg_parameter_status) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; param = (char*)PQparameterStatus(pgsql, param); if (param) { @@ -912,17 +1019,16 @@ PHP_FUNCTION(pg_parameter_status) RETURN_FALSE; } } -/* }}} */ -/* {{{ Ping database. If connection is bad, try to reconnect. */ +/* Ping database. If connection is bad, try to reconnect. */ PHP_FUNCTION(pg_ping) { zval *pgsql_link = NULL; PGconn *pgsql; PGresult *res; - zend_resource *link; + pgsql_link_handle *link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } @@ -930,12 +1036,11 @@ PHP_FUNCTION(pg_ping) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; /* ping connection */ res = PQexec(pgsql, "SELECT 1;"); @@ -952,16 +1057,15 @@ PHP_FUNCTION(pg_ping) } RETURN_FALSE; } -/* }}} */ -/* {{{ Execute a query */ +/* Execute a query */ PHP_FUNCTION(pg_query) { zval *pgsql_link = NULL; char *query; size_t query_len; int leftover = 0; - zend_resource *link; + pgsql_link_handle *link; PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; @@ -973,15 +1077,14 @@ PHP_FUNCTION(pg_query) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pgsql_link, pgsql_link_ce, &query, &query_len) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (PQsetnonblocking(pgsql, 0)) { php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); @@ -1019,11 +1122,11 @@ PHP_FUNCTION(pg_query) case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { - pgsql_result_handle *pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle)); + object_init_ex(return_value, pgsql_result_ce); + pgsql_result_handle *pg_result = Z_PGSQL_RESULT_P(return_value); pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -1031,9 +1134,7 @@ PHP_FUNCTION(pg_query) break; } } -/* }}} */ -/* {{{ _php_pgsql_free_params */ static void _php_pgsql_free_params(char **params, int num_params) { if (num_params > 0) { @@ -1046,9 +1147,8 @@ static void _php_pgsql_free_params(char **params, int num_params) efree(params); } } -/* }}} */ -/* {{{ Execute a query */ +/* Execute a query */ PHP_FUNCTION(pg_query_params) { zval *pgsql_link = NULL; @@ -1058,7 +1158,7 @@ PHP_FUNCTION(pg_query_params) int leftover = 0; int num_params = 0; char **params = NULL; - zend_resource *link; + pgsql_link_handle *link; PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; @@ -1071,15 +1171,14 @@ PHP_FUNCTION(pg_query_params) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osa", &pgsql_link, pgsql_link_ce, &query, &query_len, &pv_param_arr) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (PQsetnonblocking(pgsql, 0)) { php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); @@ -1144,11 +1243,11 @@ PHP_FUNCTION(pg_query_params) case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { - pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle)); + object_init_ex(return_value, pgsql_result_ce); + pg_result = Z_PGSQL_RESULT_P(return_value); pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -1156,9 +1255,8 @@ PHP_FUNCTION(pg_query_params) break; } } -/* }}} */ -/* {{{ Prepare a query for future execution */ +/* Prepare a query for future execution */ PHP_FUNCTION(pg_prepare) { zval *pgsql_link = NULL; @@ -1166,7 +1264,7 @@ PHP_FUNCTION(pg_prepare) size_t query_len, stmtname_len; int leftover = 0; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; PGresult *pgsql_result; ExecStatusType status; pgsql_result_handle *pg_result; @@ -1178,15 +1276,14 @@ PHP_FUNCTION(pg_prepare) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oss", &pgsql_link, pgsql_link_ce, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (PQsetnonblocking(pgsql, 0)) { php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); @@ -1224,11 +1321,11 @@ PHP_FUNCTION(pg_prepare) case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { - pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle)); + object_init_ex(return_value, pgsql_result_ce); + pg_result = Z_PGSQL_RESULT_P(return_value); pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -1236,9 +1333,8 @@ PHP_FUNCTION(pg_prepare) break; } } -/* }}} */ -/* {{{ Execute a prepared query */ +/* Execute a prepared query */ PHP_FUNCTION(pg_execute) { zval *pgsql_link = NULL; @@ -1249,7 +1345,7 @@ PHP_FUNCTION(pg_execute) int num_params = 0; char **params = NULL; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; PGresult *pgsql_result; ExecStatusType status; pgsql_result_handle *pg_result; @@ -1261,15 +1357,14 @@ PHP_FUNCTION(pg_execute) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osa", &pgsql_link, pgsql_link_ce, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (PQsetnonblocking(pgsql, 0)) { php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); @@ -1333,11 +1428,11 @@ PHP_FUNCTION(pg_execute) case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { - pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle)); + object_init_ex(return_value, pgsql_result_ce); + pg_result = Z_PGSQL_RESULT_P(return_value); pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -1345,27 +1440,24 @@ PHP_FUNCTION(pg_execute) break; } } -/* }}} */ #define PHP_PG_NUM_ROWS 1 #define PHP_PG_NUM_FIELDS 2 #define PHP_PG_CMD_TUPLES 3 -/* {{{ php_pgsql_get_result_info */ +/* php_pgsql_get_result_info */ static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { zval *result; PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { - RETURN_THROWS(); - } - - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &result, pgsql_result_ce) == FAILURE) { RETURN_THROWS(); } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; switch (entry_type) { @@ -1381,47 +1473,43 @@ static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_ty EMPTY_SWITCH_DEFAULT_CASE() } } -/* }}} */ -/* {{{ Return the number of rows in the result */ +/* Return the number of rows in the result */ PHP_FUNCTION(pg_num_rows) { php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_NUM_ROWS); } -/* }}} */ -/* {{{ Return the number of fields in the result */ +/* Return the number of fields in the result */ PHP_FUNCTION(pg_num_fields) { php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_NUM_FIELDS); } -/* }}} */ -/* {{{ Returns the number of affected tuples */ +/* Returns the number of affected tuples */ PHP_FUNCTION(pg_affected_rows) { php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_CMD_TUPLES); } -/* }}} */ -/* {{{ Returns the last notice set by the backend */ +/* Returns the last notice set by the backend */ PHP_FUNCTION(pg_last_notice) { zval *pgsql_link = NULL; zval *notice, *notices; + pgsql_link_handle *link; PGconn *pg_link; zend_long option = PGSQL_NOTICE_LAST; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pgsql_link, &option) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &pgsql_link, pgsql_link_ce, &option) == FAILURE) { RETURN_THROWS(); } - /* Just to check if user passed valid resoruce */ - if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pg_link = link->conn; - notices = zend_hash_index_find(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link)); + notices = zend_hash_index_find(&PGG(notices), (zend_ulong) Z_OBJ_P(pgsql_link)->handle); switch (option) { case PGSQL_NOTICE_LAST: if (notices) { @@ -1454,7 +1542,6 @@ PHP_FUNCTION(pg_last_notice) } RETURN_FALSE; } -/* }}} */ static inline bool is_valid_oid_string(zend_string *oid, Oid *return_oid) { @@ -1463,7 +1550,6 @@ static inline bool is_valid_oid_string(zend_string *oid, Oid *return_oid) return ZSTR_VAL(oid) + ZSTR_LEN(oid) == end_ptr; } -/* {{{ get_field_name */ static zend_string *get_field_name(PGconn *pgsql, Oid oid) { zend_string *ret = zend_hash_index_find_ptr(&PGG(field_oids), oid); @@ -1507,9 +1593,8 @@ static zend_string *get_field_name(PGconn *pgsql, Oid oid) PQclear(result); return ret; } -/* }}} */ -/* {{{ Returns the name of the table field belongs to, or table's oid if oid_only is true */ +/* Returns the name of the table field belongs to, or table's oid if oid_only is true */ PHP_FUNCTION(pg_field_table) { zval *result; @@ -1517,13 +1602,12 @@ PHP_FUNCTION(pg_field_table) zend_long fnum = -1; bool return_oid = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|b", &result, &fnum, &return_oid) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol|b", &result, pgsql_result_ce, &fnum, &return_oid) == FAILURE) { RETURN_THROWS(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); if (fnum < 0) { zend_argument_value_error(2, "must be greater than or equal to 0"); @@ -1592,13 +1676,12 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ pgsql_result_handle *pg_result; Oid oid; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result, &field) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &result, pgsql_result_ce, &field) == FAILURE) { RETURN_THROWS(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); if (field < 0) { zend_argument_value_error(2, "must be greater than or equal to 0"); @@ -1669,14 +1752,12 @@ PHP_FUNCTION(pg_field_num) PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &result, &field, &field_len) == FAILURE) { - RETURN_THROWS(); - } - - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &result, pgsql_result_ce, &field, &field_len) == FAILURE) { RETURN_THROWS(); } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; RETURN_LONG(PQfnumber(pgsql_result, field)); @@ -1718,22 +1799,21 @@ PHP_FUNCTION(pg_fetch_result) if (ZEND_NUM_ARGS() == 2) { ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(result) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) Z_PARAM_STR_OR_LONG(field_name, field_offset) ZEND_PARSE_PARAMETERS_END(); } else { ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_RESOURCE(result) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) Z_PARAM_LONG(row) Z_PARAM_STR_OR_LONG(field_name, field_offset) ZEND_PARSE_PARAMETERS_END(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } - + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; + if (ZEND_NUM_ARGS() == 2) { if (pg_result->row < 0) { pg_result->row = 0; @@ -1784,7 +1864,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ zend_class_entry *ce = NULL; if (into_object) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l!Ca", &result, &row, &row_is_null, &ce, &ctor_params) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l!Ca", &result, pgsql_result_ce, &row, &row_is_null, &ce, &ctor_params) == FAILURE) { RETURN_THROWS(); } if (!ce) { @@ -1792,7 +1872,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ } result_type = PGSQL_ASSOC; } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l!l", &result, &row, &row_is_null, &result_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l!l", &result, pgsql_result_ce, &row, &row_is_null, &result_type) == FAILURE) { RETURN_THROWS(); } } @@ -1807,10 +1887,8 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ RETURN_THROWS(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } - + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; if (!row_is_null) { @@ -1951,7 +2029,7 @@ PHP_FUNCTION(pg_fetch_all) PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &result, &result_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &result, pgsql_result_ce, &result_type) == FAILURE) { RETURN_THROWS(); } @@ -1960,11 +2038,10 @@ PHP_FUNCTION(pg_fetch_all) RETURN_THROWS(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } - + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; + array_init(return_value); php_pgsql_result2array(pgsql_result, return_value, result_type); } @@ -1980,13 +2057,12 @@ PHP_FUNCTION(pg_fetch_all_columns) int pg_numrows, pg_row; size_t num_fields; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &result, &colno) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &result, pgsql_result_ce, &colno) == FAILURE) { RETURN_THROWS(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); if (colno < 0) { zend_argument_value_error(2, "must be greater than or equal to 0"); @@ -2024,13 +2100,12 @@ PHP_FUNCTION(pg_result_seek) zend_long row; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result, &row) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &result, pgsql_result_ce, &row) == FAILURE) { RETURN_THROWS(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); if (row < 0 || row >= PQntuples(pg_result->result)) { RETURN_FALSE; @@ -2057,22 +2132,21 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) if (ZEND_NUM_ARGS() == 2) { ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(result) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) Z_PARAM_STR_OR_LONG(field_name, field_offset) ZEND_PARSE_PARAMETERS_END(); } else { ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_RESOURCE(result) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) Z_PARAM_LONG(row) Z_PARAM_STR_OR_LONG(field_name, field_offset) ZEND_PARSE_PARAMETERS_END(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } - + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; + if (ZEND_NUM_ARGS() == 2) { if (pg_result->row < 0) { pg_result->row = 0; @@ -2131,15 +2205,14 @@ PHP_FUNCTION(pg_free_result) zval *result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &result, pgsql_result_ce) == FAILURE) { RETURN_THROWS(); } - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { - RETURN_THROWS(); - } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); - zend_list_close(Z_RES_P(result)); + pgsql_result_free(pg_result); RETURN_TRUE; } /* }}} */ @@ -2152,15 +2225,14 @@ PHP_FUNCTION(pg_last_oid) pgsql_result_handle *pg_result; Oid oid; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { - RETURN_THROWS(); - } - - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &result, pgsql_result_ce) == FAILURE) { RETURN_THROWS(); } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; + oid = PQoidValue(pgsql_result); if (oid == InvalidOid) { RETURN_FALSE; @@ -2178,9 +2250,9 @@ PHP_FUNCTION(pg_trace) PGconn *pgsql; FILE *fp = NULL; php_stream *stream; - zend_resource *link; + pgsql_link_handle *link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|sr!", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|sO!", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } @@ -2188,12 +2260,11 @@ PHP_FUNCTION(pg_trace) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; stream = php_stream_open_wrapper(z_filename, mode, REPORT_ERRORS, NULL); @@ -2216,7 +2287,7 @@ PHP_FUNCTION(pg_untrace) { zval *pgsql_link = NULL; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pgsql_link) == FAILURE) { RETURN_THROWS(); @@ -2226,12 +2297,11 @@ PHP_FUNCTION(pg_untrace) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; PQuntrace(pgsql); RETURN_TRUE; @@ -2244,14 +2314,14 @@ PHP_FUNCTION(pg_lo_create) zval *pgsql_link = NULL, *oid = NULL; PGconn *pgsql; Oid pgsql_oid, wanted_oid = InvalidOid; - zend_resource *link; + pgsql_link_handle *link; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &pgsql_link, &oid) == FAILURE) { RETURN_THROWS(); } - /* Overloaded method uses default link if arg 1 is not a resource, set oid pointer */ - if ((ZEND_NUM_ARGS() == 1) && (Z_TYPE_P(pgsql_link) != IS_RESOURCE)) { + /* Overloaded method uses default link if arg 1 is not an object, set oid pointer */ + if ((ZEND_NUM_ARGS() == 1) && (Z_TYPE_P(pgsql_link) != IS_OBJECT)) { oid = pgsql_link; pgsql_link = NULL; } @@ -2259,13 +2329,12 @@ PHP_FUNCTION(pg_lo_create) if (pgsql_link == NULL) { link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); - } else if ((Z_TYPE_P(pgsql_link) == IS_RESOURCE)) { - link = Z_RES_P(pgsql_link); + } else if ((Z_TYPE_P(pgsql_link) == IS_OBJECT && instanceof_function(Z_OBJCE_P(pgsql_link), pgsql_link_ce))) { + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; } else { - link = NULL; - } - - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { + zend_argument_type_error(1, "must be of type PgSql when the connection is provided"); RETURN_THROWS(); } @@ -2316,25 +2385,27 @@ PHP_FUNCTION(pg_lo_unlink) zend_string *oid_string; PGconn *pgsql; Oid oid; - zend_resource *link; + pgsql_link_handle *link; /* accept string type since Oid type is unsigned int */ - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "rS", &pgsql_link, &oid_string) == SUCCESS) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OS", &pgsql_link, pgsql_link_ce, &oid_string) == SUCCESS) { if (!is_valid_oid_string(oid_string, &oid)) { /* wrong integer format */ zend_value_error("Invalid OID value passed"); RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "rl", &pgsql_link, &oid_long) == SUCCESS) { + "Ol", &pgsql_link, pgsql_link_ce, &oid_long) == SUCCESS) { if (oid_long <= (zend_long)InvalidOid) { zend_value_error("Invalid OID value passed"); RETURN_THROWS(); } oid = (Oid)oid_long; - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "S", &oid_string) == SUCCESS) { if (!is_valid_oid_string(oid_string, &oid)) { @@ -2360,9 +2431,7 @@ PHP_FUNCTION(pg_lo_unlink) RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (lo_unlink(pgsql, oid) == -1) { php_error_docref(NULL, E_WARNING, "Unable to delete PostgreSQL large object %u", oid); @@ -2384,26 +2453,28 @@ PHP_FUNCTION(pg_lo_open) int pgsql_mode=0, pgsql_lofd; bool create = false; pgLofp *pgsql_lofp; - zend_resource *link; + pgsql_link_handle *link; /* accept string type since Oid is unsigned int */ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "rSS", &pgsql_link, &oid_string, &mode) == SUCCESS) { + "OSS", &pgsql_link, pgsql_link_ce, &oid_string, &mode) == SUCCESS) { if (!is_valid_oid_string(oid_string, &oid)) { /* wrong integer format */ zend_value_error("Invalid OID value passed"); RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "rlS", &pgsql_link, &oid_long, &mode) == SUCCESS) { + "Ols", &pgsql_link, pgsql_link_ce, &oid_long, &mode) == SUCCESS) { if (oid_long <= (zend_long)InvalidOid) { zend_value_error("Invalid OID value passed"); RETURN_THROWS(); } oid = (Oid)oid_long; - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "SS", &oid_string, &mode) == SUCCESS) { @@ -2430,9 +2501,7 @@ PHP_FUNCTION(pg_lo_open) RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; /* r/w/+ is little bit more PHP-like than INV_READ/INV_WRITE and a lot of faster to type. Unfortunately, doesn't behave the same way as fopen()... @@ -2455,39 +2524,40 @@ PHP_FUNCTION(pg_lo_open) RETURN_THROWS(); } - pgsql_lofp = (pgLofp *) emalloc(sizeof(pgLofp)); + object_init_ex(return_value, pgsql_lob_ce); + pgsql_lofp = Z_PGSQL_LOB_P(return_value); if ((pgsql_lofd = lo_open(pgsql, oid, pgsql_mode)) == -1) { if (create) { if ((oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == 0) { - efree(pgsql_lofp); + zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Unable to create PostgreSQL large object"); RETURN_FALSE; } else { if ((pgsql_lofd = lo_open(pgsql, oid, pgsql_mode)) == -1) { if (lo_unlink(pgsql, oid) == -1) { - efree(pgsql_lofp); php_error_docref(NULL, E_WARNING, "Something is really messed up! Your database is badly corrupted in a way NOT related to PHP"); - RETURN_FALSE; + } else { + php_error_docref(NULL, E_WARNING, "Unable to open PostgreSQL large object"); } - efree(pgsql_lofp); - php_error_docref(NULL, E_WARNING, "Unable to open PostgreSQL large object"); + + zval_ptr_dtor(return_value); RETURN_FALSE; } else { pgsql_lofp->conn = pgsql; pgsql_lofp->lofd = pgsql_lofd; - RETURN_RES(zend_register_resource(pgsql_lofp, le_lofp)); + return; } } } else { - efree(pgsql_lofp); + zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Unable to open PostgreSQL large object"); RETURN_FALSE; } } else { pgsql_lofp->conn = pgsql; pgsql_lofp->lofd = pgsql_lofd; - RETURN_RES(zend_register_resource(pgsql_lofp, le_lofp)); + return; } } /* }}} */ @@ -2498,13 +2568,12 @@ PHP_FUNCTION(pg_lo_close) zval *pgsql_lofp; pgLofp *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_lofp) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_lofp, pgsql_lob_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_lofp), "PostgreSQL large object", le_lofp)) == NULL) { - RETURN_THROWS(); - } + pgsql = Z_PGSQL_LOB_P(pgsql_lofp); + CHECK_PGSQL_LOB(pgsql); if (lo_close((PGconn *)pgsql->conn, pgsql->lofd) < 0) { php_error_docref(NULL, E_WARNING, "Unable to close PostgreSQL large object descriptor %d", pgsql->lofd); @@ -2513,7 +2582,6 @@ PHP_FUNCTION(pg_lo_close) RETVAL_TRUE; } - zend_list_close(Z_RES_P(pgsql_lofp)); return; } /* }}} */ @@ -2529,13 +2597,12 @@ PHP_FUNCTION(pg_lo_read) zend_string *buf; pgLofp *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pgsql_id, &buffer_length) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &pgsql_id, pgsql_lob_ce, &buffer_length) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { - RETURN_THROWS(); - } + pgsql = Z_PGSQL_LOB_P(pgsql_id); + CHECK_PGSQL_LOB(pgsql); if (buffer_length < 0) { zend_argument_value_error(2, "must be greater or equal than 0"); @@ -2566,7 +2633,7 @@ PHP_FUNCTION(pg_lo_write) size_t len; pgLofp *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS|l!", &pgsql_id, &str, &z_len, &z_len_is_null) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS|l!", &pgsql_id, pgsql_lob_ce, &str, &z_len, &z_len_is_null) == FAILURE) { RETURN_THROWS(); } @@ -2585,9 +2652,8 @@ PHP_FUNCTION(pg_lo_write) len = ZSTR_LEN(str); } - if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { - RETURN_THROWS(); - } + pgsql = Z_PGSQL_LOB_P(pgsql_id); + CHECK_PGSQL_LOB(pgsql); if ((nbytes = lo_write((PGconn *)pgsql->conn, pgsql->lofd, ZSTR_VAL(str), len)) == (size_t)-1) { RETURN_FALSE; @@ -2606,13 +2672,12 @@ PHP_FUNCTION(pg_lo_read_all) char buf[PGSQL_LO_READ_BUF_SIZE]; pgLofp *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_id) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_id, pgsql_lob_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { - RETURN_THROWS(); - } + pgsql = Z_PGSQL_LOB_P(pgsql_id); + CHECK_PGSQL_LOB(pgsql); tbytes = 0; while ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, PGSQL_LO_READ_BUF_SIZE))>0) { @@ -2630,11 +2695,12 @@ PHP_FUNCTION(pg_lo_import) zend_string *file_in; PGconn *pgsql; Oid returned_oid; - zend_resource *link; + pgsql_link_handle *link; if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "rP|z", &pgsql_link, &file_in, &oid) == SUCCESS) { - link = Z_RES_P(pgsql_link); + "OP|z", &pgsql_link, pgsql_link_ce, &file_in, &oid) == SUCCESS) { + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "P|z", &file_in, &oid) == SUCCESS) { @@ -2649,9 +2715,7 @@ PHP_FUNCTION(pg_lo_import) RETURN_FALSE; } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (oid) { Oid wanted_oid; @@ -2704,26 +2768,28 @@ PHP_FUNCTION(pg_lo_export) zend_long oid_long; Oid oid; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; /* allow string to handle large OID value correctly */ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "rlP", &pgsql_link, &oid_long, &file_out) == SUCCESS) { + "rlP", &pgsql_link, pgsql_link_ce, &oid_long, &file_out) == SUCCESS) { if (oid_long <= (zend_long)InvalidOid) { zend_value_error("Invalid OID value passed"); RETURN_THROWS(); } oid = (Oid)oid_long; - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "rSP", &pgsql_link, &oid_string, &file_out) == SUCCESS) { + "OSP", &pgsql_link, pgsql_link_ce, &oid_string, &file_out) == SUCCESS) { if (!is_valid_oid_string(oid_string, &oid)) { /* wrong integer format */ zend_value_error("Invalid OID value passed"); RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "lP", &oid_long, &file_out) == SUCCESS) { @@ -2754,9 +2820,7 @@ PHP_FUNCTION(pg_lo_export) RETURN_FALSE; } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (lo_export(pgsql, oid, ZSTR_VAL(file_out)) == -1) { RETURN_FALSE; @@ -2772,7 +2836,7 @@ PHP_FUNCTION(pg_lo_seek) zend_long result, offset = 0, whence = SEEK_CUR; pgLofp *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|l", &pgsql_id, &offset, &whence) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol|l", &pgsql_id, pgsql_lob_ce, &offset, &whence) == FAILURE) { RETURN_THROWS(); } if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) { @@ -2780,9 +2844,8 @@ PHP_FUNCTION(pg_lo_seek) RETURN_THROWS(); } - if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { - RETURN_THROWS(); - } + pgsql = Z_PGSQL_LOB_P(pgsql_id); + CHECK_PGSQL_LOB(pgsql); #ifdef HAVE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { @@ -2808,13 +2871,12 @@ PHP_FUNCTION(pg_lo_tell) zend_long offset = 0; pgLofp *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_id) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_id, pgsql_lob_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { - RETURN_THROWS(); - } + pgsql = Z_PGSQL_LOB_P(pgsql_id); + CHECK_PGSQL_LOB(pgsql); #ifdef VE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { @@ -2837,13 +2899,12 @@ PHP_FUNCTION(pg_lo_truncate) pgLofp *pgsql; int result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pgsql_id, &size) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pgsql_id, pgsql_lob_ce, &size) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { - RETURN_THROWS(); - } + pgsql = Z_PGSQL_LOB_P(pgsql_id); + CHECK_PGSQL_LOB(pgsql); #ifdef VE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { @@ -2868,7 +2929,7 @@ PHP_FUNCTION(pg_set_error_verbosity) zval *pgsql_link = NULL; zend_long verbosity; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; if (ZEND_NUM_ARGS() == 1) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &verbosity) == FAILURE) { @@ -2877,15 +2938,14 @@ PHP_FUNCTION(pg_set_error_verbosity) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pgsql_link, &verbosity) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pgsql_link, pgsql_link_ce, &verbosity) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (verbosity & (PQERRORS_TERSE|PQERRORS_DEFAULT|PQERRORS_VERBOSE)) { RETURN_LONG(PQsetErrorVerbosity(pgsql, verbosity)); @@ -2902,7 +2962,7 @@ PHP_FUNCTION(pg_set_client_encoding) size_t encoding_len; zval *pgsql_link = NULL; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; if (ZEND_NUM_ARGS() == 1) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &encoding, &encoding_len) == FAILURE) { @@ -2911,15 +2971,14 @@ PHP_FUNCTION(pg_set_client_encoding) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pgsql_link, pgsql_link_ce, &encoding, &encoding_len) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; RETURN_LONG(PQsetClientEncoding(pgsql, encoding)); } @@ -2930,9 +2989,9 @@ PHP_FUNCTION(pg_client_encoding) { zval *pgsql_link = NULL; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } @@ -2940,12 +2999,11 @@ PHP_FUNCTION(pg_client_encoding) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; /* Just do the same as found in PostgreSQL sources... */ @@ -2959,9 +3017,9 @@ PHP_FUNCTION(pg_end_copy) zval *pgsql_link = NULL; PGconn *pgsql; int result = 0; - zend_resource *link; + pgsql_link_handle *link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } @@ -2969,12 +3027,11 @@ PHP_FUNCTION(pg_end_copy) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; result = PQendcopy(pgsql); @@ -2993,7 +3050,7 @@ PHP_FUNCTION(pg_put_line) size_t query_len; zval *pgsql_link = NULL; PGconn *pgsql; - zend_resource *link; + pgsql_link_handle *link; int result = 0; if (ZEND_NUM_ARGS() == 1) { @@ -3003,15 +3060,14 @@ PHP_FUNCTION(pg_put_line) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pgsql_link, pgsql_link_ce, &query, &query_len) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; result = PQputline(pgsql, query); if (result==EOF) { @@ -3026,6 +3082,7 @@ PHP_FUNCTION(pg_put_line) PHP_FUNCTION(pg_copy_to) { zval *pgsql_link; + pgsql_link_handle *link; zend_string *table_name; zend_string *pg_delimiter = NULL; char *pg_null_as = NULL; @@ -3037,14 +3094,15 @@ PHP_FUNCTION(pg_copy_to) ExecStatusType status; char *csv = (char *)NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rP|Ss", &pgsql_link, - &table_name, &pg_delimiter, &pg_null_as, pg_null_as_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP|Ss", &pgsql_link, pgsql_link_ce, + &table_name, &pg_delimiter, &pg_null_as, &pg_null_as_len) == FAILURE + ) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; if (!pg_delimiter) { pg_delimiter = ZSTR_CHAR('\t'); @@ -3120,6 +3178,7 @@ PHP_FUNCTION(pg_copy_to) PHP_FUNCTION(pg_copy_from) { zval *pgsql_link = NULL, *pg_rows; + pgsql_link_handle *link; zval *value; zend_string *table_name; zend_string *pg_delimiter = NULL; @@ -3131,15 +3190,15 @@ PHP_FUNCTION(pg_copy_from) PGresult *pgsql_result; ExecStatusType status; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rPa|Ss", &pgsql_link, - &table_name, &pg_rows, &pg_delimiter, &pg_null_as, - &pg_null_as_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|Ss", &pgsql_link, pgsql_link_ce, + &table_name, &pg_rows, &pg_delimiter, &pg_null_as, &pg_null_as_len) == FAILURE + ) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; if (!pg_delimiter) { pg_delimiter = ZSTR_CHAR('\t'); @@ -3228,7 +3287,7 @@ PHP_FUNCTION(pg_escape_string) { zend_string *from = NULL, *to = NULL; zval *pgsql_link; - zend_resource *link; + pgsql_link_handle *link; PGconn *pgsql; switch (ZEND_NUM_ARGS()) { @@ -3239,18 +3298,18 @@ PHP_FUNCTION(pg_escape_string) link = FETCH_DEFAULT_LINK(); break; default: - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &pgsql_link, &from) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &pgsql_link, pgsql_link_ce, &from) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); break; } to = zend_string_safe_alloc(ZSTR_LEN(from), 2, 0, 0); + // TODO When can it ben null? if (link) { - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), NULL); } else { @@ -3270,7 +3329,7 @@ PHP_FUNCTION(pg_escape_bytea) size_t to_len; PGconn *pgsql; zval *pgsql_link; - zend_resource *link; + pgsql_link_handle *link; switch (ZEND_NUM_ARGS()) { case 1: @@ -3278,19 +3337,19 @@ PHP_FUNCTION(pg_escape_bytea) RETURN_THROWS(); } link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); break; default: - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &pgsql_link, &from) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &pgsql_link, pgsql_link_ce, &from) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); break; } if (link) { - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; to = (char *)PQescapeByteaConn(pgsql, (unsigned char *)ZSTR_VAL(from), ZSTR_LEN(from), &to_len); } else { to = (char *)PQescapeBytea((unsigned char *)ZSTR_VAL(from), ZSTR_LEN(from), &to_len); @@ -3327,7 +3386,7 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l zval *pgsql_link = NULL; PGconn *pgsql; char *tmp; - zend_resource *link; + pgsql_link_handle *link; switch (ZEND_NUM_ARGS()) { case 1: @@ -3339,16 +3398,15 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l break; default: - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &pgsql_link, &from) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &pgsql_link, pgsql_link_ce, &from) == FAILURE) { RETURN_THROWS(); } - link = Z_RES_P(pgsql_link); + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); break; } - if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + pgsql = link->conn; if (escape_literal) { tmp = PQescapeLiteral(pgsql, ZSTR_VAL(from), ZSTR_LEN(from)); @@ -3387,18 +3445,16 @@ PHP_FUNCTION(pg_result_error) pgsql_result_handle *pg_result; char *err = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { - RETURN_THROWS(); - } - - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &result, pgsql_result_ce) == FAILURE) { RETURN_THROWS(); } + pg_result = Z_PGSQL_RESULT_P(result); pgsql_result = pg_result->result; if (!pgsql_result) { RETURN_FALSE; } + err = (char *)PQresultErrorMessage(pgsql_result); RETURN_STRING(err); } @@ -3413,18 +3469,16 @@ PHP_FUNCTION(pg_result_error_field) pgsql_result_handle *pg_result; char *field = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result, &fieldcode) == FAILURE) { - RETURN_THROWS(); - } - - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &result, pgsql_result_ce, &fieldcode) == FAILURE) { RETURN_THROWS(); } + pg_result = Z_PGSQL_RESULT_P(result); pgsql_result = pg_result->result; if (!pgsql_result) { RETURN_FALSE; } + if (fieldcode & (PG_DIAG_SEVERITY|PG_DIAG_SQLSTATE|PG_DIAG_MESSAGE_PRIMARY|PG_DIAG_MESSAGE_DETAIL |PG_DIAG_MESSAGE_HINT|PG_DIAG_STATEMENT_POSITION #ifdef PG_DIAG_INTERNAL_POSITION @@ -3451,15 +3505,16 @@ PHP_FUNCTION(pg_result_error_field) PHP_FUNCTION(pg_connection_status) { zval *pgsql_link = NULL; + pgsql_link_handle *link; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; RETURN_LONG(PQstatus(pgsql)); } @@ -3470,15 +3525,16 @@ PHP_FUNCTION(pg_connection_status) PHP_FUNCTION(pg_transaction_status) { zval *pgsql_link = NULL; + pgsql_link_handle *link; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; RETURN_LONG(PQtransactionStatus(pgsql)); } @@ -3489,15 +3545,16 @@ PHP_FUNCTION(pg_transaction_status) PHP_FUNCTION(pg_connection_reset) { zval *pgsql_link; + pgsql_link_handle *link; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; PQreset(pgsql); if (PQstatus(pgsql) == CONNECTION_BAD) { @@ -3533,16 +3590,17 @@ static int php_pgsql_flush_query(PGconn *pgsql) static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { zval *pgsql_link; + pgsql_link_handle *link; PGconn *pgsql; PGresult *pgsql_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; if (PQsetnonblocking(pgsql, 1)) { php_error_docref(NULL, E_NOTICE, "Cannot set connection to nonblocking mode"); @@ -3597,19 +3655,20 @@ static bool _php_pgsql_link_has_results(PGconn *pgsql) /* {{{ */ PHP_FUNCTION(pg_send_query) { zval *pgsql_link; + pgsql_link_handle *link; char *query; size_t len; PGconn *pgsql; int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &query, &len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pgsql_link, pgsql_link_ce, &query, &len) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; is_non_blocking = PQisnonblocking(pgsql); @@ -3666,6 +3725,7 @@ PHP_FUNCTION(pg_send_query) PHP_FUNCTION(pg_send_query_params) { zval *pgsql_link, *pv_param_arr, *tmp; + pgsql_link_handle *link; int num_params = 0; char **params = NULL; char *query; @@ -3674,13 +3734,13 @@ PHP_FUNCTION(pg_send_query_params) int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osa", &pgsql_link, pgsql_link_ce, &query, &query_len, &pv_param_arr) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; is_non_blocking = PQisnonblocking(pgsql); @@ -3761,19 +3821,20 @@ PHP_FUNCTION(pg_send_query_params) PHP_FUNCTION(pg_send_prepare) { zval *pgsql_link; + pgsql_link_handle *link; char *query, *stmtname; size_t stmtname_len, query_len; PGconn *pgsql; int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oss", &pgsql_link, pgsql_link_ce, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; is_non_blocking = PQisnonblocking(pgsql); @@ -3830,6 +3891,7 @@ PHP_FUNCTION(pg_send_prepare) PHP_FUNCTION(pg_send_execute) { zval *pgsql_link; + pgsql_link_handle *link; zval *pv_param_arr, *tmp; int num_params = 0; char **params = NULL; @@ -3839,13 +3901,13 @@ PHP_FUNCTION(pg_send_execute) int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osa", &pgsql_link, pgsql_link_ce, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; is_non_blocking = PQisnonblocking(pgsql); @@ -3927,28 +3989,30 @@ PHP_FUNCTION(pg_send_execute) PHP_FUNCTION(pg_get_result) { zval *pgsql_link; + pgsql_link_handle *link; PGconn *pgsql; PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; pgsql_result = PQgetResult(pgsql); if (!pgsql_result) { /* no result */ RETURN_FALSE; } - pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle)); + + object_init_ex(return_value, pgsql_result_ce); + pg_result = Z_PGSQL_RESULT_P(return_value); pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - RETURN_RES(zend_register_resource(pg_result, le_result)); } /* }}} */ @@ -3961,15 +4025,14 @@ PHP_FUNCTION(pg_result_status) PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &result, &result_type) == FAILURE) { - RETURN_THROWS(); - } - - if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &result, pgsql_result_ce, &result_type) == FAILURE) { RETURN_THROWS(); } + pg_result = Z_PGSQL_RESULT_P(result); + CHECK_PGSQL_RESULT(pg_result); pgsql_result = pg_result->result; + if (result_type == PGSQL_STATUS_LONG) { status = PQresultStatus(pgsql_result); RETURN_LONG((int)status); @@ -3987,17 +4050,18 @@ PHP_FUNCTION(pg_result_status) PHP_FUNCTION(pg_get_notify) { zval *pgsql_link; + pgsql_link_handle *link; zend_long result_type = PGSQL_ASSOC; PGconn *pgsql; PGnotify *pgsql_notify; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pgsql_link, &result_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &pgsql_link, pgsql_link_ce, &result_type) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; if (!(result_type & PGSQL_BOTH)) { zend_argument_value_error(2, "must be one of PGSQL_ASSOC, PGSQL_NUM, or PGSQL_BOTH"); @@ -4035,15 +4099,16 @@ PHP_FUNCTION(pg_get_notify) PHP_FUNCTION(pg_get_pid) { zval *pgsql_link; + pgsql_link_handle *link; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; RETURN_LONG(PQbackendPID(pgsql)); } @@ -4114,16 +4179,17 @@ static int php_pgsql_fd_cast(php_stream *stream, int cast_as, void **ret) /* {{{ PHP_FUNCTION(pg_socket) { zval *pgsql_link; + pgsql_link_handle *link; php_stream *stream; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; stream = php_stream_alloc(&php_stream_pgsql_fd_ops, pgsql, NULL, "r"); @@ -4140,15 +4206,16 @@ PHP_FUNCTION(pg_socket) PHP_FUNCTION(pg_consume_input) { zval *pgsql_link; + pgsql_link_handle *link; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; RETURN_BOOL(PQconsumeInput(pgsql)); } @@ -4158,17 +4225,18 @@ PHP_FUNCTION(pg_consume_input) PHP_FUNCTION(pg_flush) { zval *pgsql_link; + pgsql_link_handle *link; PGconn *pgsql; int ret; int is_non_blocking; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pgsql_link, pgsql_link_ce) == FAILURE) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; is_non_blocking = PQisnonblocking(pgsql); @@ -4308,18 +4376,20 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string PHP_FUNCTION(pg_meta_data) { zval *pgsql_link; + pgsql_link_handle *link; zend_string *table_name; bool extended=0; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rP|b", - &pgsql_link, &table_name, &extended) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP|b", + &pgsql_link, pgsql_link_ce, &table_name, &extended) == FAILURE + ) { RETURN_THROWS(); } - if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pgsql = link->conn; /* php_pgsql_meta_data() asserts that table_name is not empty */ if (ZSTR_LEN(table_name) == 0) { @@ -5153,12 +5223,12 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * PHP_FUNCTION(pg_convert) { zval *pgsql_link, *values; + pgsql_link_handle *link; zend_string *table_name; zend_ulong option = 0; PGconn *pg_link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), - "rPa|l", &pgsql_link, &table_name, &values, &option) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|l", &pgsql_link, pgsql_link_ce, &table_name, &values, &option) == FAILURE) { RETURN_THROWS(); } @@ -5173,9 +5243,9 @@ PHP_FUNCTION(pg_convert) RETURN_THROWS(); } - if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pg_link = link->conn; if (php_pgsql_flush_query(pg_link)) { php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); @@ -5359,6 +5429,7 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t PHP_FUNCTION(pg_insert) { zval *pgsql_link, *values; + pgsql_link_handle *link; zend_string *table; zend_ulong option = PGSQL_DML_EXEC, return_sql; PGconn *pg_link; @@ -5366,8 +5437,9 @@ PHP_FUNCTION(pg_insert) ExecStatusType status; zend_string *sql = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rPa|l", &pgsql_link, &table, - &values, &option) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|l", + &pgsql_link, pgsql_link_ce, &table, &values, &option) == FAILURE + ) { RETURN_THROWS(); } @@ -5382,16 +5454,16 @@ PHP_FUNCTION(pg_insert) RETURN_THROWS(); } - if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pg_link = link->conn; if (php_pgsql_flush_query(pg_link)) { php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } return_sql = option & PGSQL_DML_STRING; if (option & PGSQL_DML_EXEC) { - /* return resource when executed */ + /* return object when executed */ option = option & ~PGSQL_DML_EXEC; if (php_pgsql_insert(pg_link, table, values, option|PGSQL_DML_STRING, &sql) == FAILURE) { RETURN_FALSE; @@ -5422,11 +5494,12 @@ PHP_FUNCTION(pg_insert) case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pg_result) { - pgsql_result_handle *pgsql_handle = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle)); - pgsql_handle->conn = pg_link; - pgsql_handle->result = pg_result; - pgsql_handle->row = 0; - RETURN_RES(zend_register_resource(pgsql_handle, le_result)); + object_init_ex(return_value, pgsql_result_ce); + pgsql_result_handle *pg_res = Z_PGSQL_RESULT_P(return_value); + pg_res->conn = pg_link; + pg_res->result = pg_result; + pg_res->row = 0; + return; } else { PQclear(pg_result); RETURN_FALSE; @@ -5577,13 +5650,16 @@ PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *t PHP_FUNCTION(pg_update) { zval *pgsql_link, *values, *ids; + pgsql_link_handle *link; zend_string *table; + size_t table_len; zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; zend_string *sql = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rPaa|l", &pgsql_link, &table, - &values, &ids, &option) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPaa|l", + &pgsql_link, pgsql_link_ce, &table, &values, &ids, &option) == FAILURE + ) { RETURN_THROWS(); } @@ -5598,9 +5674,9 @@ PHP_FUNCTION(pg_update) RETURN_THROWS(); } - if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pg_link = link->conn; if (php_pgsql_flush_query(pg_link)) { php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); @@ -5672,13 +5748,15 @@ PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *t PHP_FUNCTION(pg_delete) { zval *pgsql_link, *ids; + pgsql_link_handle *link; zend_string *table; zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; zend_string *sql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rPa|l", &pgsql_link, &table, - &ids, &option) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|l", + &pgsql_link, pgsql_link_ce, &table, &ids, &option + ) == FAILURE) { RETURN_THROWS(); } @@ -5693,9 +5771,9 @@ PHP_FUNCTION(pg_delete) RETURN_THROWS(); } - if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pg_link = link->conn; if (php_pgsql_flush_query(pg_link)) { php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); @@ -5813,6 +5891,7 @@ PHP_PGSQL_API void php_pgsql_result2array(PGresult *pg_result, zval *ret_array, PHP_FUNCTION(pg_select) { zval *pgsql_link, *ids; + pgsql_link_handle *link; zend_string *table; zend_ulong option = PGSQL_DML_EXEC; long result_type = PGSQL_ASSOC; @@ -5820,8 +5899,9 @@ PHP_FUNCTION(pg_select) zend_string *sql = NULL; /* TODO Document result_type param on php.net (apparently it was added in PHP 7.1) */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rPa|ll", &pgsql_link, &table, - &ids, &option, &result_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|ll", + &pgsql_link, pgsql_link_ce, &table, &ids, &option, &result_type + ) == FAILURE) { RETURN_THROWS(); } @@ -5840,9 +5920,9 @@ PHP_FUNCTION(pg_select) RETURN_THROWS(); } - if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { - RETURN_THROWS(); - } + link = Z_PGSQL_LINK_P(pgsql_link); + CHECK_PGSQL_LINK(link); + pg_link = link->conn; if (php_pgsql_flush_query(pg_link)) { php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php index e05c91ebee4e7..6180a49d4edbf 100644 --- a/ext/pgsql/pgsql.stub.php +++ b/ext/pgsql/pgsql.stub.php @@ -2,267 +2,214 @@ /** @generate-class-entries */ -/** @return resource|false */ -function pg_connect(string $connection_string, int $flags = 0) {} +/** @strict-properties */ +final class PgSql +{ +} -/** @return resource|false */ -function pg_pconnect(string $connection_string, int $flags = 0) {} +/** @strict-properties */ +final class PgSqlResult +{ +} + +/** @strict-properties */ +final class PgSqlLob +{ +} + +function pg_connect(string $connection_string, int $flags = 0): PgSql|false {} -/** @param resource $connection */ -function pg_connect_poll($connection): int {} +function pg_pconnect(string $connection_string, int $flags = 0): PgSql|false {} -/** @param resource|null $connection */ -function pg_close($connection = null): bool {} +function pg_connect_poll(PgSql $connection): int {} -/** @param resource|null $connection */ -function pg_dbname($connection = null): string {} +function pg_close(?PgSql $connection = null): bool {} -/** @param resource|null $connection */ -function pg_last_error($connection = null): string {} +function pg_dbname(?PgSql $connection = null): string {} + +function pg_last_error(?PgSql $connection = null): string {} /** - * @param resource|null $connection * @alias pg_last_error * @deprecated */ -function pg_errormessage($connection = null): string {} +function pg_errormessage(?PgSql $connection = null): string {} -/** @param resource|null $connection */ -function pg_options($connection = null): string {} +function pg_options(?PgSql $connection = null): string {} -/** @param resource|null $connection */ -function pg_port($connection = null): string {} +function pg_port(?PgSql $connection = null): string {} -/** @param resource|null $connection */ -function pg_tty($connection = null): string {} +function pg_tty(?PgSql $connection = null): string {} -/** @param resource|null $connection */ -function pg_host($connection = null): string {} +function pg_host(?PgSql $connection = null): string {} -/** @param resource|null $connection */ -function pg_version($connection = null): array {} +function pg_version(?PgSql $connection = null): array {} -/** @param resource|string $connection */ +/** @param PgSql|string $connection */ function pg_parameter_status($connection, string $name = UNKNOWN): string|false {} -/** @param resource|null $connection */ -function pg_ping($connection = null): bool {} +function pg_ping(?PgSql $connection = null): bool {} -/** - * @param resource|string $connection - * @return resource|false - */ -function pg_query($connection, string $query = UNKNOWN) {} +/** @param PgSql|string $connection */ +function pg_query($connection, string $query = UNKNOWN): PgSqlResult|false {} /** - * @param resource|string $connection - * @return resource|false + * @param PgSql|string $connection * @alias pg_query */ -function pg_exec($connection, string $query = UNKNOWN) {} +function pg_exec($connection, string $query = UNKNOWN): PgSqlResult|false {} /** - * @param resource|string $connection + * @param PgSql|string $connection * @param string|array $query - * @return resource|false */ -function pg_query_params($connection, $query, array $params = UNKNOWN) {} +function pg_query_params($connection, $query, array $params = UNKNOWN): PgSqlResult|false {} -/** - * @param resource|string $connection - * @return resource|false - */ -function pg_prepare($connection, string $statement_name, string $query = UNKNOWN) {} +/** @param PgSql|string $connection */ +function pg_prepare($connection, string $statement_name, string $query = UNKNOWN): PgSqlResult|false {} /** - * @param resource|string $connection + * @param PgSql|string $connection * @param string|array $statement_name - * @return resource|false */ -function pg_execute($connection, $statement_name, array $params = UNKNOWN) {} +function pg_execute($connection, $statement_name, array $params = UNKNOWN): PgSqlResult|false {} -/** @param resource $result */ -function pg_num_rows($result): int {} +function pg_num_rows(PgSqlResult $result): int {} /** - * @param resource $result * @alias pg_num_rows * @deprecated */ -function pg_numrows($result): int {} +function pg_numrows(PgSqlResult $result): int {} -/** @param resource $result */ -function pg_num_fields($result): int {} +function pg_num_fields(PgSqlResult $result): int {} /** - * @param resource $result * @alias pg_num_fields * @deprecated */ -function pg_numfields($result): int {} +function pg_numfields(PgSqlResult $result): int {} -/** @param resource $result */ -function pg_affected_rows($result): int {} +function pg_affected_rows(PgSqlResult $result): int {} /** - * @param resource $result * @alias pg_affected_rows * @deprecated */ -function pg_cmdtuples($result): int {} +function pg_cmdtuples(PgSqlResult $result): int {} -/** @param resource $connection */ -function pg_last_notice($connection, int $mode = PGSQL_NOTICE_LAST): array|string|bool {} +function pg_last_notice(PgSql $connection, int $mode = PGSQL_NOTICE_LAST): array|string|bool {} -/** @param resource $result */ -function pg_field_table($result, int $field, bool $oid_only = false): string|int|false {} +function pg_field_table(PgSqlResult $result, int $field, bool $oid_only = false): string|int|false {} -/** @param resource $result */ -function pg_field_name($result, int $field): string {} +function pg_field_name(PgSqlResult $result, int $field): string {} /** - * @param resource $result * @alias pg_field_name * @deprecated */ -function pg_fieldname($result, int $field): string {} +function pg_fieldname(PgSqlResult $result, int $field): string {} -/** @param resource $result */ -function pg_field_size($result, int $field): int {} +function pg_field_size(PgSqlResult $result, int $field): int {} /** - * @param resource $result * @alias pg_field_size * @deprecated */ -function pg_fieldsize($result, int $field): int {} +function pg_fieldsize(PgSqlResult $result, int $field): int {} -/** @param resource $result */ -function pg_field_type($result, int $field): string {} +function pg_field_type(PgSqlResult $result, int $field): string {} /** - * @param resource $result * @alias pg_field_type * @deprecated */ -function pg_fieldtype($result, int $field): string {} +function pg_fieldtype(PgSqlResult $result, int $field): string {} -/** @param resource $result */ -function pg_field_type_oid($result, int $field): string|int {} +function pg_field_type_oid(PgSqlResult $result, int $field): string|int {} -/** @param resource $result */ -function pg_field_num($result, string $field): int {} +function pg_field_num(PgSqlResult $result, string $field): int {} /** - * @param resource $result * @alias pg_field_num * @deprecated */ -function pg_fieldnum($result, string $field): int {} +function pg_fieldnum(PgSqlResult $result, string $field): int {} -/** - * @param resource $result - * @param string|int $row - */ -function pg_fetch_result($result, $row, string|int $field = UNKNOWN): string|false|null {} +/** @param string|int $row */ +function pg_fetch_result(PgSqlResult $result, $row, string|int $field = UNKNOWN): string|false|null {} /** - * @param resource $result * @param string|int $row * @alias pg_fetch_result * @deprecated */ -function pg_result($result, $row, string|int $field = UNKNOWN): string|false|null {} +function pg_result(PgSqlResult $result, $row, string|int $field = UNKNOWN): string|false|null {} -/** - * @param resource $result - */ -function pg_fetch_row($result, ?int $row = null, int $mode = PGSQL_NUM): array|false {} +function pg_fetch_row(PgSqlResult $result, ?int $row = null, int $mode = PGSQL_NUM): array|false {} -/** - * @param resource $result - */ -function pg_fetch_assoc($result, ?int $row = null): array|false {} +function pg_fetch_assoc(PgSqlResult $result, ?int $row = null): array|false {} -/** - * @param resource $result - */ -function pg_fetch_array($result, ?int $row = null, int $mode = PGSQL_BOTH): array|false {} +function pg_fetch_array(PgSqlResult $result, ?int $row = null, int $mode = PGSQL_BOTH): array|false {} -/** @param resource $result */ -function pg_fetch_object($result, ?int $row = null, string $class = "stdClass", array $constructor_args = []): object|false {} +function pg_fetch_object(PgSqlResult $result, ?int $row = null, string $class = "stdClass", array $constructor_args = []): object|false {} -/** @param resource $result */ -function pg_fetch_all($result, int $mode = PGSQL_ASSOC): array {} +function pg_fetch_all(PgSqlResult $result, int $mode = PGSQL_ASSOC): array {} -/** @param resource $result */ -function pg_fetch_all_columns($result, int $field = 0): array {} +function pg_fetch_all_columns(PgSqlResult $result, int $field = 0): array {} -/** @param resource $result */ -function pg_result_seek($result, int $row): bool {} +function pg_result_seek(PgSqlResult $result, int $row): bool {} -/** - * @param resource $result - * @param string|int $row - */ -function pg_field_prtlen($result, $row, string|int $field = UNKNOWN): int|false {} +/** @param string|int $row */ +function pg_field_prtlen(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} /** - * @param resource $result * @param string|int $row * @alias pg_field_prtlen * @deprecated */ -function pg_fieldprtlen($result, $row, string|int $field = UNKNOWN): int|false {} +function pg_fieldprtlen(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} /** - * @param resource $result * @param string|int $row */ -function pg_field_is_null($result, $row, string|int $field = UNKNOWN): int|false {} +function pg_field_is_null(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} /** - * @param resource $result * @param string|int $row * @alias pg_field_is_null * @deprecated */ -function pg_fieldisnull($result, $row, string|int $field = UNKNOWN): int|false {} +function pg_fieldisnull(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} -/** @param resource $result */ -function pg_free_result($result): bool {} +function pg_free_result(PgSqlResult $result): bool {} /** - * @param resource $result * @alias pg_free_result * @deprecated */ -function pg_freeresult($result): bool {} +function pg_freeresult(PgSqlResult $result): bool {} -/** @param resource $result */ -function pg_last_oid($result): string|int|false {} +function pg_last_oid(PgSqlResult $result): string|int|false {} /** - * @param resource $result * @alias pg_last_oid * @deprecated */ -function pg_getlastoid($result): string|int|false {} +function pg_getlastoid(PgSqlResult $result): string|int|false {} -/** @param resource|null $connection */ -function pg_trace(string $filename, string $mode = "w", $connection = null): bool {} +function pg_trace(string $filename, string $mode = "w", ?PgSql $connection = null): bool {} -/** @param resource|null $connection */ -function pg_untrace($connection = null): bool {} +function pg_untrace(?PgSql $connection = null): bool {} /** - * @param resource $connection + * @param PgSql $connection * @param string|int $oid */ function pg_lo_create($connection = UNKNOWN, $oid = UNKNOWN): string|int|false {} /** - * @param resource $connection + * @param PgSql $connection * @param string|int $oid * @alias pg_lo_create * @deprecated @@ -270,13 +217,13 @@ function pg_lo_create($connection = UNKNOWN, $oid = UNKNOWN): string|int|false { function pg_locreate($connection = UNKNOWN, $oid = UNKNOWN): string|int|false {} /** - * @param resource $connection + * @param PgSql $connection * @param string|int $oid */ function pg_lo_unlink($connection, $oid = UNKNOWN): bool {} /** - * @param resource $connection + * @param PgSql $connection * @param string|int $oid * @alias pg_lo_unlink * @deprecated @@ -284,232 +231,178 @@ function pg_lo_unlink($connection, $oid = UNKNOWN): bool {} function pg_lounlink($connection, $oid = UNKNOWN): bool {} /** - * @param resource $connection + * @param PgSql $connection * @param string|int $oid - * @return resource|false */ -function pg_lo_open($connection, $oid = UNKNOWN, string $mode = UNKNOWN) {} +function pg_lo_open($connection, $oid = UNKNOWN, string $mode = UNKNOWN): PgSqlLob|false {} /** - * @param resource $connection + * @param PgSql $connection * @param string|int $oid - * @return resource|false * @alias pg_lo_open * @deprecated */ -function pg_loopen($connection, $oid = UNKNOWN, string $mode = UNKNOWN) {} +function pg_loopen($connection, $oid = UNKNOWN, string $mode = UNKNOWN): PgSqlLob|false {} -/** @param resource $lob */ -function pg_lo_close($lob): bool {} +function pg_lo_close(PgSqlLob $lob): bool {} /** - * @param resource $lob * @alias pg_lo_close * @deprecated */ -function pg_loclose($lob): bool {} +function pg_loclose(PgSqlLob $lob): bool {} -/** @param resource $lob */ -function pg_lo_read($lob, int $length = 8192): string|false {} +function pg_lo_read(PgSqlLob $lob, int $length = 8192): string|false {} /** - * @param resource $lob * @alias pg_lo_read * @deprecated */ -function pg_loread($lob, int $length = 8192): string|false {} +function pg_loread(PgSqlLob $lob, int $length = 8192): string|false {} -/** @param resource $lob */ -function pg_lo_write($lob, string $data, ?int $length = null): int|false {} +function pg_lo_write(PgSqlLob $lob, string $data, ?int $length = null): int|false {} /** - * @param resource $lob * @alias pg_lo_write * @deprecated */ -function pg_lowrite($lob, string $data, ?int $length = null): int|false {} +function pg_lowrite(PgSqlLob $lob, string $data, ?int $length = null): int|false {} -/** @param resource $lob */ -function pg_lo_read_all($lob): int {} +function pg_lo_read_all(PgSqlLob $lob): int {} /** - * @param resource $lob * @alias pg_lo_read_all * @deprecated */ -function pg_loreadall($lob): int {} +function pg_loreadall(PgSqlLob $lob): int {} /** - * @param resource|string $connection + * @param PgSql|string $connection * @param string|int $filename * @param string|int $oid - * @return resource|false */ function pg_lo_import($connection, $filename = UNKNOWN, $oid = UNKNOWN): string|int|false {} /** - * @param resource|string $connection + * @param PgSql|string $connection * @param string|int $filename * @param string|int $oid - * @return resource|false * @alias pg_lo_import * @deprecated */ function pg_loimport($connection, $filename = UNKNOWN, $oid = UNKNOWN): string|int|false {} /** - * @param resource|string|int $connection + * @param PgSql|string|int $connection * @param string|int $oid * @param string|int $filename - * @return resource|false */ function pg_lo_export($connection, $oid = UNKNOWN, $filename = UNKNOWN): bool {} /** - * @param resource|string|int $connection + * @param PgSql|string|int $connection * @param string|int $oid * @param string|int $filename - * @return resource|false * @alias pg_lo_export * @deprecated */ function pg_loexport($connection, $oid = UNKNOWN, $filename = UNKNOWN): bool {} -/** @param resource $lob */ -function pg_lo_seek($lob, int $offset, int $whence = SEEK_CUR): bool {} +function pg_lo_seek(PgSqlLob $lob, int $offset, int $whence = SEEK_CUR): bool {} -/** @param resource $lob */ -function pg_lo_tell($lob): int {} +function pg_lo_tell(PgSqlLob $lob): int {} -/** @param resource $lob */ -function pg_lo_truncate($lob, int $size): bool {} +function pg_lo_truncate(PgSqlLob $lob, int $size): bool {} -/** @param resource|int $connection */ +/** @param PgSql|int $connection */ function pg_set_error_verbosity($connection, int $verbosity = UNKNOWN): int|false {} -/** @param resource|string $connection */ +/** @param PgSql|string $connection */ function pg_set_client_encoding($connection, string $encoding = UNKNOWN): int {} /** - * @param resource|string $connection + * @param PgSql|string $connection * @alias pg_set_client_encoding * @deprecated */ function pg_setclientencoding($connection, string $encoding = UNKNOWN): int {} -/** @param resource|null $connection */ -function pg_client_encoding($connection = null): string {} +function pg_client_encoding(?PgSql $connection = null): string {} /** - * @param resource|null $connection * @alias pg_client_encoding * @deprecated */ -function pg_clientencoding($connection = null): string {} +function pg_clientencoding(?PgSql $connection = null): string {} -/** @param resource|null $connection */ -function pg_end_copy($connection = null): bool {} +function pg_end_copy(?PgSql $connection = null): bool {} -/** @param resource|string $connection */ +/** @param PgSql|string $connection */ function pg_put_line($connection, string $query = UNKNOWN): bool {} -/** @param resource $connection */ -function pg_copy_to($connection, string $table_name, string $separator = "\t", string $null_as = "\\\\N"): array|false {} +function pg_copy_to(PgSql $connection, string $table_name, string $separator = "\t", string $null_as = "\\\\N"): array|false {} -/** @param resource $connection */ -function pg_copy_from($connection, string $table_name, array $rows, string $separator = "\t", string $null_as = "\\\\N"): bool {} +function pg_copy_from(PgSql $connection, string $table_name, array $rows, string $separator = "\t", string $null_as = "\\\\N"): bool {} -/** @param resource|string $connection */ +/** @param PgSql|string $connection */ function pg_escape_string($connection, string $string = UNKNOWN): string {} -/** @param resource|string $connection */ +/** @param PgSql|string $connection */ function pg_escape_bytea($connection, string $string = UNKNOWN): string {} function pg_unescape_bytea(string $string): string {} -/** @param resource|string $connection */ +/** @param PgSql|string $connection */ function pg_escape_literal($connection, string $string = UNKNOWN): string|false {} -/** @param resource|string $connection */ +/** @param PgSql|string $connection */ function pg_escape_identifier($connection, string $string = UNKNOWN): string|false {} -/** @param resource $result */ -function pg_result_error($result): string|false {} +function pg_result_error(PgSqlResult $result): string|false {} -/** @param resource $result */ -function pg_result_error_field($result, int $field_code): string|false|null {} +function pg_result_error_field(PgSqlResult $result, int $field_code): string|false|null {} -/** @param resource $connection */ -function pg_connection_status($connection): int {} +function pg_connection_status(PgSql $connection): int {} -/** @param resource $connection */ -function pg_transaction_status($connection): int {} +function pg_transaction_status(PgSql $connection): int {} -/** @param resource $connection */ -function pg_connection_reset($connection): bool {} +function pg_connection_reset(PgSql $connection): bool {} -/** @param resource $connection */ -function pg_cancel_query($connection): bool {} +function pg_cancel_query(PgSql $connection): bool {} -/** @param resource $connection */ -function pg_connection_busy($connection): bool {} +function pg_connection_busy(PgSql $connection): bool {} -/** @param resource $connection */ -function pg_send_query($connection, string $query): int|bool {} +function pg_send_query(PgSql $connection, string $query): int|bool {} -/** @param resource $connection */ -function pg_send_query_params($connection, string $query, array $params): int|bool {} +function pg_send_query_params(PgSql $connection, string $query, array $params): int|bool {} -/** @param resource $connection */ -function pg_send_prepare($connection, string $statement_name, string $query): int|bool {} +function pg_send_prepare(PgSql $connection, string $statement_name, string $query): int|bool {} -/** @param resource $connection */ -function pg_send_execute($connection, string $query, array $params): int|bool {} +function pg_send_execute(PgSql $connection, string $query, array $params): int|bool {} -/** - * @param resource $connection - * @return resource|false - */ -function pg_get_result($connection) {} +function pg_get_result(PgSql $connection): PgSqlResult|false {} -/** @param resource $result */ -function pg_result_status($result, int $mode = PGSQL_STATUS_LONG): string|int {} +function pg_result_status(PgSqlResult $result, int $mode = PGSQL_STATUS_LONG): string|int {} -/** @param resource $connection */ -function pg_get_notify($connection, int $mode = PGSQL_ASSOC): array|false {} +function pg_get_notify(PgSql $connection, int $mode = PGSQL_ASSOC): array|false {} -/** @param resource $connection */ -function pg_get_pid($connection): int {} +function pg_get_pid(PgSql $connection): int {} -/** - * @param resource $connection - * @return resource|false - */ -function pg_socket($connection) {} +/** @return resource|false */ +function pg_socket(PgSql $connection) {} -/** @param resource $connection */ -function pg_consume_input($connection): bool {} +function pg_consume_input(PgSql $connection): bool {} -/** @param resource $connection */ -function pg_flush($connection): int|bool {} +function pg_flush(PgSql $connection): int|bool {} -/** @param resource $connection */ -function pg_meta_data($connection, string $table_name, bool $extended = false): array|false {} +function pg_meta_data(PgSql $connection, string $table_name, bool $extended = false): array|false {} -/** @param resource $connection */ -function pg_convert($connection, string $table_name, array $values, int $flags = 0): array|false {} +function pg_convert(PgSql $connection, string $table_name, array $values, int $flags = 0): array|false {} -/** - * @param resource $connection - * @return resource|string|bool - */ -function pg_insert($connection, string $table_name, array $values, int $flags = PGSQL_DML_EXEC) {} +function pg_insert(PgSql $connection, string $table_name, array $values, int $flags = PGSQL_DML_EXEC): PgSqlResult|string|bool {} -/** @param resource $connection */ -function pg_update($connection, string $table_name, array $values, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} +function pg_update(PgSql $connection, string $table_name, array $values, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} -/** @param resource $connection */ -function pg_delete($connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} +function pg_delete(PgSql $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} -/** @param resource $connection */ -function pg_select($connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC, int $mode = PGSQL_ASSOC): array|string|false {} +function pg_select(PgSql $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC, int $mode = PGSQL_ASSOC): array|string|false {} diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index 970d372cdde4c..bac9a2b47fbd8 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1,7 +1,7 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 949190bcdea7c4d889d0a7da190cf9aeb80ebaab */ + * Stub hash: eef82ce2f0201a9b9584c5588797af78e635cea4 */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_connect, 0, 1, PgSql, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() @@ -9,15 +9,15 @@ ZEND_END_ARG_INFO() #define arginfo_pg_pconnect arginfo_pg_connect ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_connect_poll, 0, 1, IS_LONG, 0) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_close, 0, 0, _IS_BOOL, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, connection, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_dbname, 0, 0, IS_STRING, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, connection, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") ZEND_END_ARG_INFO() #define arginfo_pg_last_error arginfo_pg_dbname @@ -33,7 +33,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_host arginfo_pg_dbname ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_version, 0, 0, IS_ARRAY, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, connection, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_parameter_status, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) @@ -43,33 +43,33 @@ ZEND_END_ARG_INFO() #define arginfo_pg_ping arginfo_pg_close -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_query, 0, 1, PgSqlResult, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pg_exec arginfo_pg_query -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query_params, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_query_params, 0, 2, PgSqlResult, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, query) ZEND_ARG_TYPE_INFO(0, params, IS_ARRAY, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_prepare, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_prepare, 0, 2, PgSqlResult, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_TYPE_INFO(0, statement_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_execute, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_execute, 0, 2, PgSqlResult, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, statement_name) ZEND_ARG_TYPE_INFO(0, params, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_num_rows, 0, 1, IS_LONG, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_END_ARG_INFO() #define arginfo_pg_numrows arginfo_pg_num_rows @@ -83,25 +83,25 @@ ZEND_END_ARG_INFO() #define arginfo_pg_cmdtuples arginfo_pg_num_rows ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_last_notice, 0, 1, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_BOOL) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_NOTICE_LAST") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_table, 0, 2, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, oid_only, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_name, 0, 2, IS_STRING, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() #define arginfo_pg_fieldname arginfo_pg_field_name ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_size, 0, 2, IS_LONG, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -112,19 +112,19 @@ ZEND_END_ARG_INFO() #define arginfo_pg_fieldtype arginfo_pg_field_name ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_type_oid, 0, 2, MAY_BE_STRING|MAY_BE_LONG) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_num, 0, 2, IS_LONG, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pg_fieldnum arginfo_pg_field_num ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_result, 0, 2, MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_INFO(0, row) ZEND_ARG_TYPE_MASK(0, field, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_END_ARG_INFO() @@ -132,46 +132,46 @@ ZEND_END_ARG_INFO() #define arginfo_pg_result arginfo_pg_fetch_result ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_row, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_NUM") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_assoc, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_array, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_BOTH") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_object, 0, 1, MAY_BE_OBJECT|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all, 0, 1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_ASSOC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all_columns, 0, 1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, field, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_result_seek, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO(0, row, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_prtlen, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_INFO(0, row) ZEND_ARG_TYPE_MASK(0, field, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_END_ARG_INFO() @@ -183,13 +183,13 @@ ZEND_END_ARG_INFO() #define arginfo_pg_fieldisnull arginfo_pg_field_prtlen ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_free_result, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_END_ARG_INFO() #define arginfo_pg_freeresult arginfo_pg_free_result ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_last_oid, 0, 1, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_END_ARG_INFO() #define arginfo_pg_getlastoid arginfo_pg_last_oid @@ -197,7 +197,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_trace, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 0, "\"w\"") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, connection, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") ZEND_END_ARG_INFO() #define arginfo_pg_untrace arginfo_pg_close @@ -216,7 +216,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_lounlink arginfo_pg_lo_unlink -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_open, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_lo_open, 0, 1, PgSqlLob, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, oid) ZEND_ARG_TYPE_INFO(0, mode, IS_STRING, 0) @@ -225,20 +225,20 @@ ZEND_END_ARG_INFO() #define arginfo_pg_loopen arginfo_pg_lo_open ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_close, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, lob) + ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) ZEND_END_ARG_INFO() #define arginfo_pg_loclose arginfo_pg_lo_close ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_lo_read, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, lob) + ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 0, "8192") ZEND_END_ARG_INFO() #define arginfo_pg_loread arginfo_pg_lo_read ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_lo_write, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, lob) + ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() @@ -246,7 +246,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_lowrite arginfo_pg_lo_write ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_read_all, 0, 1, IS_LONG, 0) - ZEND_ARG_INFO(0, lob) + ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) ZEND_END_ARG_INFO() #define arginfo_pg_loreadall arginfo_pg_lo_read_all @@ -268,7 +268,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_loexport arginfo_pg_lo_export ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_seek, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(0, lob) + ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, whence, IS_LONG, 0, "SEEK_CUR") ZEND_END_ARG_INFO() @@ -276,7 +276,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_lo_tell arginfo_pg_lo_read_all ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_truncate, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(0, lob) + ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -304,14 +304,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_put_line, 0, 1, _IS_BOOL, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_copy_to, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\"\\t\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, null_as, IS_STRING, 0, "\"\\\\\\\\N\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_copy_from, 0, 3, _IS_BOOL, 0) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, rows, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\"\\t\"") @@ -337,11 +337,11 @@ ZEND_END_ARG_INFO() #define arginfo_pg_escape_identifier arginfo_pg_escape_literal ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_error, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_error_field, 0, 2, MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO(0, field_code, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -350,7 +350,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_transaction_status arginfo_pg_connect_poll ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_connection_reset, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_END_ARG_INFO() #define arginfo_pg_cancel_query arginfo_pg_connection_reset @@ -358,70 +358,72 @@ ZEND_END_ARG_INFO() #define arginfo_pg_connection_busy arginfo_pg_connection_reset ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_send_query, 0, 2, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_send_query_params, 0, 3, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, params, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_send_prepare, 0, 3, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, statement_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pg_send_execute arginfo_pg_send_query_params -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_result, 0, 0, 1) - ZEND_ARG_INFO(0, connection) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_get_result, 0, 1, PgSqlResult, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_status, 0, 1, MAY_BE_STRING|MAY_BE_LONG) - ZEND_ARG_INFO(0, result) + ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_STATUS_LONG") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_get_notify, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_ASSOC") ZEND_END_ARG_INFO() #define arginfo_pg_get_pid arginfo_pg_connect_poll -#define arginfo_pg_socket arginfo_pg_get_result +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_socket, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) +ZEND_END_ARG_INFO() #define arginfo_pg_consume_input arginfo_pg_connection_reset ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_flush, 0, 1, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_meta_data, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extended, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_convert, 0, 3, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_insert, 0, 0, 3) - ZEND_ARG_INFO(0, connection) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_insert, 0, 3, PgSqlResult, MAY_BE_STRING|MAY_BE_BOOL) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_update, 0, 4, MAY_BE_STRING|MAY_BE_BOOL) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) @@ -429,14 +431,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_update, 0, 4, MAY_BE_STRING|M ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_delete, 0, 3, MAY_BE_STRING|MAY_BE_BOOL) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_select, 0, 3, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, connection) + ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") @@ -652,3 +654,51 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(pg_select, arginfo_pg_select) ZEND_FE_END }; + + +static const zend_function_entry class_PgSql_methods[] = { + ZEND_FE_END +}; + + +static const zend_function_entry class_PgSqlResult_methods[] = { + ZEND_FE_END +}; + + +static const zend_function_entry class_PgSqlLob_methods[] = { + ZEND_FE_END +}; + +static zend_class_entry *register_class_PgSql(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "PgSql", class_PgSql_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + + return class_entry; +} + +static zend_class_entry *register_class_PgSqlResult(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "PgSqlResult", class_PgSqlResult_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + + return class_entry; +} + +static zend_class_entry *register_class_PgSqlLob(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "PgSqlLob", class_PgSqlLob_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + + return class_entry; +} diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index a992b829173d7..9d2d5e768cd6b 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -57,108 +57,6 @@ PHP_MSHUTDOWN_FUNCTION(pgsql); PHP_RINIT_FUNCTION(pgsql); PHP_RSHUTDOWN_FUNCTION(pgsql); PHP_MINFO_FUNCTION(pgsql); -/* connection functions */ -PHP_FUNCTION(pg_connect); -PHP_FUNCTION(pg_pconnect); -PHP_FUNCTION(pg_connect_poll); -PHP_FUNCTION(pg_close); -PHP_FUNCTION(pg_connection_reset); -PHP_FUNCTION(pg_connection_status); -PHP_FUNCTION(pg_connection_busy); -PHP_FUNCTION(pg_host); -PHP_FUNCTION(pg_dbname); -PHP_FUNCTION(pg_port); -PHP_FUNCTION(pg_tty); -PHP_FUNCTION(pg_options); -PHP_FUNCTION(pg_version); -PHP_FUNCTION(pg_ping); -PHP_FUNCTION(pg_parameter_status); -PHP_FUNCTION(pg_transaction_status); -/* query functions */ -PHP_FUNCTION(pg_query); -PHP_FUNCTION(pg_query_params); -PHP_FUNCTION(pg_prepare); -PHP_FUNCTION(pg_execute); -PHP_FUNCTION(pg_send_query); -PHP_FUNCTION(pg_send_query_params); -PHP_FUNCTION(pg_send_prepare); -PHP_FUNCTION(pg_send_execute); -PHP_FUNCTION(pg_cancel_query); -/* result functions */ -PHP_FUNCTION(pg_fetch_assoc); -PHP_FUNCTION(pg_fetch_array); -PHP_FUNCTION(pg_fetch_object); -PHP_FUNCTION(pg_fetch_result); -PHP_FUNCTION(pg_fetch_row); -PHP_FUNCTION(pg_fetch_all); -PHP_FUNCTION(pg_fetch_all_columns); -PHP_FUNCTION(pg_affected_rows); -PHP_FUNCTION(pg_get_result); -PHP_FUNCTION(pg_result_seek); -PHP_FUNCTION(pg_result_status); -PHP_FUNCTION(pg_free_result); -PHP_FUNCTION(pg_last_oid); -PHP_FUNCTION(pg_num_rows); -PHP_FUNCTION(pg_num_fields); -PHP_FUNCTION(pg_field_name); -PHP_FUNCTION(pg_field_num); -PHP_FUNCTION(pg_field_size); -PHP_FUNCTION(pg_field_type); -PHP_FUNCTION(pg_field_type_oid); -PHP_FUNCTION(pg_field_prtlen); -PHP_FUNCTION(pg_field_is_null); -PHP_FUNCTION(pg_field_table); -/* async message functions */ -PHP_FUNCTION(pg_get_notify); -PHP_FUNCTION(pg_socket); -PHP_FUNCTION(pg_consume_input); -PHP_FUNCTION(pg_flush); -PHP_FUNCTION(pg_get_pid); -/* error message functions */ -PHP_FUNCTION(pg_result_error); -PHP_FUNCTION(pg_result_error_field); -PHP_FUNCTION(pg_last_error); -PHP_FUNCTION(pg_last_notice); -/* copy functions */ -PHP_FUNCTION(pg_put_line); -PHP_FUNCTION(pg_end_copy); -PHP_FUNCTION(pg_copy_to); -PHP_FUNCTION(pg_copy_from); -/* large object functions */ -PHP_FUNCTION(pg_lo_create); -PHP_FUNCTION(pg_lo_unlink); -PHP_FUNCTION(pg_lo_open); -PHP_FUNCTION(pg_lo_close); -PHP_FUNCTION(pg_lo_read); -PHP_FUNCTION(pg_lo_write); -PHP_FUNCTION(pg_lo_read_all); -PHP_FUNCTION(pg_lo_import); -PHP_FUNCTION(pg_lo_export); -PHP_FUNCTION(pg_lo_seek); -PHP_FUNCTION(pg_lo_tell); -PHP_FUNCTION(pg_lo_truncate); - -/* debugging functions */ -PHP_FUNCTION(pg_trace); -PHP_FUNCTION(pg_untrace); - -/* utility functions */ -PHP_FUNCTION(pg_client_encoding); -PHP_FUNCTION(pg_set_client_encoding); -PHP_FUNCTION(pg_set_error_verbosity); -PHP_FUNCTION(pg_escape_string); -PHP_FUNCTION(pg_escape_bytea); -PHP_FUNCTION(pg_unescape_bytea); -PHP_FUNCTION(pg_escape_literal); -PHP_FUNCTION(pg_escape_identifier); - -/* misc functions */ -PHP_FUNCTION(pg_meta_data); -PHP_FUNCTION(pg_convert); -PHP_FUNCTION(pg_insert); -PHP_FUNCTION(pg_update); -PHP_FUNCTION(pg_delete); -PHP_FUNCTION(pg_select); /* connection options - ToDo: Add async connection option */ #define PGSQL_CONNECT_FORCE_NEW (1<<1) @@ -245,15 +143,22 @@ typedef enum _php_pgsql_data_type { PG_UNKNOWN } php_pgsql_data_type; +typedef struct pgsql_link_handle { + PGconn *conn; + zend_object std; +} pgsql_link_handle; + typedef struct pgLofp { PGconn *conn; int lofd; + zend_object std; } pgLofp; typedef struct _php_pgsql_result_handle { PGconn *conn; PGresult *result; int row; + zend_object std; } pgsql_result_handle; typedef struct _php_pgsql_notice { @@ -278,13 +183,13 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) zend_long max_links,max_persistent; zend_long allow_persistent; zend_long auto_reset_persistent; - int le_lofp,le_string; int ignore_notices,log_notices; HashTable notices; /* notice message for each connection */ - zend_resource *default_link; /* default link when connection is omitted */ + zval *default_link; /* default link when connection is omitted */ HashTable hashes; /* hashes for each connection */ HashTable field_oids; HashTable table_oids; + HashTable regular_list; /* connection list */ ZEND_END_MODULE_GLOBALS(pgsql) ZEND_EXTERN_MODULE_GLOBALS(pgsql) diff --git a/ext/pgsql/tests/00version.phpt b/ext/pgsql/tests/00version.phpt index f068abe2c6cc4..407d59f7ac933 100644 --- a/ext/pgsql/tests/00version.phpt +++ b/ext/pgsql/tests/00version.phpt @@ -11,7 +11,6 @@ include('config.inc'); $db = pg_connect($conn_str); var_dump(pg_version($db)); pg_close($db); - // Get environment vars for debugging var_dump(serialize($_ENV)); diff --git a/ext/pgsql/tests/02connection.phpt b/ext/pgsql/tests/02connection.phpt index 9922bba98f3b9..c405bb04b6ccd 100644 --- a/ext/pgsql/tests/02connection.phpt +++ b/ext/pgsql/tests/02connection.phpt @@ -54,4 +54,5 @@ pg_close($db); ?> --EXPECTF-- -resource(%d) of type (pgsql link%s) +object(PgSql)#%d (0) { +} diff --git a/ext/pgsql/tests/12pg_insert_9.phpt b/ext/pgsql/tests/12pg_insert_9.phpt index 11a401f3580d5..833b1481c76be 100644 --- a/ext/pgsql/tests/12pg_insert_9.phpt +++ b/ext/pgsql/tests/12pg_insert_9.phpt @@ -19,7 +19,7 @@ $fields = array('num'=>'1234', 'str'=>'AAA', 'bin'=>'BBB'); pg_insert($db, $table_name, $fields) or print "Error in test 1\n"; echo pg_insert($db, $table_name, $fields, PGSQL_DML_STRING)."\n"; echo pg_insert($db, $table_name, $fields, PGSQL_DML_STRING|PGSQL_DML_ESCAPE)."\n"; -var_dump( pg_insert($db, $table_name, $fields, PGSQL_DML_EXEC) ); // Return resource +var_dump( pg_insert($db, $table_name, $fields, PGSQL_DML_EXEC) ); /* Invalid values */ try { diff --git a/ext/pgsql/tests/13pg_select_9.phpt b/ext/pgsql/tests/13pg_select_9.phpt index 82a59a1cf5638..6de11e1cb5d00 100644 --- a/ext/pgsql/tests/13pg_select_9.phpt +++ b/ext/pgsql/tests/13pg_select_9.phpt @@ -18,6 +18,7 @@ $fields = array('num'=>'1234', 'str'=>'ABC', 'bin'=>'XYZ'); $ids = array('num'=>'1234'); $res = pg_select($db, $table_name, $ids) or print "Error\n"; +var_dump(pg_last_error($db)); var_dump($res); echo pg_select($db, $table_name, $ids, PGSQL_DML_STRING)."\n"; echo pg_select($db, $table_name, $ids, PGSQL_DML_STRING|PGSQL_DML_ESCAPE)."\n"; diff --git a/ext/pgsql/tests/17result.phpt b/ext/pgsql/tests/17result.phpt index e5e630d0fd2b5..f7f2ef1934278 100644 --- a/ext/pgsql/tests/17result.phpt +++ b/ext/pgsql/tests/17result.phpt @@ -23,9 +23,9 @@ var_dump(pg_result_seek($result, 0)); echo "Ok\n"; ?> ---EXPECT-- +--EXPECTF-- bool(true) -object(stdClass)#1 (3) { +object(stdClass)#%d (3) { ["num"]=> string(1) "1" ["str"]=> diff --git a/ext/pgsql/tests/22pg_fetch_object.phpt b/ext/pgsql/tests/22pg_fetch_object.phpt index 4eac5b788d852..1f17d076f5832 100644 --- a/ext/pgsql/tests/22pg_fetch_object.phpt +++ b/ext/pgsql/tests/22pg_fetch_object.phpt @@ -30,9 +30,9 @@ try { echo "Ok\n"; ?> ---EXPECT-- +--EXPECTF-- test_class::__construct(1,2) -object(test_class)#1 (3) { +object(test_class)#%d (3) { ["num"]=> string(1) "0" ["str"]=> diff --git a/ext/pgsql/tests/28large_object_import_oid.phpt b/ext/pgsql/tests/28large_object_import_oid.phpt index 8209cc2932432..4bec8833f3211 100644 --- a/ext/pgsql/tests/28large_object_import_oid.phpt +++ b/ext/pgsql/tests/28large_object_import_oid.phpt @@ -93,5 +93,5 @@ Invalid OID value passed OID value must be of type string|int, bool given OID value must be of type string|int, array given OID value must be of type string|int, stdClass given -OID value must be of type string|int, resource given +OID value must be of type string|int, PgSql given OK diff --git a/ext/pgsql/tests/80_bug36625.phpt b/ext/pgsql/tests/80_bug36625.phpt index 63908f3b7ada2..55027778a2386 100644 --- a/ext/pgsql/tests/80_bug36625.phpt +++ b/ext/pgsql/tests/80_bug36625.phpt @@ -50,6 +50,7 @@ unlink($tracefile); ?> --EXPECTF-- bool(false) -resource(%d) of type (pgsql result) +object(PgSqlResult)#%d (0) { +} bool(true) bool(true) diff --git a/ext/pgsql/tests/bug60244.phpt b/ext/pgsql/tests/bug60244.phpt index 888e51129ff56..2fb083b82a0d8 100644 --- a/ext/pgsql/tests/bug60244.phpt +++ b/ext/pgsql/tests/bug60244.phpt @@ -41,7 +41,7 @@ var_dump(pg_fetch_row($result, 0)); pg_close($db); ?> ---EXPECT-- +--EXPECTF-- pg_fetch_array(): Argument #2 ($row) must be greater than or equal to 0 pg_fetch_assoc(): Argument #2 ($row) must be greater than or equal to 0 pg_fetch_object(): Argument #2 ($row) must be greater than or equal to 0 @@ -56,7 +56,7 @@ array(1) { ["?column?"]=> string(1) "a" } -object(stdClass)#1 (1) { +object(stdClass)#%d (1) { ["?column?"]=> string(1) "a" } diff --git a/ext/pgsql/tests/bug72197.phpt b/ext/pgsql/tests/bug72197.phpt index 796d4c713cdbd..f9b235dc218b8 100644 --- a/ext/pgsql/tests/bug72197.phpt +++ b/ext/pgsql/tests/bug72197.phpt @@ -31,6 +31,6 @@ pg_query($conn, "ROLLBACK"); pg_close($conn); ?> --EXPECTF-- -pg_lo_create(): supplied resource is not a valid PostgreSQL link resource%w +pg_lo_create(): Argument #1 ($connection) must be of type PgSql when the connection is provided int(%d) int(%d) diff --git a/ext/pgsql/tests/no_link_open.phpt b/ext/pgsql/tests/no_link_open.phpt index 051ce38f198f3..e6c4b9778424f 100644 --- a/ext/pgsql/tests/no_link_open.phpt +++ b/ext/pgsql/tests/no_link_open.phpt @@ -11,4 +11,4 @@ try { ?> --EXPECT-- -No PostgreSQL link opened yet +No PostgreSQL connection opened yet diff --git a/ext/pgsql/tests/skipif.inc b/ext/pgsql/tests/skipif.inc index 92712f3e05ea7..bf32d6b16f622 100644 --- a/ext/pgsql/tests/skipif.inc +++ b/ext/pgsql/tests/skipif.inc @@ -18,7 +18,7 @@ if (getenv("SKIP_REPEAT")) { die("skip Cannot repeat pgsql tests"); } $conn = @pg_connect($conn_str); -if (!is_resource($conn)) { +if (!$conn) { die("skip could not connect\n"); } From f313d5ae6f9201f80d33adfdeea97f0079181a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 22 Mar 2021 09:37:26 +0100 Subject: [PATCH 02/14] Fix build and remove outdated comment --- ext/pgsql/pgsql.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 3b127204fe52b..55e76cf917145 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1498,7 +1498,6 @@ PHP_FUNCTION(pg_last_notice) zval *pgsql_link = NULL; zval *notice, *notices; pgsql_link_handle *link; - PGconn *pg_link; zend_long option = PGSQL_NOTICE_LAST; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &pgsql_link, pgsql_link_ce, &option) == FAILURE) { @@ -1507,7 +1506,6 @@ PHP_FUNCTION(pg_last_notice) link = Z_PGSQL_LINK_P(pgsql_link); CHECK_PGSQL_LINK(link); - pg_link = link->conn; notices = zend_hash_index_find(&PGG(notices), (zend_ulong) Z_OBJ_P(pgsql_link)->handle); switch (option) { @@ -3307,7 +3305,6 @@ PHP_FUNCTION(pg_escape_string) } to = zend_string_safe_alloc(ZSTR_LEN(from), 2, 0, 0); - // TODO When can it ben null? if (link) { pgsql = link->conn; ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), NULL); From 0d52aa75e8c16205fb9710cb3f420e615a2c9b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Wed, 24 Mar 2021 12:04:19 +0100 Subject: [PATCH 03/14] Get rid of memory leak, improve default connection handling, fix a few tests --- ext/pgsql/pgsql.c | 19 +++++++++---------- ext/pgsql/php_pgsql.h | 2 +- ext/pgsql/tests/09notice.phpt | 3 ++- ext/pgsql/tests/10pg_convert_9.phpt | 2 +- ext/pgsql/tests/12pg_insert_9.phpt | 5 +++-- ext/pgsql/tests/13pg_select_9.phpt | 2 +- ext/pgsql/tests/80_bug32223.phpt | 6 ++++-- ext/pgsql/tests/connect_after_close.phpt | 1 + 8 files changed, 22 insertions(+), 18 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 55e76cf917145..3776dcf05a434 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -78,7 +78,7 @@ zend_throw_error(NULL, "No PostgreSQL connection opened yet"); \ RETURN_THROWS(); \ } -#define FETCH_DEFAULT_LINK() (PGG(default_link) ? pgsql_link_from_obj(Z_OBJ_P(PGG(default_link))) : NULL) +#define FETCH_DEFAULT_LINK() PGG(default_link) #define CHECK_PGSQL_LINK(link_handle) \ if (link_handle->conn == NULL) { \ @@ -281,10 +281,8 @@ static zend_string *_php_pgsql_trim_message(const char *message) zend_string_release(msgbuf); \ } \ -static void php_pgsql_set_default_link(zval *link) +static void php_pgsql_set_default_link(pgsql_link_handle *link) { - GC_ADDREF(Z_OBJ_P(link)); - if (PGG(default_link) != NULL) { pgsql_link_free(FETCH_DEFAULT_LINK()); } @@ -730,7 +728,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) */ if (!(connect_type & PGSQL_CONNECT_FORCE_NEW) && (index_ptr = zend_hash_find_ptr(&PGG(regular_list), str.s)) != NULL) { - php_pgsql_set_default_link(index_ptr); + php_pgsql_set_default_link(pgsql_link_from_obj(Z_OBJ_P(index_ptr))); GC_ADDREF(Z_OBJ_P(index_ptr)); ZVAL_COPY(return_value, index_ptr); @@ -768,7 +766,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* add it to the hash */ ZVAL_COPY(&new_index_ptr, return_value); - zend_hash_update_mem(&PGG(regular_list), str.s, (void *) &new_index_ptr, sizeof(zval)); + zend_hash_update(&PGG(regular_list), str.s, &new_index_ptr); /* Keep track of link => hash mapping, so we can remove the hash entry from regular_list * when the connection is closed. This uses the address of the connection rather than the @@ -785,7 +783,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_OBJECT) { PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)(zend_uintptr_t)Z_OBJ_P(return_value)->handle); } - php_pgsql_set_default_link(return_value); + php_pgsql_set_default_link(pgsql_link_from_obj(Z_OBJ_P(return_value))); cleanup: smart_str_free(&str); @@ -846,8 +844,8 @@ PHP_FUNCTION(pg_close) if (!pgsql_link) { link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); - pgsql_link_free(link); PGG(default_link) = NULL; + pgsql_link_free(link); RETURN_TRUE; } @@ -2330,12 +2328,13 @@ PHP_FUNCTION(pg_lo_create) } else if ((Z_TYPE_P(pgsql_link) == IS_OBJECT && instanceof_function(Z_OBJCE_P(pgsql_link), pgsql_link_ce))) { link = Z_PGSQL_LINK_P(pgsql_link); CHECK_PGSQL_LINK(link); - pgsql = link->conn; } else { zend_argument_type_error(1, "must be of type PgSql when the connection is provided"); RETURN_THROWS(); } + pgsql = link->conn; + if (oid) { switch (Z_TYPE_P(oid)) { case IS_STRING: @@ -3300,7 +3299,7 @@ PHP_FUNCTION(pg_escape_string) RETURN_THROWS(); } link = Z_PGSQL_LINK_P(pgsql_link); - CHECK_PGSQL_LINK(link); + CHECK_PGSQL_LINK(link); break; } diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 9d2d5e768cd6b..bfaa2a664850c 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -185,7 +185,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) zend_long auto_reset_persistent; int ignore_notices,log_notices; HashTable notices; /* notice message for each connection */ - zval *default_link; /* default link when connection is omitted */ + pgsql_link_handle *default_link; /* default link when connection is omitted */ HashTable hashes; /* hashes for each connection */ HashTable field_oids; HashTable table_oids; diff --git a/ext/pgsql/tests/09notice.phpt b/ext/pgsql/tests/09notice.phpt index f1f971195052e..4332d816b17b8 100644 --- a/ext/pgsql/tests/09notice.phpt +++ b/ext/pgsql/tests/09notice.phpt @@ -49,7 +49,8 @@ try { } ?> --EXPECTF-- -resource(%d) of type (pgsql result) +object(PgSqlResult)#%d (0) { +} string(0) "" array(0) { } diff --git a/ext/pgsql/tests/10pg_convert_9.phpt b/ext/pgsql/tests/10pg_convert_9.phpt index 0a2828a247da4..328413ec7cd1c 100644 --- a/ext/pgsql/tests/10pg_convert_9.phpt +++ b/ext/pgsql/tests/10pg_convert_9.phpt @@ -60,4 +60,4 @@ Array of values must be an associative array with string keys Array of values must be an associative array with string keys Values must be of type string|int|float|bool|null, array given Values must be of type string|int|float|bool|null, stdClass given -Values must be of type string|int|float|bool|null, resource given +Values must be of type string|int|float|bool|null, PgSql given diff --git a/ext/pgsql/tests/12pg_insert_9.phpt b/ext/pgsql/tests/12pg_insert_9.phpt index 833b1481c76be..1098405c69359 100644 --- a/ext/pgsql/tests/12pg_insert_9.phpt +++ b/ext/pgsql/tests/12pg_insert_9.phpt @@ -54,10 +54,11 @@ echo "Ok\n"; --EXPECTF-- INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES (1234,E'AAA',E'\\x424242'); INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES ('1234','AAA','BBB'); -resource(%d) of type (pgsql result) +object(PgSqlResult)#%d (0) { +} Array of values must be an associative array with string keys Array of values must be an associative array with string keys Values must be of type string|int|float|bool|null, array given Values must be of type string|int|float|bool|null, stdClass given -Values must be of type string|int|float|bool|null, resource given +Values must be of type string|int|float|bool|null, PgSql given Ok diff --git a/ext/pgsql/tests/13pg_select_9.phpt b/ext/pgsql/tests/13pg_select_9.phpt index 6de11e1cb5d00..ef0c08e7d432e 100644 --- a/ext/pgsql/tests/13pg_select_9.phpt +++ b/ext/pgsql/tests/13pg_select_9.phpt @@ -81,5 +81,5 @@ Array of values must be an associative array with string keys Array of values must be an associative array with string keys Values must be of type string|int|float|bool|null, array given Values must be of type string|int|float|bool|null, stdClass given -Values must be of type string|int|float|bool|null, resource given +Values must be of type string|int|float|bool|null, PgSql given Ok diff --git a/ext/pgsql/tests/80_bug32223.phpt b/ext/pgsql/tests/80_bug32223.phpt index 08c8903dbf8b2..10c463358247a 100644 --- a/ext/pgsql/tests/80_bug32223.phpt +++ b/ext/pgsql/tests/80_bug32223.phpt @@ -53,8 +53,10 @@ pg_close($dbh); ?> --EXPECTF-- -resource(%d) of type (pgsql result) -resource(%d) of type (pgsql result) +object(PgSqlResult)#%d (0) { +} +object(PgSqlResult)#%d (0) { +} array(1) { [0]=> string(1) "f" diff --git a/ext/pgsql/tests/connect_after_close.phpt b/ext/pgsql/tests/connect_after_close.phpt index 65f954570b08e..329c2879545ae 100644 --- a/ext/pgsql/tests/connect_after_close.phpt +++ b/ext/pgsql/tests/connect_after_close.phpt @@ -10,6 +10,7 @@ include('config.inc'); $db1 = pg_connect($conn_str); unset($db1); var_dump(pg_close()); +exit; $db2 = pg_connect($conn_str); unset($db2); var_dump(pg_close()); From 50298ada05be066a5c707987dceb45b1a55d7b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Wed, 24 Mar 2021 23:37:02 +0100 Subject: [PATCH 04/14] Get rid of the hashes global hash The idea came up in https://github.com/php/php-src/commit/c7a86a38a3f657ab81163ac794450fc7ada2ba3c --- ext/pgsql/pgsql.c | 18 ++++-------------- ext/pgsql/php_pgsql.h | 1 + 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 3776dcf05a434..7ff1908e944b5 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -160,7 +160,6 @@ static zend_function *pgsql_link_get_constructor(zend_object *object) { static void pgsql_link_free(pgsql_link_handle *link) { PGresult *res; - zval *hash; while ((res = PQgetResult(link->conn))) { PQclear(res); @@ -168,14 +167,10 @@ static void pgsql_link_free(pgsql_link_handle *link) PQfinish(link->conn); PGG(num_links)--; - /* Remove connection hash for this link */ - hash = zend_hash_index_find(&PGG(hashes), (uintptr_t) link->conn); - if (hash) { - zend_hash_index_del(&PGG(hashes), (uintptr_t) link->conn); - zend_hash_del(&PGG(regular_list), Z_STR_P(hash)); - } + zend_hash_del(&PGG(regular_list), link->hash); link->conn = NULL; + zend_string_release(link->hash); } static void pgsql_link_free_obj(zend_object *obj) @@ -406,7 +401,6 @@ static PHP_GINIT_FUNCTION(pgsql) memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); /* Initialize notice message hash at MINIT only */ zend_hash_init(&pgsql_globals->notices, 0, NULL, ZVAL_PTR_DTOR, 1); - zend_hash_init(&pgsql_globals->hashes, 0, NULL, ZVAL_PTR_DTOR, 1); zend_hash_init(&pgsql_globals->regular_list, 0, NULL, ZVAL_PTR_DTOR, 1); } @@ -578,7 +572,6 @@ PHP_MSHUTDOWN_FUNCTION(pgsql) { UNREGISTER_INI_ENTRIES(); zend_hash_destroy(&PGG(notices)); - zend_hash_destroy(&PGG(hashes)); zend_hash_destroy(&PGG(regular_list)); return SUCCESS; @@ -763,6 +756,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) object_init_ex(return_value, pgsql_link_ce); link = Z_PGSQL_LINK_P(return_value); link->conn = pgsql; + link->hash = zend_string_copy(str.s); /* add it to the hash */ ZVAL_COPY(&new_index_ptr, return_value); @@ -772,11 +766,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) * when the connection is closed. This uses the address of the connection rather than the * zend_resource, because the resource destructor is passed a stack copy of the resource * structure. */ - { - zval tmp; - ZVAL_STR_COPY(&tmp, str.s); - zend_hash_index_update(&PGG(hashes), (uintptr_t) pgsql, &tmp); - } + PGG(num_links)++; } /* set notice processor */ diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index bfaa2a664850c..128d93a0cbac9 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -145,6 +145,7 @@ typedef enum _php_pgsql_data_type { typedef struct pgsql_link_handle { PGconn *conn; + zend_string *hash; zend_object std; } pgsql_link_handle; From b86b71d6d1c1830d61e8ec696a75a4f5b18027e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Thu, 25 Mar 2021 00:50:43 +0100 Subject: [PATCH 05/14] Get rid of global notices hash The idea came up in https://github.com/php/php-src/commit/c7a86a38a3f657ab81163ac794450fc7ada2ba3c --- ext/pgsql/pgsql.c | 31 ++++++++++++++++++------------- ext/pgsql/php_pgsql.h | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 7ff1908e944b5..5c922813fe348 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -171,6 +171,9 @@ static void pgsql_link_free(pgsql_link_handle *link) link->conn = NULL; zend_string_release(link->hash); + if (link->notices) { + zend_hash_destroy(link->notices); + } } static void pgsql_link_free_obj(zend_object *obj) @@ -298,14 +301,15 @@ static void _close_pgsql_plink(zend_resource *rsrc) PGG(num_links)--; } -static void _php_pgsql_notice_handler(void *resource_id, const char *message) +static void _php_pgsql_notice_handler(void *link, const char *message) { if (PGG(ignore_notices)) { return; } + HashTable *notices, tmp_notices; zval tmp; - zval *notices = zend_hash_index_find(&PGG(notices), (zend_ulong)resource_id); + zval *notices = notices = ((pgsql_link_handle *) link)->notices; if (!notices) { array_init(&tmp); notices = &tmp; @@ -400,7 +404,6 @@ static PHP_GINIT_FUNCTION(pgsql) #endif memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); /* Initialize notice message hash at MINIT only */ - zend_hash_init(&pgsql_globals->notices, 0, NULL, ZVAL_PTR_DTOR, 1); zend_hash_init(&pgsql_globals->regular_list, 0, NULL, ZVAL_PTR_DTOR, 1); } @@ -571,7 +574,6 @@ PHP_MINIT_FUNCTION(pgsql) PHP_MSHUTDOWN_FUNCTION(pgsql) { UNREGISTER_INI_ENTRIES(); - zend_hash_destroy(&PGG(notices)); zend_hash_destroy(&PGG(regular_list)); return SUCCESS; @@ -589,7 +591,6 @@ PHP_RINIT_FUNCTION(pgsql) PHP_RSHUTDOWN_FUNCTION(pgsql) { /* clean up notice messages */ - zend_hash_clean(&PGG(notices)); zend_hash_clean(&PGG(hashes)); zend_hash_destroy(&PGG(field_oids)); zend_hash_destroy(&PGG(table_oids)); @@ -711,6 +712,8 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) object_init_ex(return_value, pgsql_link_ce); link = Z_PGSQL_LINK_P(return_value); link->conn = pgsql; + link->hash = zend_string_copy(str.s); + link->notices = NULL; } else { /* Non persistent connection */ zval *index_ptr, new_index_ptr; @@ -757,6 +760,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) link = Z_PGSQL_LINK_P(return_value); link->conn = pgsql; link->hash = zend_string_copy(str.s); + link->notices = NULL; /* add it to the hash */ ZVAL_COPY(&new_index_ptr, return_value); @@ -771,9 +775,9 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) } /* set notice processor */ if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_OBJECT) { - PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)(zend_uintptr_t)Z_OBJ_P(return_value)->handle); + PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, link); } - php_pgsql_set_default_link(pgsql_link_from_obj(Z_OBJ_P(return_value))); + php_pgsql_set_default_link(link); cleanup: smart_str_free(&str); @@ -1484,7 +1488,8 @@ PHP_FUNCTION(pg_affected_rows) PHP_FUNCTION(pg_last_notice) { zval *pgsql_link = NULL; - zval *notice, *notices; + zval *notice; + HashTable *notices; pgsql_link_handle *link; zend_long option = PGSQL_NOTICE_LAST; @@ -1495,12 +1500,12 @@ PHP_FUNCTION(pg_last_notice) link = Z_PGSQL_LINK_P(pgsql_link); CHECK_PGSQL_LINK(link); - notices = zend_hash_index_find(&PGG(notices), (zend_ulong) Z_OBJ_P(pgsql_link)->handle); + notices = link->notices; switch (option) { case PGSQL_NOTICE_LAST: if (notices) { - zend_hash_internal_pointer_end(Z_ARRVAL_P(notices)); - if ((notice = zend_hash_get_current_data(Z_ARRVAL_P(notices))) == NULL) { + zend_hash_internal_pointer_end(notices); + if ((notice = zend_hash_get_current_data(notices)) == NULL) { RETURN_EMPTY_STRING(); } RETURN_COPY(notice); @@ -1510,7 +1515,7 @@ PHP_FUNCTION(pg_last_notice) break; case PGSQL_NOTICE_ALL: if (notices) { - RETURN_COPY(notices); + RETURN_ARR(zend_array_dup(notices)); } else { array_init(return_value); return; @@ -1518,7 +1523,7 @@ PHP_FUNCTION(pg_last_notice) break; case PGSQL_NOTICE_CLEAR: if (notices) { - zend_hash_clean(&PGG(notices)); + zend_hash_clean(link->notices); } RETURN_TRUE; break; diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 128d93a0cbac9..b965b6d76fff3 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -146,6 +146,7 @@ typedef enum _php_pgsql_data_type { typedef struct pgsql_link_handle { PGconn *conn; zend_string *hash; + HashTable *notices; zend_object std; } pgsql_link_handle; @@ -185,7 +186,6 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) zend_long allow_persistent; zend_long auto_reset_persistent; int ignore_notices,log_notices; - HashTable notices; /* notice message for each connection */ pgsql_link_handle *default_link; /* default link when connection is omitted */ HashTable hashes; /* hashes for each connection */ HashTable field_oids; From efd10499d2b820384dce80c002b31d97e47b0810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 2 Apr 2021 18:52:27 +0200 Subject: [PATCH 06/14] New test fixes --- Zend/Optimizer/zend_func_info.c | 20 ++++---- ext/pgsql/pgsql.c | 61 +++++++++++++----------- ext/pgsql/php_pgsql.h | 1 + ext/pgsql/tests/13pg_select_9.phpt | 1 - ext/pgsql/tests/80_bug32223b.phpt | 23 ++++----- ext/pgsql/tests/bug46408.phpt | 6 +-- ext/pgsql/tests/connect_after_close.phpt | 2 +- 7 files changed, 59 insertions(+), 55 deletions(-) diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index 406b827aa926a..3169db44f5ed4 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -658,8 +658,8 @@ static const func_info_t func_infos[] = { F1("session_encode", MAY_BE_FALSE | MAY_BE_STRING), /* ext/pgsql */ - FN("pg_connect", MAY_BE_FALSE | MAY_BE_RESOURCE), - FN("pg_pconnect", MAY_BE_FALSE | MAY_BE_RESOURCE), + FN("pg_connect", MAY_BE_FALSE | MAY_BE_OBJECT), + FN("pg_pconnect", MAY_BE_FALSE | MAY_BE_OBJECT), F1("pg_dbname", MAY_BE_STRING), F1("pg_options", MAY_BE_STRING), F1("pg_port", MAY_BE_STRING), @@ -667,10 +667,10 @@ static const func_info_t func_infos[] = { F1("pg_host", MAY_BE_STRING), F1("pg_version", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_NULL), F1("pg_parameter_status", MAY_BE_FALSE | MAY_BE_STRING), - F1("pg_query", MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("pg_query_params", MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("pg_prepare", MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("pg_execute", MAY_BE_FALSE | MAY_BE_RESOURCE), + F1("pg_query", MAY_BE_FALSE | MAY_BE_OBJECT), + F1("pg_query_params", MAY_BE_FALSE | MAY_BE_OBJECT), + F1("pg_prepare", MAY_BE_FALSE | MAY_BE_OBJECT), + F1("pg_execute", MAY_BE_FALSE | MAY_BE_OBJECT), FN("pg_last_notice", MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_STRING | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY ), F1("pg_field_name", MAY_BE_STRING), F1("pg_field_type_oid", MAY_BE_LONG | MAY_BE_STRING), @@ -683,7 +683,7 @@ static const func_info_t func_infos[] = { F1("pg_fetch_all_columns", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_STRING), F1("pg_last_oid", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING), F1("pg_lo_create", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING), - F1("pg_lo_open", MAY_BE_FALSE | MAY_BE_RESOURCE), + F1("pg_lo_open", MAY_BE_FALSE | MAY_BE_OBJECT), F1("pg_lo_read", MAY_BE_FALSE | MAY_BE_STRING), F1("pg_lo_import", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING), F1("pg_copy_to", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING), @@ -694,13 +694,13 @@ static const func_info_t func_infos[] = { F1("pg_escape_identifier", MAY_BE_FALSE | MAY_BE_STRING), F1("pg_result_error", MAY_BE_FALSE | MAY_BE_STRING), F1("pg_result_error_field", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("pg_get_result", MAY_BE_FALSE | MAY_BE_RESOURCE), + F1("pg_get_result", MAY_BE_FALSE | MAY_BE_OBJECT), F1("pg_result_status", MAY_BE_LONG | MAY_BE_STRING), F1("pg_get_notify", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY), - F1("pg_socket", MAY_BE_FALSE | MAY_BE_RESOURCE), + F1("pg_socket", MAY_BE_FALSE | MAY_BE_OBJECT), F1("pg_meta_data", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ARRAY), F1("pg_convert", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ANY), - F1("pg_insert", MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_RESOURCE | MAY_BE_STRING), + F1("pg_insert", MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_OBJECT | MAY_BE_STRING), F1("pg_update", MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_STRING), F1("pg_delete", MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_STRING), F1("pg_select", MAY_BE_FALSE | MAY_BE_STRING | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_ARRAY), diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 5c922813fe348..dcb90fc83cfd7 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -164,15 +164,20 @@ static void pgsql_link_free(pgsql_link_handle *link) while ((res = PQgetResult(link->conn))) { PQclear(res); } - PQfinish(link->conn); + if (!link->persistent) { + PQfinish(link->conn); + } PGG(num_links)--; zend_hash_del(&PGG(regular_list), link->hash); link->conn = NULL; zend_string_release(link->hash); + if (link->notices) { zend_hash_destroy(link->notices); + FREE_HASHTABLE(link->notices); + link->notices = NULL; } } @@ -281,46 +286,46 @@ static zend_string *_php_pgsql_trim_message(const char *message) static void php_pgsql_set_default_link(pgsql_link_handle *link) { - if (PGG(default_link) != NULL) { - pgsql_link_free(FETCH_DEFAULT_LINK()); - } - PGG(default_link) = link; } static void _close_pgsql_plink(zend_resource *rsrc) { - PGconn *link = (PGconn *)rsrc->ptr; - PGresult *res; + if (rsrc->ptr) { + PGconn *link = (PGconn *)rsrc->ptr; + PGresult *res; - while ((res = PQgetResult(link))) { - PQclear(res); + while ((res = PQgetResult(link))) { + PQclear(res); + } + PQfinish(link); + PGG(num_persistent)--; + PGG(num_links)--; + rsrc->ptr = NULL; } - PQfinish(link); - PGG(num_persistent)--; - PGG(num_links)--; } -static void _php_pgsql_notice_handler(void *link, const char *message) +static void _php_pgsql_notice_handler(void *l, const char *message) { if (PGG(ignore_notices)) { return; } + pgsql_link_handle *link; HashTable *notices, tmp_notices; zval tmp; - zval *notices = notices = ((pgsql_link_handle *) link)->notices; - if (!notices) { - array_init(&tmp); - notices = &tmp; - zend_hash_index_update(&PGG(notices), (zend_ulong)resource_id, notices); + + link = ((pgsql_link_handle *) l); + if (!link->notices) { + link->notices = zend_new_array(1); } zend_string *trimmed_message = _php_pgsql_trim_message(message); if (PGG(log_notices)) { php_error_docref(NULL, E_NOTICE, "%s", ZSTR_VAL(trimmed_message)); } - add_next_index_str(notices, trimmed_message); + + add_next_index_str(link->notices, trimmed_message); } static int _rollback_transactions(zval *el) @@ -329,8 +334,9 @@ static int _rollback_transactions(zval *el) PGresult *res; zend_resource *rsrc = Z_RES_P(el); - if (rsrc->type != le_plink) - return 0; + if (rsrc->type != le_plink) { + return ZEND_HASH_APPLY_KEEP; + } link = (PGconn *) rsrc->ptr; @@ -350,7 +356,7 @@ static int _rollback_transactions(zval *el) PGG(ignore_notices) = orig; } - return 0; + return ZEND_HASH_APPLY_KEEP; } static void _free_ptr(zend_resource *rsrc) @@ -403,7 +409,6 @@ static PHP_GINIT_FUNCTION(pgsql) ZEND_TSRMLS_CACHE_UPDATE(); #endif memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); - /* Initialize notice message hash at MINIT only */ zend_hash_init(&pgsql_globals->regular_list, 0, NULL, ZVAL_PTR_DTOR, 1); } @@ -590,11 +595,8 @@ PHP_RINIT_FUNCTION(pgsql) PHP_RSHUTDOWN_FUNCTION(pgsql) { - /* clean up notice messages */ - zend_hash_clean(&PGG(hashes)); zend_hash_destroy(&PGG(field_oids)); zend_hash_destroy(&PGG(table_oids)); - zend_hash_clean(&PGG(regular_list)); /* clean up persistent connection */ zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions); return SUCCESS; @@ -714,6 +716,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) link->conn = pgsql; link->hash = zend_string_copy(str.s); link->notices = NULL; + link->persistent = 1; } else { /* Non persistent connection */ zval *index_ptr, new_index_ptr; @@ -761,6 +764,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) link->conn = pgsql; link->hash = zend_string_copy(str.s); link->notices = NULL; + link->persistent = 0; /* add it to the hash */ ZVAL_COPY(&new_index_ptr, return_value); @@ -838,8 +842,8 @@ PHP_FUNCTION(pg_close) if (!pgsql_link) { link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); + zend_hash_del(&PGG(regular_list), link->hash); PGG(default_link) = NULL; - pgsql_link_free(link); RETURN_TRUE; } @@ -847,6 +851,7 @@ PHP_FUNCTION(pg_close) CHECK_PGSQL_LINK(link); if (link == FETCH_DEFAULT_LINK()) { + zend_hash_del(&PGG(regular_list), link->hash); PGG(default_link) = NULL; } pgsql_link_free(link); @@ -3328,7 +3333,6 @@ PHP_FUNCTION(pg_escape_bytea) RETURN_THROWS(); } link = FETCH_DEFAULT_LINK(); - CHECK_DEFAULT_LINK(link); break; default: if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &pgsql_link, pgsql_link_ce, &from) == FAILURE) { @@ -5643,7 +5647,6 @@ PHP_FUNCTION(pg_update) zval *pgsql_link, *values, *ids; pgsql_link_handle *link; zend_string *table; - size_t table_len; zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; zend_string *sql = NULL; diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index b965b6d76fff3..9dcf2c577858c 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -148,6 +148,7 @@ typedef struct pgsql_link_handle { zend_string *hash; HashTable *notices; zend_object std; + bool persistent; } pgsql_link_handle; typedef struct pgLofp { diff --git a/ext/pgsql/tests/13pg_select_9.phpt b/ext/pgsql/tests/13pg_select_9.phpt index ef0c08e7d432e..03ee9a6fd7e92 100644 --- a/ext/pgsql/tests/13pg_select_9.phpt +++ b/ext/pgsql/tests/13pg_select_9.phpt @@ -18,7 +18,6 @@ $fields = array('num'=>'1234', 'str'=>'ABC', 'bin'=>'XYZ'); $ids = array('num'=>'1234'); $res = pg_select($db, $table_name, $ids) or print "Error\n"; -var_dump(pg_last_error($db)); var_dump($res); echo pg_select($db, $table_name, $ids, PGSQL_DML_STRING)."\n"; echo pg_select($db, $table_name, $ids, PGSQL_DML_STRING|PGSQL_DML_ESCAPE)."\n"; diff --git a/ext/pgsql/tests/80_bug32223b.phpt b/ext/pgsql/tests/80_bug32223b.phpt index 058460435360e..4a482ce0dbf02 100644 --- a/ext/pgsql/tests/80_bug32223b.phpt +++ b/ext/pgsql/tests/80_bug32223b.phpt @@ -23,40 +23,41 @@ pgsql.ignore_notice=0 require_once('config.inc'); require_once('lcmess.inc'); -define('dbh', pg_connect($conn_str)); -if (!dbh) { - die ("Could not connect to the server"); +$dbh = pg_connect($conn_str); +if (!$dbh) { + die ("Could not connect to the server"); } _set_lc_messages(); -$res = pg_query(dbh, "CREATE OR REPLACE FUNCTION test_notice() RETURNS boolean AS ' +$res = pg_query($dbh, "CREATE OR REPLACE FUNCTION test_notice() RETURNS boolean AS ' begin RAISE NOTICE ''11111''; return ''f''; end; ' LANGUAGE plpgsql;"); -$res = pg_query(dbh, 'SET client_min_messages TO NOTICE;'); +$res = pg_query($dbh, 'SET client_min_messages TO NOTICE;'); var_dump($res); -function tester() { - $res = pg_query(dbh, 'SELECT test_notice()'); +function tester($dbh) { + $res = pg_query($dbh, 'SELECT test_notice()'); $row = pg_fetch_row($res, 0); var_dump($row); pg_free_result($res); if ($row[0] == 'f') { - var_dump(pg_last_notice(dbh)); + var_dump(pg_last_notice($dbh)); } } -tester(); +tester($dbh); -pg_close(dbh); +pg_close($dbh); ?> --EXPECTF-- -resource(%d) of type (pgsql result) +object(PgSqlResult)#%d (0) { +} array(1) { [0]=> string(1) "f" diff --git a/ext/pgsql/tests/bug46408.phpt b/ext/pgsql/tests/bug46408.phpt index bd0b78696f8f2..f78cca1cd0e04 100644 --- a/ext/pgsql/tests/bug46408.phpt +++ b/ext/pgsql/tests/bug46408.phpt @@ -3,8 +3,8 @@ Bug #46408 (Locale number format settings can cause pg_query_params to break wit --SKIPIF-- --FILE-- @@ -13,7 +13,7 @@ if (false === setlocale(LC_ALL, 'de_DE.utf-8', 'de_DE')) { require_once('config.inc'); $dbh = pg_connect($conn_str); -setlocale(LC_ALL, 'de_DE.utf-8', 'de_DE'); +setlocale(LC_ALL, "de", "de_DE", "de_DE.ISO8859-1", "de_DE.ISO_8859-1", "de_DE.UTF-8"); echo 3.5 , "\n"; pg_query_params("SELECT $1::numeric", array(3.5)); pg_close($dbh); diff --git a/ext/pgsql/tests/connect_after_close.phpt b/ext/pgsql/tests/connect_after_close.phpt index 329c2879545ae..932a06ed523ec 100644 --- a/ext/pgsql/tests/connect_after_close.phpt +++ b/ext/pgsql/tests/connect_after_close.phpt @@ -10,7 +10,7 @@ include('config.inc'); $db1 = pg_connect($conn_str); unset($db1); var_dump(pg_close()); -exit; + $db2 = pg_connect($conn_str); unset($db2); var_dump(pg_close()); From a745eb57746dcd84e772b345791a57c4cb0ec442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 26 Apr 2021 20:08:57 +0200 Subject: [PATCH 07/14] Address review comments --- NEWS | 7 +- UPGRADING | 13 +- ext/pgsql/pgsql.c | 37 +- ext/pgsql/pgsql.stub.php | 634 +++++++++--------- ext/pgsql/pgsql_arginfo.h | 132 ++-- ext/pgsql/php_pgsql.h | 4 +- ext/pgsql/tests/02connection.phpt | 2 +- ext/pgsql/tests/09notice.phpt | 2 +- ext/pgsql/tests/10pg_convert_9.phpt | 2 +- ext/pgsql/tests/12pg_insert_9.phpt | 4 +- ext/pgsql/tests/13pg_select_9.phpt | 2 +- .../tests/28large_object_import_oid.phpt | 2 +- ext/pgsql/tests/80_bug32223.phpt | 4 +- ext/pgsql/tests/80_bug32223b.phpt | 2 +- ext/pgsql/tests/80_bug36625.phpt | 2 +- 15 files changed, 422 insertions(+), 427 deletions(-) diff --git a/NEWS b/NEWS index 2f80c442e4f5a..586097b5b4cec 100644 --- a/NEWS +++ b/NEWS @@ -99,10 +99,9 @@ PHP NEWS . Fixed bug #38334 (Proper data-type support for PDO_SQLITE). (Nikita) - PgSQL: - . Convert resource to object \PgSql. (Máté) - . Convert resource to object \PgSqlResult. (Máté) - . Convert resource to object \PgSqlLob. (Máté) - . Convert resource to object \PgsqlString. (Máté) + . Convert resource to object \PgSql\Connection. (Máté) + . Convert resource to object \PgSql\Result. (Máté) + . Convert resource to object \PgSql\Lob. (Máté) - PSpell: . Convert resource to object \PSpell\Dictionary. (Sara) diff --git a/UPGRADING b/UPGRADING index ec0f59e1a8cdd..5a6c736e364eb 100644 --- a/UPGRADING +++ b/UPGRADING @@ -121,18 +121,15 @@ PHP 8.1 UPGRADE NOTES PDO::ATTR_STRINGIFY_FETCHES option. - PgSQL: - . The PgSQL functions now accept and return, respectively, PgSql objects - instead of "pgsql link" resources. Return value checks using is_resource() - should be replaced with checks for `false`. - . The PgSQL functions now accept and return, respectively, PgSqlResult + . The PgSQL functions now accept and return, respectively, \PgSql\Connection + objects instead of "pgsql link" resources. Return value checks using + is_resource() should be replaced with checks for `false`. + . The PgSQL functions now accept and return, respectively, \PgSql\Result objects instead of "pgsql result" resources. Return value checks using is_resource() should be replaced with checks for `false`. - . The PgSQL functions now accept and return, respectively, PgSqlLob + . The PgSQL functions now accept and return, respectively, \PgSql\Lob objects instead of "pgsql large object" resources. Return value checks using is_resource() should be replaced with checks for `false`. - . The PgSQL functions now accept and return, respectively, PgSqlString - objects instead of "pgsql string" resources. Return value checks - using is_resource() should be replaced with checks for `false`. - PSpell: . The PSpell functions now accept and return, respectively, PSpell\Dictionary objects diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index dcb90fc83cfd7..e434f8a5a5816 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -169,7 +169,7 @@ static void pgsql_link_free(pgsql_link_handle *link) } PGG(num_links)--; - zend_hash_del(&PGG(regular_list), link->hash); + zend_hash_del(&PGG(connections), link->hash); link->conn = NULL; zend_string_release(link->hash); @@ -257,7 +257,6 @@ static void pgsql_lob_free_obj(zend_object *obj) zend_object_std_dtor(&lofp->std); } -static int le_link, le_plink, le_result, le_lofp; /* Compatibility definitions */ @@ -286,6 +285,8 @@ static zend_string *_php_pgsql_trim_message(const char *message) static void php_pgsql_set_default_link(pgsql_link_handle *link) { + GC_ADDREF(res); + PGG(default_link) = link; } @@ -312,10 +313,9 @@ static void _php_pgsql_notice_handler(void *l, const char *message) } pgsql_link_handle *link; - HashTable *notices, tmp_notices; zval tmp; - link = ((pgsql_link_handle *) l); + link = (pgsql_link_handle *) l; if (!link->notices) { link->notices = zend_new_array(1); } @@ -325,7 +325,8 @@ static void _php_pgsql_notice_handler(void *l, const char *message) php_error_docref(NULL, E_NOTICE, "%s", ZSTR_VAL(trimmed_message)); } - add_next_index_str(link->notices, trimmed_message); + ZVAL_STR(&tmp, trimmed_message); + zend_hash_next_index_insert(link->notices, &tmp); } static int _rollback_transactions(zval *el) @@ -359,12 +360,6 @@ static int _rollback_transactions(zval *el) return ZEND_HASH_APPLY_KEEP; } -static void _free_ptr(zend_resource *rsrc) -{ - pgLofp *lofp = (pgLofp *)rsrc->ptr; - efree(lofp); -} - static void release_string(zval *zv) { zend_string_release((zend_string *) Z_PTR_P(zv)); @@ -409,7 +404,7 @@ static PHP_GINIT_FUNCTION(pgsql) ZEND_TSRMLS_CACHE_UPDATE(); #endif memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); - zend_hash_init(&pgsql_globals->regular_list, 0, NULL, ZVAL_PTR_DTOR, 1); + zend_hash_init(&pgsql_globals->connections, 0, NULL, ZVAL_PTR_DTOR, 1); } static void php_libpq_version(char *buf, size_t len) @@ -434,7 +429,7 @@ PHP_MINIT_FUNCTION(pgsql) le_plink = zend_register_list_destructors_ex(NULL, _close_pgsql_plink, "pgsql link persistent", module_number); - pgsql_link_ce = register_class_PgSql(); + pgsql_link_ce = register_class_PgSql_Connection(); pgsql_link_ce->create_object = pgsql_link_create_object; pgsql_link_ce->serialize = zend_class_serialize_deny; pgsql_link_ce->unserialize = zend_class_unserialize_deny; @@ -446,7 +441,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_link_object_handlers.clone_obj = NULL; pgsql_link_object_handlers.compare = zend_objects_not_comparable; - pgsql_result_ce = register_class_PgSqlResult(); + pgsql_result_ce = register_class_PgSql_Result(); pgsql_result_ce->create_object = pgsql_result_create_object; pgsql_result_ce->serialize = zend_class_serialize_deny; pgsql_result_ce->unserialize = zend_class_unserialize_deny; @@ -458,7 +453,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_result_object_handlers.clone_obj = NULL; pgsql_result_object_handlers.compare = zend_objects_not_comparable; - pgsql_lob_ce = register_class_PgSqlLob(); + pgsql_lob_ce = register_class_PgSql_Lob(); pgsql_lob_ce->create_object = pgsql_lob_create_object; pgsql_lob_ce->serialize = zend_class_serialize_deny; pgsql_lob_ce->unserialize = zend_class_unserialize_deny; @@ -579,7 +574,7 @@ PHP_MINIT_FUNCTION(pgsql) PHP_MSHUTDOWN_FUNCTION(pgsql) { UNREGISTER_INI_ENTRIES(); - zend_hash_destroy(&PGG(regular_list)); + zend_hash_destroy(&PGG(connections)); return SUCCESS; } @@ -726,7 +721,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) * and add a pointer to it with hashed_details as the key. */ if (!(connect_type & PGSQL_CONNECT_FORCE_NEW) - && (index_ptr = zend_hash_find_ptr(&PGG(regular_list), str.s)) != NULL) { + && (index_ptr = zend_hash_find_ptr(&PGG(connections), str.s)) != NULL) { php_pgsql_set_default_link(pgsql_link_from_obj(Z_OBJ_P(index_ptr))); GC_ADDREF(Z_OBJ_P(index_ptr)); ZVAL_COPY(return_value, index_ptr); @@ -768,9 +763,9 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* add it to the hash */ ZVAL_COPY(&new_index_ptr, return_value); - zend_hash_update(&PGG(regular_list), str.s, &new_index_ptr); + zend_hash_update(&PGG(connections), str.s, &new_index_ptr); - /* Keep track of link => hash mapping, so we can remove the hash entry from regular_list + /* Keep track of link => hash mapping, so we can remove the hash entry from connections * when the connection is closed. This uses the address of the connection rather than the * zend_resource, because the resource destructor is passed a stack copy of the resource * structure. */ @@ -842,7 +837,7 @@ PHP_FUNCTION(pg_close) if (!pgsql_link) { link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); - zend_hash_del(&PGG(regular_list), link->hash); + zend_hash_del(&PGG(connections), link->hash); PGG(default_link) = NULL; RETURN_TRUE; } @@ -851,7 +846,7 @@ PHP_FUNCTION(pg_close) CHECK_PGSQL_LINK(link); if (link == FETCH_DEFAULT_LINK()) { - zend_hash_del(&PGG(regular_list), link->hash); + zend_hash_del(&PGG(connections), link->hash); PGG(default_link) = NULL; } pgsql_link_free(link); diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php index 6180a49d4edbf..68e0d359ad380 100644 --- a/ext/pgsql/pgsql.stub.php +++ b/ext/pgsql/pgsql.stub.php @@ -2,407 +2,411 @@ /** @generate-class-entries */ -/** @strict-properties */ -final class PgSql -{ +namespace PgSql { + /** @strict-properties */ + final class Connection + { + } + + /** @strict-properties */ + final class Result + { + } + + /** @strict-properties */ + final class Lob + { + } } -/** @strict-properties */ -final class PgSqlResult -{ -} - -/** @strict-properties */ -final class PgSqlLob -{ -} +namespace { + function pg_connect(string $connection_string, int $flags = 0): PgSql\Connection|false {} -function pg_connect(string $connection_string, int $flags = 0): PgSql|false {} + function pg_pconnect(string $connection_string, int $flags = 0): PgSql\Connection|false {} -function pg_pconnect(string $connection_string, int $flags = 0): PgSql|false {} + function pg_connect_poll(PgSql\Connection $connection): int {} -function pg_connect_poll(PgSql $connection): int {} + function pg_close(?PgSql\Connection $connection = null): bool {} -function pg_close(?PgSql $connection = null): bool {} + function pg_dbname(?PgSql\Connection $connection = null): string {} -function pg_dbname(?PgSql $connection = null): string {} + function pg_last_error(?PgSql\Connection $connection = null): string {} -function pg_last_error(?PgSql $connection = null): string {} + /** + * @alias pg_last_error + * @deprecated + */ + function pg_errormessage(?PgSql\Connection $connection = null): string {} -/** - * @alias pg_last_error - * @deprecated - */ -function pg_errormessage(?PgSql $connection = null): string {} + function pg_options(?PgSql\Connection $connection = null): string {} -function pg_options(?PgSql $connection = null): string {} + function pg_port(?PgSql\Connection $connection = null): string {} -function pg_port(?PgSql $connection = null): string {} + function pg_tty(?PgSql\Connection $connection = null): string {} -function pg_tty(?PgSql $connection = null): string {} + function pg_host(?PgSql\Connection $connection = null): string {} -function pg_host(?PgSql $connection = null): string {} + function pg_version(?PgSql\Connection $connection = null): array {} -function pg_version(?PgSql $connection = null): array {} + /** @param PgSql\Connection|string $connection */ + function pg_parameter_status($connection, string $name = UNKNOWN): string|false {} -/** @param PgSql|string $connection */ -function pg_parameter_status($connection, string $name = UNKNOWN): string|false {} + function pg_ping(?PgSql\Connection $connection = null): bool {} -function pg_ping(?PgSql $connection = null): bool {} + /** @param PgSql\Connection|string $connection */ + function pg_query($connection, string $query = UNKNOWN): PgSql\Result|false {} -/** @param PgSql|string $connection */ -function pg_query($connection, string $query = UNKNOWN): PgSqlResult|false {} + /** + * @param PgSql\Connection|string $connection + * @alias pg_query + */ + function pg_exec($connection, string $query = UNKNOWN): PgSql\Result|false {} -/** - * @param PgSql|string $connection - * @alias pg_query - */ -function pg_exec($connection, string $query = UNKNOWN): PgSqlResult|false {} + /** + * @param PgSql\Connection|string $connection + * @param string|array $query + */ + function pg_query_params($connection, $query, array $params = UNKNOWN): PgSql\Result|false {} -/** - * @param PgSql|string $connection - * @param string|array $query - */ -function pg_query_params($connection, $query, array $params = UNKNOWN): PgSqlResult|false {} + /** @param PgSql\Connection|string $connection */ + function pg_prepare($connection, string $statement_name, string $query = UNKNOWN): PgSql\Result|false {} -/** @param PgSql|string $connection */ -function pg_prepare($connection, string $statement_name, string $query = UNKNOWN): PgSqlResult|false {} + /** + * @param PgSql\Connection|string $connection + * @param string|array $statement_name + */ + function pg_execute($connection, $statement_name, array $params = UNKNOWN): PgSql\Result|false {} -/** - * @param PgSql|string $connection - * @param string|array $statement_name - */ -function pg_execute($connection, $statement_name, array $params = UNKNOWN): PgSqlResult|false {} + function pg_num_rows(PgSql\Result $result): int {} -function pg_num_rows(PgSqlResult $result): int {} + /** + * @alias pg_num_rows + * @deprecated + */ + function pg_numrows(PgSql\Result $result): int {} -/** - * @alias pg_num_rows - * @deprecated - */ -function pg_numrows(PgSqlResult $result): int {} + function pg_num_fields(PgSql\Result $result): int {} -function pg_num_fields(PgSqlResult $result): int {} + /** + * @alias pg_num_fields + * @deprecated + */ + function pg_numfields(PgSql\Result $result): int {} -/** - * @alias pg_num_fields - * @deprecated - */ -function pg_numfields(PgSqlResult $result): int {} + function pg_affected_rows(PgSql\Result $result): int {} -function pg_affected_rows(PgSqlResult $result): int {} + /** + * @alias pg_affected_rows + * @deprecated + */ + function pg_cmdtuples(PgSql\Result $result): int {} -/** - * @alias pg_affected_rows - * @deprecated - */ -function pg_cmdtuples(PgSqlResult $result): int {} + function pg_last_notice(PgSql\Connection $connection, int $mode = PGSQL_NOTICE_LAST): array|string|bool {} -function pg_last_notice(PgSql $connection, int $mode = PGSQL_NOTICE_LAST): array|string|bool {} + function pg_field_table(PgSql\Result $result, int $field, bool $oid_only = false): string|int|false {} -function pg_field_table(PgSqlResult $result, int $field, bool $oid_only = false): string|int|false {} + function pg_field_name(PgSql\Result $result, int $field): string {} -function pg_field_name(PgSqlResult $result, int $field): string {} + /** + * @alias pg_field_name + * @deprecated + */ + function pg_fieldname(PgSql\Result $result, int $field): string {} -/** - * @alias pg_field_name - * @deprecated - */ -function pg_fieldname(PgSqlResult $result, int $field): string {} + function pg_field_size(PgSql\Result $result, int $field): int {} -function pg_field_size(PgSqlResult $result, int $field): int {} + /** + * @alias pg_field_size + * @deprecated + */ + function pg_fieldsize(PgSql\Result $result, int $field): int {} -/** - * @alias pg_field_size - * @deprecated - */ -function pg_fieldsize(PgSqlResult $result, int $field): int {} + function pg_field_type(PgSql\Result $result, int $field): string {} -function pg_field_type(PgSqlResult $result, int $field): string {} + /** + * @alias pg_field_type + * @deprecated + */ + function pg_fieldtype(PgSql\Result $result, int $field): string {} -/** - * @alias pg_field_type - * @deprecated - */ -function pg_fieldtype(PgSqlResult $result, int $field): string {} + function pg_field_type_oid(PgSql\Result $result, int $field): string|int {} -function pg_field_type_oid(PgSqlResult $result, int $field): string|int {} + function pg_field_num(PgSql\Result $result, string $field): int {} -function pg_field_num(PgSqlResult $result, string $field): int {} + /** + * @alias pg_field_num + * @deprecated + */ + function pg_fieldnum(PgSql\Result $result, string $field): int {} -/** - * @alias pg_field_num - * @deprecated - */ -function pg_fieldnum(PgSqlResult $result, string $field): int {} + /** @param string|int $row */ + function pg_fetch_result(PgSql\Result $result, $row, string|int $field = UNKNOWN): string|false|null {} -/** @param string|int $row */ -function pg_fetch_result(PgSqlResult $result, $row, string|int $field = UNKNOWN): string|false|null {} + /** + * @param string|int $row + * @alias pg_fetch_result + * @deprecated + */ + function pg_result(PgSql\Result $result, $row, string|int $field = UNKNOWN): string|false|null {} -/** - * @param string|int $row - * @alias pg_fetch_result - * @deprecated - */ -function pg_result(PgSqlResult $result, $row, string|int $field = UNKNOWN): string|false|null {} + function pg_fetch_row(PgSql\Result $result, ?int $row = null, int $mode = PGSQL_NUM): array|false {} -function pg_fetch_row(PgSqlResult $result, ?int $row = null, int $mode = PGSQL_NUM): array|false {} + function pg_fetch_assoc(PgSql\Result $result, ?int $row = null): array|false {} + + function pg_fetch_array(PgSql\Result $result, ?int $row = null, int $mode = PGSQL_BOTH): array|false {} + + function pg_fetch_object(PgSql\Result $result, ?int $row = null, string $class = "stdClass", array $constructor_args = []): object|false {} + + function pg_fetch_all(PgSql\Result $result, int $mode = PGSQL_ASSOC): array {} + + function pg_fetch_all_columns(PgSql\Result $result, int $field = 0): array {} + + function pg_result_seek(PgSql\Result $result, int $row): bool {} + + /** @param string|int $row */ + function pg_field_prtlen(PgSql\Result $result, $row, string|int $field = UNKNOWN): int|false {} -function pg_fetch_assoc(PgSqlResult $result, ?int $row = null): array|false {} - -function pg_fetch_array(PgSqlResult $result, ?int $row = null, int $mode = PGSQL_BOTH): array|false {} - -function pg_fetch_object(PgSqlResult $result, ?int $row = null, string $class = "stdClass", array $constructor_args = []): object|false {} - -function pg_fetch_all(PgSqlResult $result, int $mode = PGSQL_ASSOC): array {} - -function pg_fetch_all_columns(PgSqlResult $result, int $field = 0): array {} - -function pg_result_seek(PgSqlResult $result, int $row): bool {} - -/** @param string|int $row */ -function pg_field_prtlen(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} + /** + * @param string|int $row + * @alias pg_field_prtlen + * @deprecated + */ + function pg_fieldprtlen(PgSql\Result $result, $row, string|int $field = UNKNOWN): int|false {} -/** - * @param string|int $row - * @alias pg_field_prtlen - * @deprecated - */ -function pg_fieldprtlen(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} + /** + * @param string|int $row + */ + function pg_field_is_null(PgSql\Result $result, $row, string|int $field = UNKNOWN): int|false {} + + /** + * @param string|int $row + * @alias pg_field_is_null + * @deprecated + */ + function pg_fieldisnull(PgSql\Result $result, $row, string|int $field = UNKNOWN): int|false {} + + function pg_free_result(PgSql\Result $result): bool {} + + /** + * @alias pg_free_result + * @deprecated + */ + function pg_freeresult(PgSql\Result $result): bool {} + + function pg_last_oid(PgSql\Result $result): string|int|false {} + + /** + * @alias pg_last_oid + * @deprecated + */ + function pg_getlastoid(PgSql\Result $result): string|int|false {} + + function pg_trace(string $filename, string $mode = "w", ?PgSql\Connection $connection = null): bool {} + + function pg_untrace(?PgSql\Connection $connection = null): bool {} + + /** + * @param PgSql\Connection $connection + * @param string|int $oid + */ + function pg_lo_create($connection = UNKNOWN, $oid = UNKNOWN): string|int|false {} + + /** + * @param PgSql\Connection $connection + * @param string|int $oid + * @alias pg_lo_create + * @deprecated + */ + function pg_locreate($connection = UNKNOWN, $oid = UNKNOWN): string|int|false {} + + /** + * @param PgSql\Connection $connection + * @param string|int $oid + */ + function pg_lo_unlink($connection, $oid = UNKNOWN): bool {} + + /** + * @param PgSql\Connection $connection + * @param string|int $oid + * @alias pg_lo_unlink + * @deprecated + */ + function pg_lounlink($connection, $oid = UNKNOWN): bool {} + + /** + * @param PgSql\Connection $connection + * @param string|int $oid + */ + function pg_lo_open($connection, $oid = UNKNOWN, string $mode = UNKNOWN): PgSql\Lob|false {} + + /** + * @param PgSql\Connection $connection + * @param string|int $oid + * @alias pg_lo_open + * @deprecated + */ + function pg_loopen($connection, $oid = UNKNOWN, string $mode = UNKNOWN): PgSql\Lob|false {} + + function pg_lo_close(PgSql\Lob $lob): bool {} + + /** + * @alias pg_lo_close + * @deprecated + */ + function pg_loclose(PgSql\Lob $lob): bool {} + + function pg_lo_read(PgSql\Lob $lob, int $length = 8192): string|false {} + + /** + * @alias pg_lo_read + * @deprecated + */ + function pg_loread(PgSql\Lob $lob, int $length = 8192): string|false {} + + function pg_lo_write(PgSql\Lob $lob, string $data, ?int $length = null): int|false {} + + /** + * @alias pg_lo_write + * @deprecated + */ + function pg_lowrite(PgSql\Lob $lob, string $data, ?int $length = null): int|false {} + + function pg_lo_read_all(PgSql\Lob $lob): int {} -/** - * @param string|int $row - */ -function pg_field_is_null(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} - -/** - * @param string|int $row - * @alias pg_field_is_null - * @deprecated - */ -function pg_fieldisnull(PgSqlResult $result, $row, string|int $field = UNKNOWN): int|false {} - -function pg_free_result(PgSqlResult $result): bool {} - -/** - * @alias pg_free_result - * @deprecated - */ -function pg_freeresult(PgSqlResult $result): bool {} - -function pg_last_oid(PgSqlResult $result): string|int|false {} - -/** - * @alias pg_last_oid - * @deprecated - */ -function pg_getlastoid(PgSqlResult $result): string|int|false {} - -function pg_trace(string $filename, string $mode = "w", ?PgSql $connection = null): bool {} - -function pg_untrace(?PgSql $connection = null): bool {} - -/** - * @param PgSql $connection - * @param string|int $oid - */ -function pg_lo_create($connection = UNKNOWN, $oid = UNKNOWN): string|int|false {} - -/** - * @param PgSql $connection - * @param string|int $oid - * @alias pg_lo_create - * @deprecated - */ -function pg_locreate($connection = UNKNOWN, $oid = UNKNOWN): string|int|false {} - -/** - * @param PgSql $connection - * @param string|int $oid - */ -function pg_lo_unlink($connection, $oid = UNKNOWN): bool {} - -/** - * @param PgSql $connection - * @param string|int $oid - * @alias pg_lo_unlink - * @deprecated - */ -function pg_lounlink($connection, $oid = UNKNOWN): bool {} - -/** - * @param PgSql $connection - * @param string|int $oid - */ -function pg_lo_open($connection, $oid = UNKNOWN, string $mode = UNKNOWN): PgSqlLob|false {} - -/** - * @param PgSql $connection - * @param string|int $oid - * @alias pg_lo_open - * @deprecated - */ -function pg_loopen($connection, $oid = UNKNOWN, string $mode = UNKNOWN): PgSqlLob|false {} - -function pg_lo_close(PgSqlLob $lob): bool {} - -/** - * @alias pg_lo_close - * @deprecated - */ -function pg_loclose(PgSqlLob $lob): bool {} - -function pg_lo_read(PgSqlLob $lob, int $length = 8192): string|false {} - -/** - * @alias pg_lo_read - * @deprecated - */ -function pg_loread(PgSqlLob $lob, int $length = 8192): string|false {} - -function pg_lo_write(PgSqlLob $lob, string $data, ?int $length = null): int|false {} - -/** - * @alias pg_lo_write - * @deprecated - */ -function pg_lowrite(PgSqlLob $lob, string $data, ?int $length = null): int|false {} - -function pg_lo_read_all(PgSqlLob $lob): int {} + /** + * @alias pg_lo_read_all + * @deprecated + */ + function pg_loreadall(PgSql\Lob $lob): int {} -/** - * @alias pg_lo_read_all - * @deprecated - */ -function pg_loreadall(PgSqlLob $lob): int {} + /** + * @param PgSql\Connection|string $connection + * @param string|int $filename + * @param string|int $oid + */ + function pg_lo_import($connection, $filename = UNKNOWN, $oid = UNKNOWN): string|int|false {} -/** - * @param PgSql|string $connection - * @param string|int $filename - * @param string|int $oid - */ -function pg_lo_import($connection, $filename = UNKNOWN, $oid = UNKNOWN): string|int|false {} + /** + * @param PgSql\Connection|string $connection + * @param string|int $filename + * @param string|int $oid + * @alias pg_lo_import + * @deprecated + */ + function pg_loimport($connection, $filename = UNKNOWN, $oid = UNKNOWN): string|int|false {} -/** - * @param PgSql|string $connection - * @param string|int $filename - * @param string|int $oid - * @alias pg_lo_import - * @deprecated - */ -function pg_loimport($connection, $filename = UNKNOWN, $oid = UNKNOWN): string|int|false {} + /** + * @param PgSql\Connection|string|int $connection + * @param string|int $oid + * @param string|int $filename + */ + function pg_lo_export($connection, $oid = UNKNOWN, $filename = UNKNOWN): bool {} -/** - * @param PgSql|string|int $connection - * @param string|int $oid - * @param string|int $filename - */ -function pg_lo_export($connection, $oid = UNKNOWN, $filename = UNKNOWN): bool {} + /** + * @param PgSql\Connection|string|int $connection + * @param string|int $oid + * @param string|int $filename + * @alias pg_lo_export + * @deprecated + */ + function pg_loexport($connection, $oid = UNKNOWN, $filename = UNKNOWN): bool {} -/** - * @param PgSql|string|int $connection - * @param string|int $oid - * @param string|int $filename - * @alias pg_lo_export - * @deprecated - */ -function pg_loexport($connection, $oid = UNKNOWN, $filename = UNKNOWN): bool {} + function pg_lo_seek(PgSql\Lob $lob, int $offset, int $whence = SEEK_CUR): bool {} -function pg_lo_seek(PgSqlLob $lob, int $offset, int $whence = SEEK_CUR): bool {} + function pg_lo_tell(PgSql\Lob $lob): int {} -function pg_lo_tell(PgSqlLob $lob): int {} + function pg_lo_truncate(PgSql\Lob $lob, int $size): bool {} -function pg_lo_truncate(PgSqlLob $lob, int $size): bool {} + /** @param PgSql\Connection|int $connection */ + function pg_set_error_verbosity($connection, int $verbosity = UNKNOWN): int|false {} -/** @param PgSql|int $connection */ -function pg_set_error_verbosity($connection, int $verbosity = UNKNOWN): int|false {} + /** @param PgSql\Connection|string $connection */ + function pg_set_client_encoding($connection, string $encoding = UNKNOWN): int {} -/** @param PgSql|string $connection */ -function pg_set_client_encoding($connection, string $encoding = UNKNOWN): int {} + /** + * @param PgSql\Connection|string $connection + * @alias pg_set_client_encoding + * @deprecated + */ + function pg_setclientencoding($connection, string $encoding = UNKNOWN): int {} -/** - * @param PgSql|string $connection - * @alias pg_set_client_encoding - * @deprecated - */ -function pg_setclientencoding($connection, string $encoding = UNKNOWN): int {} + function pg_client_encoding(?PgSql\Connection $connection = null): string {} -function pg_client_encoding(?PgSql $connection = null): string {} + /** + * @alias pg_client_encoding + * @deprecated + */ + function pg_clientencoding(?PgSql\Connection $connection = null): string {} -/** - * @alias pg_client_encoding - * @deprecated - */ -function pg_clientencoding(?PgSql $connection = null): string {} + function pg_end_copy(?PgSql\Connection $connection = null): bool {} -function pg_end_copy(?PgSql $connection = null): bool {} + /** @param PgSql\Connection|string $connection */ + function pg_put_line($connection, string $query = UNKNOWN): bool {} -/** @param PgSql|string $connection */ -function pg_put_line($connection, string $query = UNKNOWN): bool {} + function pg_copy_to(PgSql\Connection $connection, string $table_name, string $separator = "\t", string $null_as = "\\\\N"): array|false {} -function pg_copy_to(PgSql $connection, string $table_name, string $separator = "\t", string $null_as = "\\\\N"): array|false {} + function pg_copy_from(PgSql\Connection $connection, string $table_name, array $rows, string $separator = "\t", string $null_as = "\\\\N"): bool {} -function pg_copy_from(PgSql $connection, string $table_name, array $rows, string $separator = "\t", string $null_as = "\\\\N"): bool {} + /** @param PgSql\Connection|string $connection */ + function pg_escape_string($connection, string $string = UNKNOWN): string {} -/** @param PgSql|string $connection */ -function pg_escape_string($connection, string $string = UNKNOWN): string {} + /** @param PgSql\Connection|string $connection */ + function pg_escape_bytea($connection, string $string = UNKNOWN): string {} -/** @param PgSql|string $connection */ -function pg_escape_bytea($connection, string $string = UNKNOWN): string {} + function pg_unescape_bytea(string $string): string {} -function pg_unescape_bytea(string $string): string {} + /** @param PgSql\Connection|string $connection */ + function pg_escape_literal($connection, string $string = UNKNOWN): string|false {} -/** @param PgSql|string $connection */ -function pg_escape_literal($connection, string $string = UNKNOWN): string|false {} + /** @param PgSql\Connection|string $connection */ + function pg_escape_identifier($connection, string $string = UNKNOWN): string|false {} -/** @param PgSql|string $connection */ -function pg_escape_identifier($connection, string $string = UNKNOWN): string|false {} + function pg_result_error(PgSql\Result $result): string|false {} -function pg_result_error(PgSqlResult $result): string|false {} + function pg_result_error_field(PgSql\Result $result, int $field_code): string|false|null {} -function pg_result_error_field(PgSqlResult $result, int $field_code): string|false|null {} + function pg_connection_status(PgSql\Connection $connection): int {} -function pg_connection_status(PgSql $connection): int {} + function pg_transaction_status(PgSql\Connection $connection): int {} -function pg_transaction_status(PgSql $connection): int {} + function pg_connection_reset(PgSql\Connection $connection): bool {} -function pg_connection_reset(PgSql $connection): bool {} + function pg_cancel_query(PgSql\Connection $connection): bool {} -function pg_cancel_query(PgSql $connection): bool {} + function pg_connection_busy(PgSql\Connection $connection): bool {} -function pg_connection_busy(PgSql $connection): bool {} + function pg_send_query(PgSql\Connection $connection, string $query): int|bool {} -function pg_send_query(PgSql $connection, string $query): int|bool {} + function pg_send_query_params(PgSql\Connection $connection, string $query, array $params): int|bool {} -function pg_send_query_params(PgSql $connection, string $query, array $params): int|bool {} + function pg_send_prepare(PgSql\Connection $connection, string $statement_name, string $query): int|bool {} -function pg_send_prepare(PgSql $connection, string $statement_name, string $query): int|bool {} + function pg_send_execute(PgSql\Connection $connection, string $query, array $params): int|bool {} -function pg_send_execute(PgSql $connection, string $query, array $params): int|bool {} + function pg_get_result(PgSql\Connection $connection): PgSql\Result|false {} -function pg_get_result(PgSql $connection): PgSqlResult|false {} + function pg_result_status(PgSql\Result $result, int $mode = PGSQL_STATUS_LONG): string|int {} -function pg_result_status(PgSqlResult $result, int $mode = PGSQL_STATUS_LONG): string|int {} + function pg_get_notify(PgSql\Connection $connection, int $mode = PGSQL_ASSOC): array|false {} -function pg_get_notify(PgSql $connection, int $mode = PGSQL_ASSOC): array|false {} + function pg_get_pid(PgSql\Connection $connection): int {} -function pg_get_pid(PgSql $connection): int {} + /** @return resource|false */ + function pg_socket(PgSql\Connection $connection) {} -/** @return resource|false */ -function pg_socket(PgSql $connection) {} + function pg_consume_input(PgSql\Connection $connection): bool {} -function pg_consume_input(PgSql $connection): bool {} + function pg_flush(PgSql\Connection $connection): int|bool {} -function pg_flush(PgSql $connection): int|bool {} + function pg_meta_data(PgSql\Connection $connection, string $table_name, bool $extended = false): array|false {} -function pg_meta_data(PgSql $connection, string $table_name, bool $extended = false): array|false {} + function pg_convert(PgSql\Connection $connection, string $table_name, array $values, int $flags = 0): array|false {} -function pg_convert(PgSql $connection, string $table_name, array $values, int $flags = 0): array|false {} + function pg_insert(PgSql\Connection $connection, string $table_name, array $values, int $flags = PGSQL_DML_EXEC): PgSql\Result|string|bool {} -function pg_insert(PgSql $connection, string $table_name, array $values, int $flags = PGSQL_DML_EXEC): PgSqlResult|string|bool {} + function pg_update(PgSql\Connection $connection, string $table_name, array $values, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} -function pg_update(PgSql $connection, string $table_name, array $values, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} + function pg_delete(PgSql\Connection $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} -function pg_delete(PgSql $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} - -function pg_select(PgSql $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC, int $mode = PGSQL_ASSOC): array|string|false {} + function pg_select(PgSql\Connection $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC, int $mode = PGSQL_ASSOC): array|string|false {} +} diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index bac9a2b47fbd8..a24601533a549 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1,7 +1,7 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: eef82ce2f0201a9b9584c5588797af78e635cea4 */ + * Stub hash: 1a3e16a1168698458b7de376533cb8e10e1725bd */ -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_connect, 0, 1, PgSql, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_connect, 0, 1, PgSql\\Connection, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() @@ -9,15 +9,15 @@ ZEND_END_ARG_INFO() #define arginfo_pg_pconnect arginfo_pg_connect ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_connect_poll, 0, 1, IS_LONG, 0) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_close, 0, 0, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql\\Connection, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_dbname, 0, 0, IS_STRING, 0) - ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql\\Connection, 1, "null") ZEND_END_ARG_INFO() #define arginfo_pg_last_error arginfo_pg_dbname @@ -33,7 +33,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_host arginfo_pg_dbname ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_version, 0, 0, IS_ARRAY, 0) - ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql\\Connection, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_parameter_status, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) @@ -43,33 +43,33 @@ ZEND_END_ARG_INFO() #define arginfo_pg_ping arginfo_pg_close -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_query, 0, 1, PgSqlResult, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_query, 0, 1, PgSql\\Result, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pg_exec arginfo_pg_query -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_query_params, 0, 2, PgSqlResult, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_query_params, 0, 2, PgSql\\Result, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, query) ZEND_ARG_TYPE_INFO(0, params, IS_ARRAY, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_prepare, 0, 2, PgSqlResult, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_prepare, 0, 2, PgSql\\Result, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_TYPE_INFO(0, statement_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_execute, 0, 2, PgSqlResult, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_execute, 0, 2, PgSql\\Result, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, statement_name) ZEND_ARG_TYPE_INFO(0, params, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_num_rows, 0, 1, IS_LONG, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_END_ARG_INFO() #define arginfo_pg_numrows arginfo_pg_num_rows @@ -83,25 +83,25 @@ ZEND_END_ARG_INFO() #define arginfo_pg_cmdtuples arginfo_pg_num_rows ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_last_notice, 0, 1, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_NOTICE_LAST") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_table, 0, 2, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, oid_only, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_name, 0, 2, IS_STRING, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() #define arginfo_pg_fieldname arginfo_pg_field_name ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_size, 0, 2, IS_LONG, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -112,19 +112,19 @@ ZEND_END_ARG_INFO() #define arginfo_pg_fieldtype arginfo_pg_field_name ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_type_oid, 0, 2, MAY_BE_STRING|MAY_BE_LONG) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_num, 0, 2, IS_LONG, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pg_fieldnum arginfo_pg_field_num ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_result, 0, 2, MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_INFO(0, row) ZEND_ARG_TYPE_MASK(0, field, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_END_ARG_INFO() @@ -132,46 +132,46 @@ ZEND_END_ARG_INFO() #define arginfo_pg_result arginfo_pg_fetch_result ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_row, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_NUM") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_assoc, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_array, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_BOTH") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_object, 0, 1, MAY_BE_OBJECT|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all, 0, 1, IS_ARRAY, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_ASSOC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all_columns, 0, 1, IS_ARRAY, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, field, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_result_seek, 0, 2, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO(0, row, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_prtlen, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_INFO(0, row) ZEND_ARG_TYPE_MASK(0, field, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_END_ARG_INFO() @@ -183,13 +183,13 @@ ZEND_END_ARG_INFO() #define arginfo_pg_fieldisnull arginfo_pg_field_prtlen ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_free_result, 0, 1, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_END_ARG_INFO() #define arginfo_pg_freeresult arginfo_pg_free_result ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_last_oid, 0, 1, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_END_ARG_INFO() #define arginfo_pg_getlastoid arginfo_pg_last_oid @@ -197,7 +197,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_trace, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 0, "\"w\"") - ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql, 1, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, connection, PgSql\\Connection, 1, "null") ZEND_END_ARG_INFO() #define arginfo_pg_untrace arginfo_pg_close @@ -216,7 +216,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_lounlink arginfo_pg_lo_unlink -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_lo_open, 0, 1, PgSqlLob, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_lo_open, 0, 1, PgSql\\Lob, MAY_BE_FALSE) ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, oid) ZEND_ARG_TYPE_INFO(0, mode, IS_STRING, 0) @@ -225,20 +225,20 @@ ZEND_END_ARG_INFO() #define arginfo_pg_loopen arginfo_pg_lo_open ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_close, 0, 1, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) + ZEND_ARG_OBJ_INFO(0, lob, PgSql\\Lob, 0) ZEND_END_ARG_INFO() #define arginfo_pg_loclose arginfo_pg_lo_close ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_lo_read, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) + ZEND_ARG_OBJ_INFO(0, lob, PgSql\\Lob, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 0, "8192") ZEND_END_ARG_INFO() #define arginfo_pg_loread arginfo_pg_lo_read ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_lo_write, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) + ZEND_ARG_OBJ_INFO(0, lob, PgSql\\Lob, 0) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() @@ -246,7 +246,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_lowrite arginfo_pg_lo_write ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_read_all, 0, 1, IS_LONG, 0) - ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) + ZEND_ARG_OBJ_INFO(0, lob, PgSql\\Lob, 0) ZEND_END_ARG_INFO() #define arginfo_pg_loreadall arginfo_pg_lo_read_all @@ -268,7 +268,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_loexport arginfo_pg_lo_export ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_seek, 0, 2, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) + ZEND_ARG_OBJ_INFO(0, lob, PgSql\\Lob, 0) ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, whence, IS_LONG, 0, "SEEK_CUR") ZEND_END_ARG_INFO() @@ -276,7 +276,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_lo_tell arginfo_pg_lo_read_all ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_lo_truncate, 0, 2, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO(0, lob, PgSqlLob, 0) + ZEND_ARG_OBJ_INFO(0, lob, PgSql\\Lob, 0) ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -304,14 +304,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_put_line, 0, 1, _IS_BOOL, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_copy_to, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\"\\t\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, null_as, IS_STRING, 0, "\"\\\\\\\\N\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_copy_from, 0, 3, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, rows, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\"\\t\"") @@ -337,11 +337,11 @@ ZEND_END_ARG_INFO() #define arginfo_pg_escape_identifier arginfo_pg_escape_literal ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_error, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_error_field, 0, 2, MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO(0, field_code, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -350,7 +350,7 @@ ZEND_END_ARG_INFO() #define arginfo_pg_transaction_status arginfo_pg_connect_poll ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_connection_reset, 0, 1, _IS_BOOL, 0) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_END_ARG_INFO() #define arginfo_pg_cancel_query arginfo_pg_connection_reset @@ -358,72 +358,72 @@ ZEND_END_ARG_INFO() #define arginfo_pg_connection_busy arginfo_pg_connection_reset ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_send_query, 0, 2, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_send_query_params, 0, 3, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, params, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_send_prepare, 0, 3, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, statement_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pg_send_execute arginfo_pg_send_query_params -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_get_result, 0, 1, PgSqlResult, MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_get_result, 0, 1, PgSql\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_status, 0, 1, MAY_BE_STRING|MAY_BE_LONG) - ZEND_ARG_OBJ_INFO(0, result, PgSqlResult, 0) + ZEND_ARG_OBJ_INFO(0, result, PgSql\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_STATUS_LONG") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_get_notify, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_ASSOC") ZEND_END_ARG_INFO() #define arginfo_pg_get_pid arginfo_pg_connect_poll ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_socket, 0, 0, 1) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_END_ARG_INFO() #define arginfo_pg_consume_input arginfo_pg_connection_reset ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_flush, 0, 1, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_meta_data, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extended, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_convert, 0, 3, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_insert, 0, 3, PgSqlResult, MAY_BE_STRING|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_insert, 0, 3, PgSql\\Result, MAY_BE_STRING|MAY_BE_BOOL) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_update, 0, 4, MAY_BE_STRING|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) @@ -431,14 +431,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_update, 0, 4, MAY_BE_STRING|M ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_delete, 0, 3, MAY_BE_STRING|MAY_BE_BOOL) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_select, 0, 3, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, connection, PgSql, 0) + ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") @@ -656,47 +656,47 @@ static const zend_function_entry ext_functions[] = { }; -static const zend_function_entry class_PgSql_methods[] = { +static const zend_function_entry class_PgSql_Connection_methods[] = { ZEND_FE_END }; -static const zend_function_entry class_PgSqlResult_methods[] = { +static const zend_function_entry class_PgSql_Result_methods[] = { ZEND_FE_END }; -static const zend_function_entry class_PgSqlLob_methods[] = { +static const zend_function_entry class_PgSql_Lob_methods[] = { ZEND_FE_END }; -static zend_class_entry *register_class_PgSql(void) +static zend_class_entry *register_class_PgSql_Connection(void) { zend_class_entry ce, *class_entry; - INIT_CLASS_ENTRY(ce, "PgSql", class_PgSql_methods); + INIT_NS_CLASS_ENTRY(ce, "PgSql", "Connection", class_PgSql_Connection_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; return class_entry; } -static zend_class_entry *register_class_PgSqlResult(void) +static zend_class_entry *register_class_PgSql_Result(void) { zend_class_entry ce, *class_entry; - INIT_CLASS_ENTRY(ce, "PgSqlResult", class_PgSqlResult_methods); + INIT_NS_CLASS_ENTRY(ce, "PgSql", "Result", class_PgSql_Result_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; return class_entry; } -static zend_class_entry *register_class_PgSqlLob(void) +static zend_class_entry *register_class_PgSql_Lob(void) { zend_class_entry ce, *class_entry; - INIT_CLASS_ENTRY(ce, "PgSqlLob", class_PgSqlLob_methods); + INIT_NS_CLASS_ENTRY(ce, "PgSql", "Lob", class_PgSql_Lob_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 9dcf2c577858c..4e8fd14a412e7 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -147,8 +147,8 @@ typedef struct pgsql_link_handle { PGconn *conn; zend_string *hash; HashTable *notices; - zend_object std; bool persistent; + zend_object std; } pgsql_link_handle; typedef struct pgLofp { @@ -191,7 +191,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) HashTable hashes; /* hashes for each connection */ HashTable field_oids; HashTable table_oids; - HashTable regular_list; /* connection list */ + HashTable connections; ZEND_END_MODULE_GLOBALS(pgsql) ZEND_EXTERN_MODULE_GLOBALS(pgsql) diff --git a/ext/pgsql/tests/02connection.phpt b/ext/pgsql/tests/02connection.phpt index c405bb04b6ccd..2cbec6b6a270e 100644 --- a/ext/pgsql/tests/02connection.phpt +++ b/ext/pgsql/tests/02connection.phpt @@ -54,5 +54,5 @@ pg_close($db); ?> --EXPECTF-- -object(PgSql)#%d (0) { +object(PgSql\Connection)#%d (0) { } diff --git a/ext/pgsql/tests/09notice.phpt b/ext/pgsql/tests/09notice.phpt index 4332d816b17b8..9cb894f5d2f03 100644 --- a/ext/pgsql/tests/09notice.phpt +++ b/ext/pgsql/tests/09notice.phpt @@ -49,7 +49,7 @@ try { } ?> --EXPECTF-- -object(PgSqlResult)#%d (0) { +object(PgSql\Result)#%d (0) { } string(0) "" array(0) { diff --git a/ext/pgsql/tests/10pg_convert_9.phpt b/ext/pgsql/tests/10pg_convert_9.phpt index 328413ec7cd1c..5f867ef0883f3 100644 --- a/ext/pgsql/tests/10pg_convert_9.phpt +++ b/ext/pgsql/tests/10pg_convert_9.phpt @@ -60,4 +60,4 @@ Array of values must be an associative array with string keys Array of values must be an associative array with string keys Values must be of type string|int|float|bool|null, array given Values must be of type string|int|float|bool|null, stdClass given -Values must be of type string|int|float|bool|null, PgSql given +Values must be of type string|int|float|bool|null, PgSql\Connection given diff --git a/ext/pgsql/tests/12pg_insert_9.phpt b/ext/pgsql/tests/12pg_insert_9.phpt index 1098405c69359..10a85834b4af9 100644 --- a/ext/pgsql/tests/12pg_insert_9.phpt +++ b/ext/pgsql/tests/12pg_insert_9.phpt @@ -54,11 +54,11 @@ echo "Ok\n"; --EXPECTF-- INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES (1234,E'AAA',E'\\x424242'); INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES ('1234','AAA','BBB'); -object(PgSqlResult)#%d (0) { +object(PgSql\Result)#%d (0) { } Array of values must be an associative array with string keys Array of values must be an associative array with string keys Values must be of type string|int|float|bool|null, array given Values must be of type string|int|float|bool|null, stdClass given -Values must be of type string|int|float|bool|null, PgSql given +Values must be of type string|int|float|bool|null, PgSql\Connection given Ok diff --git a/ext/pgsql/tests/13pg_select_9.phpt b/ext/pgsql/tests/13pg_select_9.phpt index 03ee9a6fd7e92..2031f18d81ec1 100644 --- a/ext/pgsql/tests/13pg_select_9.phpt +++ b/ext/pgsql/tests/13pg_select_9.phpt @@ -80,5 +80,5 @@ Array of values must be an associative array with string keys Array of values must be an associative array with string keys Values must be of type string|int|float|bool|null, array given Values must be of type string|int|float|bool|null, stdClass given -Values must be of type string|int|float|bool|null, PgSql given +Values must be of type string|int|float|bool|null, PgSql\Connection given Ok diff --git a/ext/pgsql/tests/28large_object_import_oid.phpt b/ext/pgsql/tests/28large_object_import_oid.phpt index 4bec8833f3211..c5a1ecec9aaa5 100644 --- a/ext/pgsql/tests/28large_object_import_oid.phpt +++ b/ext/pgsql/tests/28large_object_import_oid.phpt @@ -93,5 +93,5 @@ Invalid OID value passed OID value must be of type string|int, bool given OID value must be of type string|int, array given OID value must be of type string|int, stdClass given -OID value must be of type string|int, PgSql given +OID value must be of type string|int, PgSql\Connection given OK diff --git a/ext/pgsql/tests/80_bug32223.phpt b/ext/pgsql/tests/80_bug32223.phpt index 10c463358247a..8bc9af399f7ce 100644 --- a/ext/pgsql/tests/80_bug32223.phpt +++ b/ext/pgsql/tests/80_bug32223.phpt @@ -53,9 +53,9 @@ pg_close($dbh); ?> --EXPECTF-- -object(PgSqlResult)#%d (0) { +object(PgSql\Result)#%d (0) { } -object(PgSqlResult)#%d (0) { +object(PgSql\Result)#%d (0) { } array(1) { [0]=> diff --git a/ext/pgsql/tests/80_bug32223b.phpt b/ext/pgsql/tests/80_bug32223b.phpt index 4a482ce0dbf02..1c687ccec9467 100644 --- a/ext/pgsql/tests/80_bug32223b.phpt +++ b/ext/pgsql/tests/80_bug32223b.phpt @@ -56,7 +56,7 @@ pg_close($dbh); ?> --EXPECTF-- -object(PgSqlResult)#%d (0) { +object(PgSql\Result)#%d (0) { } array(1) { [0]=> diff --git a/ext/pgsql/tests/80_bug36625.phpt b/ext/pgsql/tests/80_bug36625.phpt index 55027778a2386..ad769d026076b 100644 --- a/ext/pgsql/tests/80_bug36625.phpt +++ b/ext/pgsql/tests/80_bug36625.phpt @@ -50,7 +50,7 @@ unlink($tracefile); ?> --EXPECTF-- bool(false) -object(PgSqlResult)#%d (0) { +object(PgSql\Result)#%d (0) { } bool(true) bool(true) From 94f57565c6f812f4bd0286018e147e26e4755564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 10 May 2021 10:44:49 +0200 Subject: [PATCH 08/14] Some fixes --- ext/pgsql/pgsql.c | 23 +++++++++++++++-------- ext/pgsql/php_pgsql.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index e434f8a5a5816..87322fe92b616 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -78,7 +78,8 @@ zend_throw_error(NULL, "No PostgreSQL connection opened yet"); \ RETURN_THROWS(); \ } -#define FETCH_DEFAULT_LINK() PGG(default_link) +#define FETCH_DEFAULT_LINK() \ + (PGG(default_link) ? pgsql_link_from_obj(PGG(default_link)) : NULL) #define CHECK_PGSQL_LINK(link_handle) \ if (link_handle->conn == NULL) { \ @@ -283,11 +284,15 @@ static zend_string *_php_pgsql_trim_message(const char *message) zend_string_release(msgbuf); \ } \ -static void php_pgsql_set_default_link(pgsql_link_handle *link) +static void php_pgsql_set_default_link(zend_object *obj) { - GC_ADDREF(res); + GC_ADDREF(obj); - PGG(default_link) = link; + if (PGG(default_link) != NULL) { + GC_DELREF(obj); + } + + PGG(default_link) = obj; } static void _close_pgsql_plink(zend_resource *rsrc) @@ -715,15 +720,14 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) } else { /* Non persistent connection */ zval *index_ptr, new_index_ptr; - /* first we check the hash for the hashed_details key. if it exists, + /* first we check the hash for the hashed_details key. If it exists, * it should point us to the right offset where the actual pgsql link sits. * if it doesn't, open a new pgsql link, add it to the resource list, * and add a pointer to it with hashed_details as the key. */ if (!(connect_type & PGSQL_CONNECT_FORCE_NEW) && (index_ptr = zend_hash_find_ptr(&PGG(connections), str.s)) != NULL) { - php_pgsql_set_default_link(pgsql_link_from_obj(Z_OBJ_P(index_ptr))); - GC_ADDREF(Z_OBJ_P(index_ptr)); + php_pgsql_set_default_link(Z_OBJ_P(index_ptr)); ZVAL_COPY(return_value, index_ptr); goto cleanup; @@ -776,7 +780,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_OBJECT) { PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, link); } - php_pgsql_set_default_link(link); + php_pgsql_set_default_link(Z_OBJ_P(return_value)); cleanup: smart_str_free(&str); @@ -838,7 +842,9 @@ PHP_FUNCTION(pg_close) link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); zend_hash_del(&PGG(connections), link->hash); + GC_DELREF(PGG(default_link)); PGG(default_link) = NULL; + pgsql_link_free(link); RETURN_TRUE; } @@ -847,6 +853,7 @@ PHP_FUNCTION(pg_close) if (link == FETCH_DEFAULT_LINK()) { zend_hash_del(&PGG(connections), link->hash); + GC_DELREF(PGG(default_link)); PGG(default_link) = NULL; } pgsql_link_free(link); diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 4e8fd14a412e7..b60ccc06a234e 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -187,7 +187,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) zend_long allow_persistent; zend_long auto_reset_persistent; int ignore_notices,log_notices; - pgsql_link_handle *default_link; /* default link when connection is omitted */ + zend_object *default_link; /* default link when connection is omitted */ HashTable hashes; /* hashes for each connection */ HashTable field_oids; HashTable table_oids; From 37814072212f36eb26044d0e40d43a9863032d8f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 10 May 2021 11:32:02 +0200 Subject: [PATCH 09/14] Some memory management fixes --- ext/pgsql/pgsql.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 87322fe92b616..4a8a6d37abce0 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -289,7 +289,7 @@ static void php_pgsql_set_default_link(zend_object *obj) GC_ADDREF(obj); if (PGG(default_link) != NULL) { - GC_DELREF(obj); + zend_object_release(PGG(default_link)); } PGG(default_link) = obj; @@ -409,7 +409,7 @@ static PHP_GINIT_FUNCTION(pgsql) ZEND_TSRMLS_CACHE_UPDATE(); #endif memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); - zend_hash_init(&pgsql_globals->connections, 0, NULL, ZVAL_PTR_DTOR, 1); + zend_hash_init(&pgsql_globals->connections, 0, NULL, NULL, 1); } static void php_libpq_version(char *buf, size_t len) @@ -595,6 +595,11 @@ PHP_RINIT_FUNCTION(pgsql) PHP_RSHUTDOWN_FUNCTION(pgsql) { + if (PGG(default_link)) { + zend_object_release(PGG(default_link)); + PGG(default_link) = NULL; + } + zend_hash_destroy(&PGG(field_oids)); zend_hash_destroy(&PGG(table_oids)); /* clean up persistent connection */ @@ -718,7 +723,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) link->notices = NULL; link->persistent = 1; } else { /* Non persistent connection */ - zval *index_ptr, new_index_ptr; + zval *index_ptr; /* first we check the hash for the hashed_details key. If it exists, * it should point us to the right offset where the actual pgsql link sits. @@ -766,8 +771,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) link->persistent = 0; /* add it to the hash */ - ZVAL_COPY(&new_index_ptr, return_value); - zend_hash_update(&PGG(connections), str.s, &new_index_ptr); + zend_hash_update(&PGG(connections), str.s, return_value); /* Keep track of link => hash mapping, so we can remove the hash entry from connections * when the connection is closed. This uses the address of the connection rather than the From be1161b696972bbf12450f932cde7690491c91f4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 10 May 2021 11:41:47 +0200 Subject: [PATCH 10/14] Fix connection reuse --- ext/pgsql/pgsql.c | 2 +- ext/pgsql/tests/connection_reuse.phpt | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/pgsql/tests/connection_reuse.phpt diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 4a8a6d37abce0..412ff3a5955cf 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -731,7 +731,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) * and add a pointer to it with hashed_details as the key. */ if (!(connect_type & PGSQL_CONNECT_FORCE_NEW) - && (index_ptr = zend_hash_find_ptr(&PGG(connections), str.s)) != NULL) { + && (index_ptr = zend_hash_find(&PGG(connections), str.s)) != NULL) { php_pgsql_set_default_link(Z_OBJ_P(index_ptr)); ZVAL_COPY(return_value, index_ptr); diff --git a/ext/pgsql/tests/connection_reuse.phpt b/ext/pgsql/tests/connection_reuse.phpt new file mode 100644 index 0000000000000..a2d7911767b8e --- /dev/null +++ b/ext/pgsql/tests/connection_reuse.phpt @@ -0,0 +1,17 @@ +--TEST-- +Reusing connection with same connection string +--SKIPIF-- + +--FILE-- + +--EXPECT-- +object(PgSql\Connection)#1 (0) { +} +object(PgSql\Connection)#1 (0) { +} From 6553e248d89d3be924ba87d9db306987107fd1e4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 10 May 2021 11:52:23 +0200 Subject: [PATCH 11/14] Minor cleanup --- ext/pgsql/pgsql.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 412ff3a5955cf..855d515de78f1 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -845,10 +845,8 @@ PHP_FUNCTION(pg_close) if (!pgsql_link) { link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); - zend_hash_del(&PGG(connections), link->hash); - GC_DELREF(PGG(default_link)); + zend_object_release(PGG(default_link)); PGG(default_link) = NULL; - pgsql_link_free(link); RETURN_TRUE; } @@ -856,7 +854,6 @@ PHP_FUNCTION(pg_close) CHECK_PGSQL_LINK(link); if (link == FETCH_DEFAULT_LINK()) { - zend_hash_del(&PGG(connections), link->hash); GC_DELREF(PGG(default_link)); PGG(default_link) = NULL; } From 51e861f021a74b382bf91b240226dd7087c2d36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 10 May 2021 12:32:39 +0200 Subject: [PATCH 12/14] Remove useless funcinfo --- Zend/Optimizer/zend_func_info.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index 3169db44f5ed4..3542458f762c6 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -658,8 +658,6 @@ static const func_info_t func_infos[] = { F1("session_encode", MAY_BE_FALSE | MAY_BE_STRING), /* ext/pgsql */ - FN("pg_connect", MAY_BE_FALSE | MAY_BE_OBJECT), - FN("pg_pconnect", MAY_BE_FALSE | MAY_BE_OBJECT), F1("pg_dbname", MAY_BE_STRING), F1("pg_options", MAY_BE_STRING), F1("pg_port", MAY_BE_STRING), From 7fd8e01ff3cdeb41a46513698fd5992a24e72b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 10 May 2021 15:02:11 +0200 Subject: [PATCH 13/14] Fix test and error messages --- ext/pgsql/pgsql.c | 6 +++--- ext/pgsql/tests/bug72197.phpt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 855d515de78f1..4b6b618450ce8 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -154,7 +154,7 @@ static zend_object *pgsql_link_create_object(zend_class_entry *class_type) { } static zend_function *pgsql_link_get_constructor(zend_object *object) { - zend_throw_error(NULL, "Cannot directly construct PgSql, use pg_connect() or pg_pconnect() instead"); + zend_throw_error(NULL, "Cannot directly construct PgSql\\Connection, use pg_connect() or pg_pconnect() instead"); return NULL; } @@ -210,7 +210,7 @@ static zend_object *pgsql_result_create_object(zend_class_entry *class_type) { } static zend_function *pgsql_result_get_constructor(zend_object *object) { - zend_throw_error(NULL, "Cannot directly construct PgSqlResult, use a dedicated function instead"); + zend_throw_error(NULL, "Cannot directly construct PgSql\\Result, use a dedicated function instead"); return NULL; } @@ -248,7 +248,7 @@ static zend_object *pgsql_lob_create_object(zend_class_entry *class_type) { } static zend_function *pgsql_lob_get_constructor(zend_object *object) { - zend_throw_error(NULL, "Cannot directly construct PgSqlLob, use pg_lo_open() instead"); + zend_throw_error(NULL, "Cannot directly construct PgSql\\Lob, use pg_lo_open() instead"); return NULL; } diff --git a/ext/pgsql/tests/bug72197.phpt b/ext/pgsql/tests/bug72197.phpt index f9b235dc218b8..332219a51ef5d 100644 --- a/ext/pgsql/tests/bug72197.phpt +++ b/ext/pgsql/tests/bug72197.phpt @@ -31,6 +31,6 @@ pg_query($conn, "ROLLBACK"); pg_close($conn); ?> --EXPECTF-- -pg_lo_create(): Argument #1 ($connection) must be of type PgSql when the connection is provided +pg_lo_create(): Argument #1 ($connection) must be of type PgSql when the connection is provided%w int(%d) int(%d) From d735e8340ee023cb29a8402d2e9b35d47eb0910a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 10 May 2021 22:47:41 +0200 Subject: [PATCH 14/14] Address review comments --- ext/pgsql/pgsql.c | 42 +++++++++++++++--------------------------- ext/pgsql/php_pgsql.h | 1 - 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 4b6b618450ce8..d0e19f33ea0c2 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -297,18 +297,16 @@ static void php_pgsql_set_default_link(zend_object *obj) static void _close_pgsql_plink(zend_resource *rsrc) { - if (rsrc->ptr) { - PGconn *link = (PGconn *)rsrc->ptr; - PGresult *res; + PGconn *link = (PGconn *)rsrc->ptr; + PGresult *res; - while ((res = PQgetResult(link))) { - PQclear(res); - } - PQfinish(link); - PGG(num_persistent)--; - PGG(num_links)--; - rsrc->ptr = NULL; + while ((res = PQgetResult(link))) { + PQclear(res); } + PQfinish(link); + PGG(num_persistent)--; + PGG(num_links)--; + rsrc->ptr = NULL; } static void _php_pgsql_notice_handler(void *l, const char *message) @@ -317,10 +315,9 @@ static void _php_pgsql_notice_handler(void *l, const char *message) return; } - pgsql_link_handle *link; zval tmp; + pgsql_link_handle *link = (pgsql_link_handle *) l; - link = (pgsql_link_handle *) l; if (!link->notices) { link->notices = zend_new_array(1); } @@ -1531,7 +1528,7 @@ PHP_FUNCTION(pg_last_notice) break; case PGSQL_NOTICE_CLEAR: if (notices) { - zend_hash_clean(link->notices); + zend_hash_clean(notices); } RETURN_TRUE; break; @@ -2524,13 +2521,9 @@ PHP_FUNCTION(pg_lo_open) RETURN_THROWS(); } - object_init_ex(return_value, pgsql_lob_ce); - pgsql_lofp = Z_PGSQL_LOB_P(return_value); - if ((pgsql_lofd = lo_open(pgsql, oid, pgsql_mode)) == -1) { if (create) { if ((oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == 0) { - zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Unable to create PostgreSQL large object"); RETURN_FALSE; } else { @@ -2541,24 +2534,19 @@ PHP_FUNCTION(pg_lo_open) php_error_docref(NULL, E_WARNING, "Unable to open PostgreSQL large object"); } - zval_ptr_dtor(return_value); RETURN_FALSE; - } else { - pgsql_lofp->conn = pgsql; - pgsql_lofp->lofd = pgsql_lofd; - return; } } } else { - zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Unable to open PostgreSQL large object"); RETURN_FALSE; } - } else { - pgsql_lofp->conn = pgsql; - pgsql_lofp->lofd = pgsql_lofd; - return; } + + object_init_ex(return_value, pgsql_lob_ce); + pgsql_lofp = Z_PGSQL_LOB_P(return_value); + pgsql_lofp->conn = pgsql; + pgsql_lofp->lofd = pgsql_lofd; } /* }}} */ diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index b60ccc06a234e..f297f91b3ecde 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -188,7 +188,6 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) zend_long auto_reset_persistent; int ignore_notices,log_notices; zend_object *default_link; /* default link when connection is omitted */ - HashTable hashes; /* hashes for each connection */ HashTable field_oids; HashTable table_oids; HashTable connections;