diff options
Diffstat (limited to 'ext/pgsql/pgsql.c')
-rw-r--r-- | ext/pgsql/pgsql.c | 2787 |
1 files changed, 1388 insertions, 1399 deletions
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index a6263680af..a65b7a0aa9 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -35,8 +35,8 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/php_standard.h" -#include "ext/standard/php_smart_str.h" -#include "ext/ereg/php_regex.h" +#include "zend_smart_str.h" +#include "ext/pcre/php_pcre.h" #ifdef PHP_WIN32 # include "win32/time.h" #endif @@ -66,18 +66,18 @@ #define PGSQL_MAX_LENGTH_OF_LONG 30 #define PGSQL_MAX_LENGTH_OF_DOUBLE 60 -#if LONG_MAX < UINT_MAX +#if ZEND_LONG_MAX < UINT_MAX #define PGSQL_RETURN_OID(oid) do { \ - if (oid > LONG_MAX) { \ + if (oid > ZEND_LONG_MAX) { \ smart_str s = {0}; \ smart_str_append_unsigned(&s, oid); \ smart_str_0(&s); \ - RETURN_STRINGL(s.c, s.len, 0); \ + RETURN_NEW_STR(s.s); \ } \ - RETURN_LONG((long)oid); \ + RETURN_LONG((zend_long)oid); \ } while(0) #else -#define PGSQL_RETURN_OID(oid) (RETURN_LONG((long)oid)) +#define PGSQL_RETURN_OID(oid) RETURN_LONG((zend_long)oid) #endif #if HAVE_PQSETNONBLOCKING @@ -86,7 +86,8 @@ #define PQ_SETNONBLOCKING(pg_link, flag) 0 #endif -#define CHECK_DEFAULT_LINK(x) if ((x) == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No PostgreSQL link opened yet"); } +#define CHECK_DEFAULT_LINK(x) if ((x) == NULL) { php_error_docref(NULL, E_WARNING, "No PostgreSQL link opened yet"); } +#define FETCH_DEFAULT_LINK() PGG(default_link) #ifndef HAVE_PQFREEMEM #define PQfreemem free @@ -761,7 +762,7 @@ zend_module_entry pgsql_module_entry = { PHP_RINIT(pgsql), PHP_RSHUTDOWN(pgsql), PHP_MINFO(pgsql), - NO_VERSION_YET, + PHP_PGSQL_VERSION, PHP_MODULE_GLOBALS(pgsql), PHP_GINIT(pgsql), NULL, @@ -771,6 +772,9 @@ zend_module_entry pgsql_module_entry = { /* }}} */ #ifdef COMPILE_DL_PGSQL +#ifdef ZTS +ZEND_TSRMLS_CACHE_DEFINE(); +#endif ZEND_GET_MODULE(pgsql) #endif @@ -797,7 +801,8 @@ static int le_link, le_plink, le_result, le_lofp, le_string; #define PGSQLfree(a) efree(a) /* emulate libpq's PQescapeInternal() 9.0 or later */ -static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal, int safe) { +static char *php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal, int safe) /* {{{ */ +{ char *result, *rp, *s; size_t tmp_len; @@ -833,9 +838,8 @@ static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t le !strncmp(encoding, "GBK", sizeof("GBK")-1) || !strncmp(encoding, "JOHAB", sizeof("JOHAB")-1) || !strncmp(encoding, "UHC", sizeof("UHC")-1) ) { - TSRMLS_FETCH(); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsafe encoding is used. Do not use '%s' encoding or use PostgreSQL 9.0 or later libpq.", encoding); + php_error_docref(NULL, E_WARNING, "Unsafe encoding is used. Do not use '%s' encoding or use PostgreSQL 9.0 or later libpq.", encoding); } /* check backslashes */ tmp_len = strspn(str, "\\"); @@ -872,21 +876,20 @@ static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t le return result; } +/* }}} */ #endif - /* {{{ _php_pgsql_trim_message */ -static char * _php_pgsql_trim_message(const char *message, int *len) +static char * _php_pgsql_trim_message(const char *message, size_t *len) { - register int i = strlen(message)-1; + register size_t i = strlen(message); - if (i>1 && (message[i-1] == '\r' || message[i-1] == '\n') && message[i] == '.') { + if (i>2 && (message[i-2] == '\r' || message[i-2] == '\n') && message[i-1] == '.') { --i; } - while (i>0 && (message[i] == '\r' || message[i] == '\n')) { + while (i>1 && (message[i-1] == '\r' || message[i-1] == '\n')) { --i; } - ++i; if (len) { *len = i; } @@ -905,27 +908,27 @@ static inline char * _php_pgsql_trim_result(PGconn * pgsql, char **buf) #define PHP_PQ_ERROR(text, pgsql) { \ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, text, msgbuf); \ + php_error_docref(NULL, E_WARNING, text, msgbuf); \ efree(msgbuf); \ } \ /* {{{ php_pgsql_set_default_link */ -static void php_pgsql_set_default_link(int id TSRMLS_DC) +static void php_pgsql_set_default_link(zend_resource *res) { - zend_list_addref(id); + GC_REFCOUNT(res)++; - if (PGG(default_link) != -1) { + if (PGG(default_link) != NULL) { zend_list_delete(PGG(default_link)); } - PGG(default_link) = id; + PGG(default_link) = res; } /* }}} */ /* {{{ _close_pgsql_link */ -static void _close_pgsql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void _close_pgsql_link(zend_resource *rsrc) { PGconn *link = (PGconn *)rsrc->ptr; PGresult *res; @@ -940,7 +943,7 @@ static void _close_pgsql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ _close_pgsql_plink */ -static void _close_pgsql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void _close_pgsql_plink(zend_resource *rsrc) { PGconn *link = (PGconn *)rsrc->ptr; PGresult *res; @@ -959,52 +962,51 @@ static void _close_pgsql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) static void _php_pgsql_notice_handler(void *resource_id, const char *message) { php_pgsql_notice *notice; - - TSRMLS_FETCH(); + if (! PGG(ignore_notices)) { notice = (php_pgsql_notice *)emalloc(sizeof(php_pgsql_notice)); - notice->message = _php_pgsql_trim_message(message, (int *)¬ice->len); + notice->message = _php_pgsql_trim_message(message, ¬ice->len); if (PGG(log_notices)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", notice->message); + php_error_docref(NULL, E_NOTICE, "%s", notice->message); } - zend_hash_index_update(&PGG(notices), (ulong)resource_id, (void **)¬ice, sizeof(php_pgsql_notice *), NULL); + zend_hash_index_update_ptr(&PGG(notices), (zend_ulong)resource_id, notice); } } /* }}} */ -#define PHP_PGSQL_NOTICE_PTR_DTOR (void (*)(void *))_php_pgsql_notice_ptr_dtor +#define PHP_PGSQL_NOTICE_PTR_DTOR _php_pgsql_notice_ptr_dtor /* {{{ _php_pgsql_notice_dtor */ -static void _php_pgsql_notice_ptr_dtor(void **ptr) +static void _php_pgsql_notice_ptr_dtor(zval *el) { - php_pgsql_notice *notice = (php_pgsql_notice *)*ptr; + php_pgsql_notice *notice = (php_pgsql_notice *)Z_PTR_P(el); if (notice) { efree(notice->message); efree(notice); - notice = NULL; } } /* }}} */ /* {{{ _rollback_transactions */ -static int _rollback_transactions(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static int _rollback_transactions(zval *el) { PGconn *link; PGresult *res; int orig; + zend_resource *rsrc = Z_RES_P(el); - if (Z_TYPE_P(rsrc) != le_plink) + if (rsrc->type != le_plink) return 0; link = (PGconn *) rsrc->ptr; if (PQ_SETNONBLOCKING(link, 0)) { - php_error_docref("ref.pgsql" TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + php_error_docref("ref.pgsql", E_NOTICE, "Cannot set connection to blocking mode"); return -1; } - + while ((res = PQgetResult(link))) { PQclear(res); } @@ -1031,7 +1033,7 @@ static int _rollback_transactions(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ _free_ptr */ -static void _free_ptr(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void _free_ptr(zend_resource *rsrc) { pgLofp *lofp = (pgLofp *)rsrc->ptr; efree(lofp); @@ -1040,7 +1042,7 @@ static void _free_ptr(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ _free_result */ -static void _free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void _free_result(zend_resource *rsrc) { pgsql_result_handle *pg_result = (pgsql_result_handle *)rsrc->ptr; @@ -1049,8 +1051,7 @@ static void _free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) } /* }}} */ - -static int _php_pgsql_detect_identifier_escape(const char *identifier, size_t len) +static int _php_pgsql_detect_identifier_escape(const char *identifier, size_t len) /* {{{ */ { size_t i; @@ -1072,8 +1073,7 @@ static int _php_pgsql_detect_identifier_escape(const char *identifier, size_t le /* Escaped properly */ return SUCCESS; } - - +/* }}} */ /* {{{ PHP_INI */ @@ -1091,9 +1091,12 @@ PHP_INI_END() */ static PHP_GINIT_FUNCTION(pgsql) { +#if defined(COMPILE_DL_PGSQL) && defined(ZTS) + ZEND_TSRMLS_CACHE_UPDATE(); +#endif memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); /* Initilize notice message hash at MINIT only */ - zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, PHP_PGSQL_NOTICE_PTR_DTOR, 1, 0); + zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, PHP_PGSQL_NOTICE_PTR_DTOR, 1, 0); } /* }}} */ @@ -1215,7 +1218,7 @@ PHP_MSHUTDOWN_FUNCTION(pgsql) */ PHP_RINIT_FUNCTION(pgsql) { - PGG(default_link)=-1; + PGG(default_link) = NULL; PGG(num_links) = PGG(num_persistent); return SUCCESS; } @@ -1228,7 +1231,7 @@ PHP_RSHUTDOWN_FUNCTION(pgsql) /* clean up notice messages */ zend_hash_clean(&PGG(notices)); /* clean up persistent connection */ - zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions TSRMLS_CC); + zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions); return SUCCESS; } /* }}} */ @@ -1255,9 +1258,9 @@ PHP_MINFO_FUNCTION(pgsql) php_info_print_table_row(2, "SSL support", "disabled"); #endif #endif /* HAVE_PG_CONFIG_H */ - snprintf(buf, sizeof(buf), "%ld", PGG(num_persistent)); + snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_persistent)); php_info_print_table_row(2, "Active Persistent Links", buf); - snprintf(buf, sizeof(buf), "%ld", PGG(num_links)); + snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_links)); php_info_print_table_row(2, "Active Links", buf); php_info_print_table_end(); @@ -1265,7 +1268,6 @@ PHP_MINFO_FUNCTION(pgsql) } /* }}} */ - /* {{{ php_pgsql_do_connect */ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) @@ -1273,81 +1275,85 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) char *host=NULL,*port=NULL,*options=NULL,*tty=NULL,*dbname=NULL,*connstring=NULL; PGconn *pgsql; smart_str str = {0}; - zval **args[5]; - int i, connect_type = 0; + zval *args; + uint32_t i; + int connect_type = 0; PGresult *pg_result; + args = (zval *)safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval), 0); if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 5 || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { + efree(args); WRONG_PARAM_COUNT; } smart_str_appends(&str, "pgsql"); - + for (i = 0; i < ZEND_NUM_ARGS(); i++) { /* make sure that the PGSQL_CONNECT_FORCE_NEW bit is not part of the hash so that subsequent connections * can re-use this connection. Bug #39979 - */ - if (i == 1 && ZEND_NUM_ARGS() == 2 && Z_TYPE_PP(args[i]) == IS_LONG) { - if (Z_LVAL_PP(args[1]) == PGSQL_CONNECT_FORCE_NEW) { + */ + if (i == 1 && ZEND_NUM_ARGS() == 2 && Z_TYPE(args[i]) == IS_LONG) { + if (Z_LVAL(args[1]) == PGSQL_CONNECT_FORCE_NEW) { continue; - } else if (Z_LVAL_PP(args[1]) & PGSQL_CONNECT_FORCE_NEW) { - smart_str_append_long(&str, Z_LVAL_PP(args[1]) ^ PGSQL_CONNECT_FORCE_NEW); + } else if (Z_LVAL(args[1]) & PGSQL_CONNECT_FORCE_NEW) { + smart_str_append_long(&str, Z_LVAL(args[1]) ^ PGSQL_CONNECT_FORCE_NEW); } } - convert_to_string_ex(args[i]); + convert_to_string_ex(&args[i]); smart_str_appendc(&str, '_'); - smart_str_appendl(&str, Z_STRVAL_PP(args[i]), Z_STRLEN_PP(args[i])); + smart_str_appendl(&str, Z_STRVAL(args[i]), Z_STRLEN(args[i])); } smart_str_0(&str); if (ZEND_NUM_ARGS() == 1) { /* new style, using connection string */ - connstring = Z_STRVAL_PP(args[0]); + connstring = Z_STRVAL(args[0]); } else if (ZEND_NUM_ARGS() == 2 ) { /* Safe to add conntype_option, since 2 args was illegal */ - connstring = Z_STRVAL_PP(args[0]); - convert_to_long_ex(args[1]); - connect_type = Z_LVAL_PP(args[1]); + connstring = Z_STRVAL(args[0]); + convert_to_long_ex(&args[1]); + connect_type = (int)Z_LVAL(args[1]); } else { - host = Z_STRVAL_PP(args[0]); - port = Z_STRVAL_PP(args[1]); - dbname = Z_STRVAL_PP(args[ZEND_NUM_ARGS()-1]); + host = Z_STRVAL(args[0]); + port = Z_STRVAL(args[1]); + dbname = Z_STRVAL(args[ZEND_NUM_ARGS()-1]); switch (ZEND_NUM_ARGS()) { case 5: - tty = Z_STRVAL_PP(args[3]); + tty = Z_STRVAL(args[3]); /* fall through */ case 4: - options = Z_STRVAL_PP(args[2]); + options = Z_STRVAL(args[2]); break; } } + efree(args); if (persistent && PGG(allow_persistent)) { - zend_rsrc_list_entry *le; - + zend_resource *le; + /* try to find if we already have this link in our persistent list */ - if (zend_hash_find(&EG(persistent_list), str.c, str.len+1, (void **) &le)==FAILURE) { /* we don't */ - zend_rsrc_list_entry new_le; - - if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Cannot create new link. Too many open links (%ld)", PGG(num_links)); + if ((le = zend_hash_find_ptr(&EG(persistent_list), str.s)) == NULL) { /* we don't */ + zend_resource new_le; + + if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) { + php_error_docref(NULL, E_WARNING, + "Cannot create new link. Too many open links (%pd)", PGG(num_links)); goto err; } - if (PGG(max_persistent)!=-1 && PGG(num_persistent)>=PGG(max_persistent)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Cannot create new link. Too many open persistent links (%ld)", PGG(num_persistent)); + if (PGG(max_persistent) != -1 && PGG(num_persistent) >= PGG(max_persistent)) { + php_error_docref(NULL, E_WARNING, + "Cannot create new link. Too many open persistent links (%pd)", PGG(num_persistent)); goto err; } /* create the link */ if (connstring) { - pgsql=PQconnectdb(connstring); + pgsql = PQconnectdb(connstring); } else { - pgsql=PQsetdb(host,port,options,tty,dbname); + pgsql = PQsetdb(host, port, options, tty, dbname); } - if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { + if (pgsql == NULL || PQstatus(pgsql) == CONNECTION_BAD) { PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql) if (pgsql) { PQfinish(pgsql); @@ -1356,15 +1362,15 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) } /* hash it up */ - Z_TYPE(new_le) = le_plink; + new_le.type = le_plink; new_le.ptr = pgsql; - if (zend_hash_update(&EG(persistent_list), str.c, str.len+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) { + if (zend_hash_str_update_mem(&EG(persistent_list), str.s->val, str.s->len, &new_le, sizeof(zend_resource)) == NULL) { goto err; } PGG(num_links)++; PGG(num_persistent)++; } else { /* we do */ - if (Z_TYPE_P(le) != le_plink) { + if (le->type != le_plink) { RETURN_FALSE; } /* ensure that the link did not die */ @@ -1375,20 +1381,20 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) pg_result = PQexec(le->ptr, "select 1"); PQclear(pg_result); } - if (PQstatus(le->ptr)==CONNECTION_BAD) { /* the link died */ + if (PQstatus(le->ptr) == CONNECTION_BAD) { /* the link died */ if (le->ptr == NULL) { if (connstring) { - le->ptr=PQconnectdb(connstring); + le->ptr = PQconnectdb(connstring); } else { - le->ptr=PQsetdb(host,port,options,tty,dbname); + le->ptr = PQsetdb(host,port,options,tty,dbname); } } else { PQreset(le->ptr); } - if (le->ptr==NULL || PQstatus(le->ptr)==CONNECTION_BAD) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"PostgreSQL link lost, unable to reconnect"); - zend_hash_del(&EG(persistent_list),str.c,str.len+1); + if (le->ptr == NULL || PQstatus(le->ptr) == CONNECTION_BAD) { + php_error_docref(NULL, E_WARNING,"PostgreSQL link lost, unable to reconnect"); + zend_hash_del(&EG(persistent_list), str.s); goto err; } } @@ -1402,9 +1408,9 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) PQclear(pg_result); } } - ZEND_REGISTER_RESOURCE(return_value, pgsql, le_plink); + RETVAL_RES(zend_register_resource(pgsql, le_plink)); } else { /* Non persistent connection */ - zend_rsrc_list_entry *index_ptr,new_index_ptr; + zend_resource *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. @@ -1412,28 +1418,25 @@ 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) - && zend_hash_find(&EG(regular_list),str.c,str.len+1,(void **) &index_ptr)==SUCCESS) { - int type; - ulong link; - void *ptr; + && (index_ptr = zend_hash_find_ptr(&EG(regular_list), str.s)) != NULL) { + zend_resource *link; - if (Z_TYPE_P(index_ptr) != le_index_ptr) { + if (index_ptr->type != le_index_ptr) { RETURN_FALSE; } - link = (ulong) index_ptr->ptr; - ptr = zend_list_find(link,&type); /* check if the link is still there */ - if (ptr && (type==le_link || type==le_plink)) { - Z_LVAL_P(return_value) = link; - zend_list_addref(link); - php_pgsql_set_default_link(link TSRMLS_CC); - Z_TYPE_P(return_value) = IS_RESOURCE; + + link = (zend_resource *)index_ptr->ptr; + if (link->ptr && (link->type == le_link || link->type == le_plink)) { + php_pgsql_set_default_link(link); + GC_REFCOUNT(link)++; + RETVAL_RES(link); goto cleanup; } else { - zend_hash_del(&EG(regular_list),str.c,str.len+1); + zend_hash_del(&EG(regular_list), str.s); } } - if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", PGG(num_links)); + if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) { + php_error_docref(NULL, E_WARNING, "Cannot create new link. Too many open links (%pd)", PGG(num_links)); goto err; } @@ -1449,7 +1452,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) goto err; } } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection string required for async connections"); + php_error_docref(NULL, E_WARNING, "Connection string required for async connections"); goto err; } } else { @@ -1468,22 +1471,22 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) } /* add it to the list */ - ZEND_REGISTER_RESOURCE(return_value, pgsql, le_link); + RETVAL_RES(zend_register_resource(pgsql, le_link)); /* add it to the hash */ - new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); - Z_TYPE(new_index_ptr) = le_index_ptr; - if (zend_hash_update(&EG(regular_list),str.c,str.len+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) { + new_index_ptr.ptr = (void *) Z_RES_P(return_value); + new_index_ptr.type = le_index_ptr; + if (zend_hash_update_mem(&EG(regular_list), str.s, (void *) &new_index_ptr, sizeof(zend_resource)) == NULL) { goto err; } PGG(num_links)++; } /* set notice processor */ if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_RESOURCE) { - PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)Z_RESVAL_P(return_value)); + PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)(zend_uintptr_t)Z_RES_HANDLE_P(return_value)); } - php_pgsql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC); - + php_pgsql_set_default_link(Z_RES_P(return_value)); + cleanup: smart_str_free(&str); return; @@ -1521,20 +1524,17 @@ PHP_FUNCTION(pg_connect) PHP_FUNCTION(pg_connect_poll) { zval *pgsql_link; - int id = -1; PGconn *pgsql; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { return; } - - if (pgsql_link == NULL && id == -1) { + + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - ret = PQconnectPoll(pgsql); RETURN_LONG(ret); @@ -1550,43 +1550,42 @@ PHP_FUNCTION(pg_pconnect) /* }}} */ /* {{{ proto bool pg_close([resource connection]) - Close a PostgreSQL connection */ + Close a PostgreSQL connection */ PHP_FUNCTION(pg_close) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + zend_resource *link; + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(argc, "|r", &pgsql_link) == FAILURE) { return; } if (argc == 0) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - - if (id==-1) { /* explicit resource number */ - zend_list_delete(Z_RESVAL_P(pgsql_link)); + if (argc == 0) { /* explicit resource number */ + zend_list_close(link); } - if (id!=-1 - || (pgsql_link && Z_RESVAL_P(pgsql_link)==PGG(default_link))) { - zend_list_delete(PGG(default_link)); - PGG(default_link) = -1; + if (argc || (pgsql_link && Z_RES_P(pgsql_link) == PGG(default_link))) { + zend_list_close(link); + PGG(default_link) = NULL; } RETURN_TRUE; } /* }}} */ - #define PHP_PG_DBNAME 1 #define PHP_PG_ERROR_MESSAGE 2 #define PHP_PG_OPTIONS 3 @@ -1595,80 +1594,83 @@ PHP_FUNCTION(pg_close) #define PHP_PG_HOST 6 #define PHP_PG_VERSION 7 - /* {{{ php_pgsql_get_link_info */ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { + zend_resource *link; zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; char *msgbuf; + char *result; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(argc, "|r", &pgsql_link) == FAILURE) { return; } - + if (argc == 0) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + link = Z_RES_P(pgsql_link); } - - if (pgsql_link == NULL && id == -1) { + + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - switch(entry_type) { case PHP_PG_DBNAME: - Z_STRVAL_P(return_value) = PQdb(pgsql); + result = PQdb(pgsql); break; case PHP_PG_ERROR_MESSAGE: - RETURN_STRING(PQErrorMessageTrim(pgsql, &msgbuf), 0); + result = PQErrorMessageTrim(pgsql, &msgbuf); + RETVAL_STRING(result); + efree(result); return; case PHP_PG_OPTIONS: - Z_STRVAL_P(return_value) = PQoptions(pgsql); + result = PQoptions(pgsql); break; case PHP_PG_PORT: - Z_STRVAL_P(return_value) = PQport(pgsql); + result = PQport(pgsql); break; case PHP_PG_TTY: - Z_STRVAL_P(return_value) = PQtty(pgsql); + result = PQtty(pgsql); break; case PHP_PG_HOST: - Z_STRVAL_P(return_value) = PQhost(pgsql); + result = PQhost(pgsql); break; case PHP_PG_VERSION: array_init(return_value); - add_assoc_string(return_value, "client", PG_VERSION, 1); + add_assoc_string(return_value, "client", PG_VERSION); #if HAVE_PQPROTOCOLVERSION add_assoc_long(return_value, "protocol", PQprotocolVersion(pgsql)); #if HAVE_PQPARAMETERSTATUS if (PQprotocolVersion(pgsql) >= 3) { /* 8.0 or grater supports protorol version 3 */ char *tmp; - add_assoc_string(return_value, "server", (char*)PQparameterStatus(pgsql, "server_version"), 1); + add_assoc_string(return_value, "server", (char*)PQparameterStatus(pgsql, "server_version")); tmp = (char*)PQparameterStatus(pgsql, "server_encoding"); - add_assoc_string(return_value, "server_encoding", tmp, 1); + add_assoc_string(return_value, "server_encoding", tmp); tmp = (char*)PQparameterStatus(pgsql, "client_encoding"); - add_assoc_string(return_value, "client_encoding", tmp, 1); + add_assoc_string(return_value, "client_encoding", tmp); tmp = (char*)PQparameterStatus(pgsql, "is_superuser"); - add_assoc_string(return_value, "is_superuser", tmp, 1); + add_assoc_string(return_value, "is_superuser", tmp); tmp = (char*)PQparameterStatus(pgsql, "session_authorization"); - add_assoc_string(return_value, "session_authorization", tmp, 1); + add_assoc_string(return_value, "session_authorization", tmp); tmp = (char*)PQparameterStatus(pgsql, "DateStyle"); - add_assoc_string(return_value, "DateStyle", tmp, 1); + add_assoc_string(return_value, "DateStyle", tmp); tmp = (char*)PQparameterStatus(pgsql, "IntervalStyle"); - add_assoc_string(return_value, "IntervalStyle", tmp ? tmp : "", 1); + add_assoc_string(return_value, "IntervalStyle", tmp ? tmp : ""); tmp = (char*)PQparameterStatus(pgsql, "TimeZone"); - add_assoc_string(return_value, "TimeZone", tmp ? tmp : "", 1); + add_assoc_string(return_value, "TimeZone", tmp ? tmp : ""); tmp = (char*)PQparameterStatus(pgsql, "integer_datetimes"); - add_assoc_string(return_value, "integer_datetimes", tmp ? tmp : "", 1); + add_assoc_string(return_value, "integer_datetimes", tmp ? tmp : ""); tmp = (char*)PQparameterStatus(pgsql, "standard_conforming_strings"); - add_assoc_string(return_value, "standard_conforming_strings", tmp ? tmp : "", 1); + add_assoc_string(return_value, "standard_conforming_strings", tmp ? tmp : ""); tmp = (char*)PQparameterStatus(pgsql, "application_name"); - add_assoc_string(return_value, "application_name", tmp ? tmp : "", 1); + add_assoc_string(return_value, "application_name", tmp ? tmp : ""); } #endif #endif @@ -1676,19 +1678,16 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type default: RETURN_FALSE; } - if (Z_STRVAL_P(return_value)) { - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value)); + if (result) { + RETURN_STRING(result); } else { - Z_STRLEN_P(return_value) = 0; - Z_STRVAL_P(return_value) = (char *) estrdup(""); + RETURN_EMPTY_STRING(); } - Z_TYPE_P(return_value) = IS_STRING; } /* }}} */ /* {{{ proto string pg_dbname([resource connection]) - Get the database name */ + Get the database name */ PHP_FUNCTION(pg_dbname) { php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_DBNAME); @@ -1748,29 +1747,30 @@ PHP_FUNCTION(pg_version) Returns the value of a server parameter */ PHP_FUNCTION(pg_parameter_status) { - zval *pgsql_link; - int id; + zval *pgsql_link = NULL; + zend_resource *link; PGconn *pgsql; char *param; - int len; + size_t len; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, ¶m, &len) == SUCCESS) { - id = -1; - } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", ¶m, &len) == SUCCESS) { - pgsql_link = NULL; - id = PGG(default_link); + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "rs", &pgsql_link, ¶m, &len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", ¶m, &len) == SUCCESS) { + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + RETURN_FALSE; + } } else { - RETURN_FALSE; + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - param = (char*)PQparameterStatus(pgsql, param); if (param) { - RETURN_STRING(param, 1); + RETURN_STRING(param); } else { RETURN_FALSE; } @@ -1783,22 +1783,21 @@ PHP_FUNCTION(pg_parameter_status) PHP_FUNCTION(pg_ping) { zval *pgsql_link; - int id; PGconn *pgsql; PGresult *res; + zend_resource *link; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == SUCCESS) { - id = -1; + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &pgsql_link) == SUCCESS) { + link = Z_RES_P(pgsql_link); } else { - pgsql_link = NULL; - id = PGG(default_link); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } - if (pgsql_link == NULL && id == -1) { + + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - /* ping connection */ res = PQexec(pgsql, "SELECT 1;"); PQclear(res); @@ -1822,33 +1821,34 @@ PHP_FUNCTION(pg_query) { zval *pgsql_link = NULL; char *query; - int id = -1, query_len, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); + size_t query_len; int leftover = 0; + zend_resource *link; PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; pgsql_result_handle *pg_result; if (argc == 1) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query, &query_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &query, &query_len) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); RETURN_FALSE; } while ((pgsql_result = PQgetResult(pgsql))) { @@ -1856,7 +1856,7 @@ PHP_FUNCTION(pg_query) leftover = 1; } if (leftover) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); + php_error_docref(NULL, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); } pgsql_result = PQexec(pgsql, query); if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { @@ -1887,7 +1887,7 @@ PHP_FUNCTION(pg_query) pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result); + RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -1920,37 +1920,38 @@ static void _php_pgsql_free_params(char **params, int num_params) PHP_FUNCTION(pg_query_params) { zval *pgsql_link = NULL; - zval *pv_param_arr, **tmp; + zval *pv_param_arr, *tmp; char *query; - int query_len, id = -1, argc = ZEND_NUM_ARGS(); + size_t query_len; + int argc = ZEND_NUM_ARGS(); int leftover = 0; int num_params = 0; char **params = NULL; + zend_resource *link; PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; pgsql_result_handle *pg_result; - + if (argc == 2) { - if (zend_parse_parameters(argc TSRMLS_CC, "sa", &query, &query_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(argc, "sa", &query, &query_len, &pv_param_arr) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rsa", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(argc, "rsa", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); RETURN_FALSE; } while ((pgsql_result = PQgetResult(pgsql))) { @@ -1958,48 +1959,42 @@ PHP_FUNCTION(pg_query_params) leftover = 1; } if (leftover) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); + php_error_docref(NULL, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr)); num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - for(i = 0; i < num_params; i++) { - if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); - _php_pgsql_free_params(params, num_params); - RETURN_FALSE; - } + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { - if (Z_TYPE_PP(tmp) == IS_NULL) { + if (Z_TYPE_P(tmp) == IS_NULL) { params[i] = NULL; } else { - zval tmp_val = **tmp; - zval_copy_ctor(&tmp_val); + zval tmp_val; + + ZVAL_COPY(&tmp_val, tmp); convert_to_cstring(&tmp_val); if (Z_TYPE(tmp_val) != IS_STRING) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter"); - zval_dtor(&tmp_val); + php_error_docref(NULL, E_WARNING,"Error converting parameter"); + zval_ptr_dtor(&tmp_val); _php_pgsql_free_params(params, num_params); RETURN_FALSE; } params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); - zval_dtor(&tmp_val); + zval_ptr_dtor(&tmp_val); } - - zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr)); - } + i++; + } ZEND_HASH_FOREACH_END(); } - pgsql_result = PQexecParams(pgsql, query, num_params, + pgsql_result = PQexecParams(pgsql, query, num_params, NULL, (const char * const *)params, NULL, NULL, 0); if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { PQclear(pgsql_result); PQreset(pgsql); - pgsql_result = PQexecParams(pgsql, query, num_params, + pgsql_result = PQexecParams(pgsql, query, num_params, NULL, (const char * const *)params, NULL, NULL, 0); } @@ -2008,7 +2003,7 @@ PHP_FUNCTION(pg_query_params) } else { status = (ExecStatusType) PQstatus(pgsql); } - + _php_pgsql_free_params(params, num_params); switch (status) { @@ -2027,7 +2022,7 @@ PHP_FUNCTION(pg_query_params) pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result); + RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -2045,33 +2040,34 @@ PHP_FUNCTION(pg_prepare) { zval *pgsql_link = NULL; char *query, *stmtname; - int query_len, stmtname_len, id = -1, argc = ZEND_NUM_ARGS(); + size_t query_len, stmtname_len; + int argc = ZEND_NUM_ARGS(); int leftover = 0; PGconn *pgsql; + zend_resource *link; PGresult *pgsql_result; ExecStatusType status; pgsql_result_handle *pg_result; if (argc == 2) { - if (zend_parse_parameters(argc TSRMLS_CC, "ss", &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(argc, "ss", &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(argc, "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); RETURN_FALSE; } while ((pgsql_result = PQgetResult(pgsql))) { @@ -2079,7 +2075,7 @@ PHP_FUNCTION(pg_prepare) leftover = 1; } if (leftover) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); + php_error_docref(NULL, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); } pgsql_result = PQprepare(pgsql, stmtname, query, 0, NULL); if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { @@ -2110,7 +2106,7 @@ PHP_FUNCTION(pg_prepare) pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result); + RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -2127,37 +2123,38 @@ PHP_FUNCTION(pg_prepare) PHP_FUNCTION(pg_execute) { zval *pgsql_link = NULL; - zval *pv_param_arr, **tmp; + zval *pv_param_arr, *tmp; char *stmtname; - int stmtname_len, id = -1, argc = ZEND_NUM_ARGS(); + size_t stmtname_len; + int argc = ZEND_NUM_ARGS(); int leftover = 0; int num_params = 0; char **params = NULL; PGconn *pgsql; + zend_resource *link; PGresult *pgsql_result; ExecStatusType status; pgsql_result_handle *pg_result; if (argc == 2) { - if (zend_parse_parameters(argc TSRMLS_CC, "sa/", &stmtname, &stmtname_len, &pv_param_arr)==FAILURE) { + if (zend_parse_parameters(argc, "sa/", &stmtname, &stmtname_len, &pv_param_arr)==FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rsa/", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(argc, "rsa/", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE,"Cannot set connection to blocking mode"); RETURN_FALSE; } while ((pgsql_result = PQgetResult(pgsql))) { @@ -2165,48 +2162,43 @@ PHP_FUNCTION(pg_execute) leftover = 1; } if (leftover) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); + php_error_docref(NULL, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr)); num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - for(i = 0; i < num_params; i++) { - if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); - _php_pgsql_free_params(params, num_params); - RETURN_FALSE; - } + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { - if (Z_TYPE_PP(tmp) == IS_NULL) { + if (Z_TYPE_P(tmp) == IS_NULL) { params[i] = NULL; } else { - zval tmp_val = **tmp; - zval_copy_ctor(&tmp_val); + zval tmp_val; + + ZVAL_COPY(&tmp_val, tmp); convert_to_string(&tmp_val); if (Z_TYPE(tmp_val) != IS_STRING) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter"); - zval_dtor(&tmp_val); + php_error_docref(NULL, E_WARNING,"Error converting parameter"); + zval_ptr_dtor(&tmp_val); _php_pgsql_free_params(params, num_params); RETURN_FALSE; } params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); - zval_dtor(&tmp_val); + zval_ptr_dtor(&tmp_val); } - zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr)); - } + i++; + } ZEND_HASH_FOREACH_END(); } - pgsql_result = PQexecPrepared(pgsql, stmtname, num_params, + pgsql_result = PQexecPrepared(pgsql, stmtname, num_params, (const char * const *)params, NULL, NULL, 0); if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { PQclear(pgsql_result); PQreset(pgsql); - pgsql_result = PQexecPrepared(pgsql, stmtname, num_params, + pgsql_result = PQexecPrepared(pgsql, stmtname, num_params, (const char * const *)params, NULL, NULL, 0); } @@ -2234,7 +2226,7 @@ PHP_FUNCTION(pg_execute) pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result); + RETURN_RES(zend_register_resource(pg_result, le_result)); } else { PQclear(pgsql_result); RETURN_FALSE; @@ -2257,33 +2249,34 @@ static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_ty PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { return; } - - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; switch (entry_type) { case PHP_PG_NUM_ROWS: - Z_LVAL_P(return_value) = PQntuples(pgsql_result); + RETVAL_LONG(PQntuples(pgsql_result)); break; case PHP_PG_NUM_FIELDS: - Z_LVAL_P(return_value) = PQnfields(pgsql_result); + RETVAL_LONG(PQnfields(pgsql_result)); break; case PHP_PG_CMD_TUPLES: #if HAVE_PQCMDTUPLES - Z_LVAL_P(return_value) = atoi(PQcmdTuples(pgsql_result)); + RETVAL_LONG(atoi(PQcmdTuples(pgsql_result))); #else - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported under this build"); - Z_LVAL_P(return_value) = 0; + php_error_docref(NULL, E_WARNING, "Not supported under this build"); + RETVAL_LONG(0); #endif break; default: RETURN_FALSE; } - Z_TYPE_P(return_value) = IS_LONG; } /* }}} */ @@ -2315,33 +2308,35 @@ PHP_FUNCTION(pg_affected_rows) /* {{{ proto string pg_last_notice(resource connection) Returns the last notice set by the backend */ -PHP_FUNCTION(pg_last_notice) +PHP_FUNCTION(pg_last_notice) { - zval *pgsql_link; + zval *pgsql_link = NULL; PGconn *pg_link; - int id = -1; - php_pgsql_notice **notice; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + php_pgsql_notice *notice; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { return; } + /* Just to check if user passed valid resoruce */ - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } - if (zend_hash_index_find(&PGG(notices), Z_RESVAL_P(pgsql_link), (void **)¬ice) == FAILURE) { + if ((notice = zend_hash_index_find_ptr(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link))) == NULL) { RETURN_FALSE; } - RETURN_STRINGL((*notice)->message, (*notice)->len, 1); + RETURN_STRINGL(notice->message, notice->len); } /* }}} */ /* {{{ get_field_name */ -static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) +static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list) { PGresult *result; smart_str str = {0}; - zend_rsrc_list_entry *field_type; + zend_resource *field_type; char *ret=NULL; /* try to lookup the type in the resource list */ @@ -2349,20 +2344,20 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) smart_str_append_unsigned(&str, oid); smart_str_0(&str); - if (zend_hash_find(list,str.c,str.len+1,(void **) &field_type)==SUCCESS) { + if ((field_type = zend_hash_find_ptr(list, str.s)) != NULL) { ret = estrdup((char *)field_type->ptr); } else { /* hash all oid's */ - int i,num_rows; + int i, num_rows; int oid_offset,name_offset; char *tmp_oid, *end_ptr, *tmp_name; - zend_rsrc_list_entry new_oid_entry; + zend_resource new_oid_entry; - if ((result = PQexec(pgsql,"select oid,typname from pg_type")) == NULL || PQresultStatus(result) != PGRES_TUPLES_OK) { + if ((result = PQexec(pgsql, "select oid,typname from pg_type")) == NULL || PQresultStatus(result) != PGRES_TUPLES_OK) { if (result) { PQclear(result); } smart_str_free(&str); - return STR_EMPTY_ALLOC(); + return estrndup("", sizeof("") - 1); } num_rows = PQntuples(result); oid_offset = PQfnumber(result,"oid"); @@ -2372,8 +2367,8 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) if ((tmp_oid = PQgetvalue(result,i,oid_offset))==NULL) { continue; } - - str.len = 0; + + str.s->len = 0; smart_str_appends(&str, "pgsql_oid_"); smart_str_appends(&str, tmp_oid); smart_str_0(&str); @@ -2381,9 +2376,9 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) if ((tmp_name = PQgetvalue(result,i,name_offset))==NULL) { continue; } - Z_TYPE(new_oid_entry) = le_string; + new_oid_entry.type = le_string; new_oid_entry.ptr = estrdup(tmp_name); - zend_hash_update(list,str.c,str.len+1,(void *) &new_oid_entry, sizeof(zend_rsrc_list_entry), NULL); + zend_hash_update_mem(list, str.s, (void *) &new_oid_entry, sizeof(zend_resource)); if (!ret && strtoul(tmp_oid, &end_ptr, 10)==oid) { ret = estrdup(tmp_name); } @@ -2403,40 +2398,42 @@ PHP_FUNCTION(pg_field_table) { zval *result; pgsql_result_handle *pg_result; - long fnum = -1; + zend_long fnum = -1; zend_bool return_oid = 0; Oid oid; smart_str hash_key = {0}; char *table_name; - zend_rsrc_list_entry *field_table; + zend_resource *field_table; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|b", &result, &fnum, &return_oid) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|b", &result, &fnum, &return_oid) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } if (fnum < 0 || fnum >= PQnfields(pg_result->result)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified"); + php_error_docref(NULL, E_WARNING, "Bad field offset specified"); RETURN_FALSE; } - oid = PQftable(pg_result->result, fnum); + oid = PQftable(pg_result->result, (int)fnum); if (InvalidOid == oid) { RETURN_FALSE; } if (return_oid) { -#if UINT_MAX > LONG_MAX /* Oid is unsigned int, we don't need this code, where LONG is wider */ - if (oid > LONG_MAX) { +#if UINT_MAX > ZEND_LONG_MAX /* Oid is unsigned int, we don't need this code, where LONG is wider */ + if (oid > ZEND_LONG_MAX) { smart_str oidstr = {0}; smart_str_append_unsigned(&oidstr, oid); smart_str_0(&oidstr); - RETURN_STRINGL(oidstr.c, oidstr.len, 0); + RETURN_NEW_STR(oidstr.s); } else #endif - RETURN_LONG((long)oid); + RETURN_LONG((zend_long)oid); } /* try to lookup the table name in the resource list */ @@ -2444,19 +2441,19 @@ PHP_FUNCTION(pg_field_table) smart_str_append_unsigned(&hash_key, oid); smart_str_0(&hash_key); - if (zend_hash_find(&EG(regular_list), hash_key.c, hash_key.len+1, (void **) &field_table) == SUCCESS) { + if ((field_table = zend_hash_find_ptr(&EG(regular_list), hash_key.s)) != NULL) { smart_str_free(&hash_key); - RETURN_STRING((char *)field_table->ptr, 1); + RETURN_STRING((char *)field_table->ptr); } else { /* Not found, lookup by querying PostgreSQL system tables */ PGresult *tmp_res; smart_str querystr = {0}; - zend_rsrc_list_entry new_field_table; + zend_resource new_field_table; smart_str_appends(&querystr, "select relname from pg_class where oid="); smart_str_append_unsigned(&querystr, oid); smart_str_0(&querystr); - if ((tmp_res = PQexec(pg_result->conn, querystr.c)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) { + if ((tmp_res = PQexec(pg_result->conn, querystr.s->val)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) { if (tmp_res) { PQclear(tmp_res); } @@ -2473,13 +2470,13 @@ PHP_FUNCTION(pg_field_table) RETURN_FALSE; } - Z_TYPE(new_field_table) = le_string; + new_field_table.type = le_string; new_field_table.ptr = estrdup(table_name); - zend_hash_update(&EG(regular_list), hash_key.c, hash_key.len+1, (void *) &new_field_table, sizeof(zend_rsrc_list_entry), NULL); + zend_hash_update_mem(&EG(regular_list), hash_key.s, (void *)&new_field_table, sizeof(zend_resource)); smart_str_free(&hash_key); PQclear(tmp_res); - RETURN_STRING(table_name, 1); + RETURN_STRING(table_name); } } @@ -2496,56 +2493,53 @@ PHP_FUNCTION(pg_field_table) static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { zval *result; - long field; + zend_long field; PGresult *pgsql_result; pgsql_result_handle *pg_result; Oid oid; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result, &field) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } + pgsql_result = pg_result->result; - + if (field < 0 || field >= PQnfields(pgsql_result)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified"); + php_error_docref(NULL, E_WARNING, "Bad field offset specified"); RETURN_FALSE; } switch (entry_type) { case PHP_PG_FIELD_NAME: - Z_STRVAL_P(return_value) = PQfname(pgsql_result, field); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + RETURN_STRING(PQfname(pgsql_result, (int)field)); break; case PHP_PG_FIELD_SIZE: - Z_LVAL_P(return_value) = PQfsize(pgsql_result, field); - Z_TYPE_P(return_value) = IS_LONG; + RETURN_LONG(PQfsize(pgsql_result, (int)field)); break; - case PHP_PG_FIELD_TYPE: - Z_STRVAL_P(return_value) = get_field_name(pg_result->conn, PQftype(pgsql_result, field), &EG(regular_list) TSRMLS_CC); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + case PHP_PG_FIELD_TYPE: { + char *name = get_field_name(pg_result->conn, PQftype(pgsql_result, (int)field), &EG(regular_list)); + RETVAL_STRING(name); + efree(name); + } break; case PHP_PG_FIELD_TYPE_OID: - - oid = PQftype(pgsql_result, field); -#if UINT_MAX > LONG_MAX - if (oid > LONG_MAX) { + + oid = PQftype(pgsql_result, (int)field); +#if UINT_MAX > ZEND_LONG_MAX + if (oid > ZEND_LONG_MAX) { smart_str s = {0}; smart_str_append_unsigned(&s, oid); smart_str_0(&s); - Z_STRVAL_P(return_value) = s.c; - Z_STRLEN_P(return_value) = s.len; - Z_TYPE_P(return_value) = IS_STRING; + RETURN_NEW_STR(s.s); } else #endif { - Z_LVAL_P(return_value) = (long)oid; - Z_TYPE_P(return_value) = IS_LONG; + RETURN_LONG((zend_long)oid); } break; default: @@ -2563,7 +2557,7 @@ PHP_FUNCTION(pg_field_name) /* }}} */ /* {{{ proto int pg_field_size(resource result, int field_number) - Returns the internal size of the field */ + Returns the internal size of the field */ PHP_FUNCTION(pg_field_size) { php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_SIZE); @@ -2578,7 +2572,6 @@ PHP_FUNCTION(pg_field_type) } /* }}} */ - /* {{{ proto string pg_field_type_oid(resource result, int field_number) Returns the type oid for the given field */ PHP_FUNCTION(pg_field_type_oid) @@ -2593,20 +2586,21 @@ PHP_FUNCTION(pg_field_num) { zval *result; char *field; - int field_len; + size_t field_len; PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &result, &field, &field_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &result, &field, &field_len) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; - Z_LVAL_P(return_value) = PQfnumber(pgsql_result, field); - Z_TYPE_P(return_value) = IS_LONG; + RETURN_LONG(PQfnumber(pgsql_result, field)); } /* }}} */ @@ -2614,23 +2608,25 @@ PHP_FUNCTION(pg_field_num) Returns values from a result identifier */ PHP_FUNCTION(pg_fetch_result) { - zval *result, **field=NULL; - long row; + zval *result, *field=NULL; + zend_long row; PGresult *pgsql_result; pgsql_result_handle *pg_result; int field_offset, pgsql_row, argc = ZEND_NUM_ARGS(); if (argc == 2) { - if (zend_parse_parameters(argc TSRMLS_CC, "rZ", &result, &field) == FAILURE) { + if (zend_parse_parameters(argc, "rz", &result, &field) == FAILURE) { return; } } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rlZ", &result, &row, &field) == FAILURE) { + if (zend_parse_parameters(argc, "rlz", &result, &row, &field) == FAILURE) { return; } } - - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; if (argc == 2) { @@ -2642,68 +2638,70 @@ PHP_FUNCTION(pg_fetch_result) RETURN_FALSE; } } else { - pgsql_row = row; - if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on PostgreSQL result index %ld", + if (row < 0 || row >= PQntuples(pgsql_result)) { + php_error_docref(NULL, E_WARNING, "Unable to jump to row %pd on PostgreSQL result index %pd", row, Z_LVAL_P(result)); RETURN_FALSE; } + pgsql_row = (int)row; } - switch(Z_TYPE_PP(field)) { + switch (Z_TYPE_P(field)) { case IS_STRING: - field_offset = PQfnumber(pgsql_result, Z_STRVAL_PP(field)); + field_offset = PQfnumber(pgsql_result, Z_STRVAL_P(field)); + if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) { + php_error_docref(NULL, E_WARNING, "Bad column offset specified"); + RETURN_FALSE; + } break; default: convert_to_long_ex(field); - field_offset = Z_LVAL_PP(field); + if (Z_LVAL_P(field) < 0 || Z_LVAL_P(field) >= PQnfields(pgsql_result)) { + php_error_docref(NULL, E_WARNING, "Bad column offset specified"); + RETURN_FALSE; + } + field_offset = (int)Z_LVAL_P(field); break; } - if (field_offset<0 || field_offset>=PQnfields(pgsql_result)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); - RETURN_FALSE; - } if (PQgetisnull(pgsql_result, pgsql_row, field_offset)) { - Z_TYPE_P(return_value) = IS_NULL; + RETVAL_NULL(); } else { - char *value = PQgetvalue(pgsql_result, pgsql_row, field_offset); - int value_len = PQgetlength(pgsql_result, pgsql_row, field_offset); - ZVAL_STRINGL(return_value, value, value_len, 1); + RETVAL_STRINGL(PQgetvalue(pgsql_result, pgsql_row, field_offset), + PQgetlength(pgsql_result, pgsql_row, field_offset)); } } /* }}} */ /* {{{ void php_pgsql_fetch_hash */ -static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int into_object) +static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_type, int into_object) { zval *result, *zrow = NULL; PGresult *pgsql_result; pgsql_result_handle *pg_result; int i, num_fields, pgsql_row, use_row; - long row = -1; + zend_long row = -1; char *field_name; zval *ctor_params = NULL; zend_class_entry *ce = NULL; if (into_object) { - char *class_name = NULL; - int class_name_len; + zend_string *class_name = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z!sz", &result, &zrow, &class_name, &class_name_len, &ctor_params) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|z!Sz", &result, &zrow, &class_name, &ctor_params) == FAILURE) { return; } if (!class_name) { ce = zend_standard_class_def; } else { - ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); + ce = zend_fetch_class(class_name, ZEND_FETCH_CLASS_AUTO); } if (!ce) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); + php_error_docref(NULL, E_WARNING, "Could not find class '%s'", class_name->val); return; } result_type = PGSQL_ASSOC; } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z!l", &result, &zrow, &result_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|z!l", &result, &zrow, &result_type) == FAILURE) { return; } } @@ -2713,29 +2711,31 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, convert_to_long(zrow); row = Z_LVAL_P(zrow); if (row < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The row parameter must be greater or equal to zero"); + php_error_docref(NULL, E_WARNING, "The row parameter must be greater or equal to zero"); RETURN_FALSE; } } use_row = ZEND_NUM_ARGS() > 1 && row != -1; if (!(result_type & PGSQL_BOTH)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type"); + php_error_docref(NULL, E_WARNING, "Invalid result type"); + RETURN_FALSE; + } + + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; - if (use_row) { - pgsql_row = row; - pg_result->row = pgsql_row; - if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on PostgreSQL result index %ld", + if (use_row) { + if (row < 0 || row >= PQntuples(pgsql_result)) { + php_error_docref(NULL, E_WARNING, "Unable to jump to row %pd on PostgreSQL result index %pd", row, Z_LVAL_P(result)); RETURN_FALSE; } + pgsql_row = (int)row; + pg_result->row = pgsql_row; } else { /* If 2nd param is NULL, use internal row counter to access next row */ pgsql_row = pg_result->row; @@ -2758,56 +2758,57 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, } else { char *element = PQgetvalue(pgsql_result, pgsql_row, i); if (element) { - char *data; - int data_len; - int should_copy=0; - const uint element_len = strlen(element); - - data = safe_estrndup(element, element_len); - data_len = element_len; + const size_t element_len = strlen(element); if (result_type & PGSQL_NUM) { - add_index_stringl(return_value, i, data, data_len, should_copy); - should_copy=1; + add_index_stringl(return_value, i, element, element_len); } if (result_type & PGSQL_ASSOC) { field_name = PQfname(pgsql_result, i); - add_assoc_stringl(return_value, field_name, data, data_len, should_copy); + add_assoc_stringl(return_value, field_name, element, element_len); } } } } if (into_object) { - zval dataset = *return_value; + zval dataset; zend_fcall_info fci; zend_fcall_info_cache fcc; - zval *retval_ptr; + zval retval; + ZVAL_COPY_VALUE(&dataset, return_value); object_and_properties_init(return_value, ce, NULL); - zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC); + if (!ce->default_properties_count && !ce->__set) { + ALLOC_HASHTABLE(Z_OBJ_P(return_value)->properties); + *Z_OBJ_P(return_value)->properties = *Z_ARRVAL(dataset); + efree(Z_ARR(dataset)); + } else { + zend_merge_properties(return_value, Z_ARRVAL(dataset)); + zval_ptr_dtor(&dataset); + } if (ce->constructor) { fci.size = sizeof(fci); fci.function_table = &ce->function_table; - fci.function_name = NULL; + ZVAL_UNDEF(&fci.function_name); fci.symbol_table = NULL; - fci.object_ptr = return_value; - fci.retval_ptr_ptr = &retval_ptr; + fci.object = Z_OBJ_P(return_value); + fci.retval = &retval; fci.params = NULL; fci.param_count = 0; fci.no_separation = 1; if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) { - if (zend_fcall_info_args(&fci, ctor_params TSRMLS_CC) == FAILURE) { + if (zend_fcall_info_args(&fci, ctor_params) == FAILURE) { /* Two problems why we throw exceptions here: PHP is typeless * and hence passing one argument that's not an array could be * by mistake and the other way round is possible, too. The * single value is an array. Also we'd have to make that one * argument passed by reference. */ - zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC); + zend_throw_exception(zend_exception_get_default(), "Parameter ctor_params must be an array", 0); return; } } @@ -2816,27 +2817,25 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, fcc.function_handler = ce->constructor; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(return_value); - fcc.object_ptr = return_value; + fcc.object = Z_OBJ_P(return_value); - if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { - zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); + if (zend_call_function(&fci, &fcc) == FAILURE) { + zend_throw_exception_ex(zend_exception_get_default(), 0, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); } else { - if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); - } + zval_ptr_dtor(&retval); } if (fci.params) { efree(fci.params); } } else if (ctor_params) { - zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name); + zend_throw_exception_ex(zend_exception_get_default(), 0, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name); } } } /* }}} */ /* {{{ proto array pg_fetch_row(resource result [, int row [, int result_type]]) - Get a row as an enumerated array */ + Get a row as an enumerated array */ PHP_FUNCTION(pg_fetch_row) { php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_NUM, 0); @@ -2881,15 +2880,17 @@ PHP_FUNCTION(pg_fetch_all) PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; array_init(return_value); - if (php_pgsql_result2array(pgsql_result, return_value TSRMLS_CC) == FAILURE) { + if (php_pgsql_result2array(pgsql_result, return_value) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } @@ -2903,21 +2904,23 @@ PHP_FUNCTION(pg_fetch_all_columns) zval *result; PGresult *pgsql_result; pgsql_result_handle *pg_result; - unsigned long colno=0; + zend_long colno=0; int pg_numrows, pg_row; size_t num_fields; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &colno) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &result, &colno) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; num_fields = PQnfields(pgsql_result); - if (colno >= num_fields || colno < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column number '%ld'", colno); + if (colno >= (zend_long)num_fields || colno < 0) { + php_error_docref(NULL, E_WARNING, "Invalid column number '%pd'", colno); RETURN_FALSE; } @@ -2928,10 +2931,10 @@ PHP_FUNCTION(pg_fetch_all_columns) } for (pg_row = 0; pg_row < pg_numrows; pg_row++) { - if (PQgetisnull(pgsql_result, pg_row, colno)) { + if (PQgetisnull(pgsql_result, pg_row, (int)colno)) { add_next_index_null(return_value); } else { - add_next_index_string(return_value, PQgetvalue(pgsql_result, pg_row, colno), 1); + add_next_index_string(return_value, PQgetvalue(pgsql_result, pg_row, (int)colno)); } } } @@ -2942,26 +2945,27 @@ PHP_FUNCTION(pg_fetch_all_columns) PHP_FUNCTION(pg_result_seek) { zval *result; - long row; + zend_long row; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &row) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result, &row) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } if (row < 0 || row >= PQntuples(pg_result->result)) { RETURN_FALSE; } /* seek to offset */ - pg_result->row = row; + pg_result->row = (int)row; RETURN_TRUE; } /* }}} */ - #define PHP_PG_DATA_LENGTH 1 #define PHP_PG_DATA_ISNULL 2 @@ -2969,23 +2973,25 @@ PHP_FUNCTION(pg_result_seek) */ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { - zval *result, **field; - long row; + zval *result, *field; + zend_long row; PGresult *pgsql_result; pgsql_result_handle *pg_result; int field_offset, pgsql_row, argc = ZEND_NUM_ARGS(); if (argc == 2) { - if (zend_parse_parameters(argc TSRMLS_CC, "rZ", &result, &field) == FAILURE) { + if (zend_parse_parameters(argc, "rz", &result, &field) == FAILURE) { return; } } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rlZ", &result, &row, &field) == FAILURE) { + if (zend_parse_parameters(argc, "rlz", &result, &row, &field) == FAILURE) { return; } } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; if (argc == 2) { @@ -2997,38 +3003,41 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) RETURN_FALSE; } } else { - pgsql_row = row; - if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on PostgreSQL result index %ld", + if (row < 0 || row >= PQntuples(pgsql_result)) { + php_error_docref(NULL, E_WARNING, "Unable to jump to row %pd on PostgreSQL result index %pd", row, Z_LVAL_P(result)); RETURN_FALSE; } + pgsql_row = (int)row; } - switch(Z_TYPE_PP(field)) { + switch (Z_TYPE_P(field)) { case IS_STRING: convert_to_string_ex(field); - field_offset = PQfnumber(pgsql_result, Z_STRVAL_PP(field)); + field_offset = PQfnumber(pgsql_result, Z_STRVAL_P(field)); + if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) { + php_error_docref(NULL, E_WARNING, "Bad column offset specified"); + RETURN_FALSE; + } break; default: convert_to_long_ex(field); - field_offset = Z_LVAL_PP(field); + if (Z_LVAL_P(field) < 0 || Z_LVAL_P(field) >= PQnfields(pgsql_result)) { + php_error_docref(NULL, E_WARNING, "Bad column offset specified"); + RETURN_FALSE; + } + field_offset = (int)Z_LVAL_P(field); break; } - if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); - RETURN_FALSE; - } switch (entry_type) { case PHP_PG_DATA_LENGTH: - Z_LVAL_P(return_value) = PQgetlength(pgsql_result, pgsql_row, field_offset); + RETVAL_LONG(PQgetlength(pgsql_result, pgsql_row, field_offset)); break; case PHP_PG_DATA_ISNULL: - Z_LVAL_P(return_value) = PQgetisnull(pgsql_result, pgsql_row, field_offset); + RETVAL_LONG(PQgetisnull(pgsql_result, pgsql_row, field_offset)) break; } - Z_TYPE_P(return_value) = IS_LONG; } /* }}} */ @@ -3055,15 +3064,15 @@ PHP_FUNCTION(pg_free_result) zval *result; pgsql_result_handle *pg_result; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); - if (Z_LVAL_P(result) == 0) { + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { RETURN_FALSE; } - zend_list_delete(Z_RESVAL_P(result)); + + zend_list_close(Z_RES_P(result)); RETURN_TRUE; } /* }}} */ @@ -3079,11 +3088,14 @@ PHP_FUNCTION(pg_last_oid) Oid oid; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } + pgsql_result = pg_result->result; #ifdef HAVE_PQOIDVALUE oid = PQoidValue(pgsql_result); @@ -3094,9 +3106,9 @@ PHP_FUNCTION(pg_last_oid) #else Z_STRVAL_P(return_value) = (char *) PQoidStatus(pgsql_result); if (Z_STRVAL_P(return_value)) { - RETURN_STRING(Z_STRVAL_P(return_value), 1); + RETURN_STRING(Z_STRVAL_P(return_value)); } - RETURN_STRING("", 1); + RETURN_EMPTY_STRING(); #endif } /* }}} */ @@ -3106,28 +3118,29 @@ PHP_FUNCTION(pg_last_oid) PHP_FUNCTION(pg_trace) { char *z_filename, *mode = "w"; - int z_filename_len, mode_len; + size_t z_filename_len, mode_len; zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; FILE *fp = NULL; php_stream *stream; - id = PGG(default_link); + zend_resource *link; - if (zend_parse_parameters(argc TSRMLS_CC, "p|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) { + if (zend_parse_parameters(argc, "p|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) { return; } if (argc < 3) { - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - stream = php_stream_open_wrapper(z_filename, mode, REPORT_ERRORS, NULL); if (!stream) { @@ -3149,23 +3162,25 @@ PHP_FUNCTION(pg_trace) PHP_FUNCTION(pg_untrace) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; - - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + zend_resource *link; + + if (zend_parse_parameters(argc, "|r", &pgsql_link) == FAILURE) { return; } - if (argc == 0) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + if (argc == 0) { + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); PQuntrace(pgsql); RETURN_TRUE; } @@ -3178,9 +3193,10 @@ PHP_FUNCTION(pg_lo_create) zval *pgsql_link = NULL, *oid = NULL; PGconn *pgsql; Oid pgsql_oid, wanted_oid = InvalidOid; - int id = -1, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); + zend_resource *link; - if (zend_parse_parameters(argc TSRMLS_CC, "|zz", &pgsql_link, &oid) == FAILURE) { + if (zend_parse_parameters(argc, "|zz", &pgsql_link, &oid) == FAILURE) { return; } @@ -3188,20 +3204,21 @@ PHP_FUNCTION(pg_lo_create) oid = pgsql_link; pgsql_link = NULL; } - + if (pgsql_link == NULL) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); - if (id == -1) { - RETURN_FALSE; - } + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + link = Z_RES_P(pgsql_link); + } + + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (oid) { #ifndef HAVE_PG_LO_CREATE - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Passing OID value is not supported. Upgrade your PostgreSQL"); + php_error_docref(NULL, E_NOTICE, "Passing OID value is not supported. Upgrade your PostgreSQL"); #else switch (Z_TYPE_P(oid)) { case IS_STRING: @@ -3210,24 +3227,24 @@ PHP_FUNCTION(pg_lo_create) wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10); if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed"); + php_error_docref(NULL, E_NOTICE, "invalid OID value passed"); RETURN_FALSE; } } break; case IS_LONG: - if (Z_LVAL_P(oid) < (long)InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed"); + if (Z_LVAL_P(oid) < (zend_long)InvalidOid) { + php_error_docref(NULL, E_NOTICE, "invalid OID value passed"); RETURN_FALSE; } wanted_oid = (Oid)Z_LVAL_P(oid); break; default: - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed"); + php_error_docref(NULL, E_NOTICE, "invalid OID value passed"); RETURN_FALSE; } if ((pgsql_oid = lo_create(pgsql, wanted_oid)) == InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create PostgreSQL large object"); + php_error_docref(NULL, E_WARNING, "Unable to create PostgreSQL large object"); RETURN_FALSE; } @@ -3236,7 +3253,7 @@ PHP_FUNCTION(pg_lo_create) } if ((pgsql_oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create PostgreSQL large object"); + php_error_docref(NULL, E_WARNING, "Unable to create PostgreSQL large object"); RETURN_FALSE; } @@ -3249,65 +3266,66 @@ PHP_FUNCTION(pg_lo_create) PHP_FUNCTION(pg_lo_unlink) { zval *pgsql_link = NULL; - long oid_long; + zend_long oid_long; char *oid_string, *end_ptr; - int oid_strlen; + size_t oid_strlen; PGconn *pgsql; Oid oid; - int id = -1; + zend_resource *link; int argc = ZEND_NUM_ARGS(); /* accept string type since Oid type is unsigned int */ - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "rs", &pgsql_link, &oid_string, &oid_strlen) == SUCCESS) { oid = (Oid)strtoul(oid_string, &end_ptr, 10); if ((oid_string+oid_strlen) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); + php_error_docref(NULL, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "rl", &pgsql_link, &oid_long) == SUCCESS) { if (oid_long <= InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified"); + php_error_docref(NULL, E_NOTICE, "Invalid OID specified"); RETURN_FALSE; } oid = (Oid)oid_long; + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "s", &oid_string, &oid_strlen) == SUCCESS) { oid = (Oid)strtoul(oid_string, &end_ptr, 10); if ((oid_string+oid_strlen) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); + php_error_docref(NULL, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "l", &oid_long) == SUCCESS) { if (oid_long <= InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID is specified"); + php_error_docref(NULL, E_NOTICE, "Invalid OID is specified"); RETURN_FALSE; } oid = (Oid)oid_long; - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 1 or 2 arguments"); + php_error_docref(NULL, E_WARNING, "Requires 1 or 2 arguments"); RETURN_FALSE; } - if (pgsql_link == NULL && id == -1) { + + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (lo_unlink(pgsql, oid) == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete PostgreSQL large object %u", oid); + php_error_docref(NULL, E_WARNING, "Unable to delete PostgreSQL large object %u", oid); RETURN_FALSE; } RETURN_TRUE; @@ -3319,65 +3337,67 @@ PHP_FUNCTION(pg_lo_unlink) PHP_FUNCTION(pg_lo_open) { zval *pgsql_link = NULL; - long oid_long; + zend_long oid_long; char *oid_string, *end_ptr, *mode_string; - int oid_strlen, mode_strlen; + size_t oid_strlen, mode_strlen; PGconn *pgsql; Oid oid; - int id = -1, pgsql_mode=0, pgsql_lofd; - int create=0; + int pgsql_mode=0, pgsql_lofd; + int create = 0; pgLofp *pgsql_lofp; int argc = ZEND_NUM_ARGS(); + zend_resource *link; /* accept string type since Oid is unsigned int */ - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "rss", &pgsql_link, &oid_string, &oid_strlen, &mode_string, &mode_strlen) == SUCCESS) { oid = (Oid)strtoul(oid_string, &end_ptr, 10); if ((oid_string+oid_strlen) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); + php_error_docref(NULL, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "rls", &pgsql_link, &oid_long, &mode_string, &mode_strlen) == SUCCESS) { if (oid_long <= InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified"); + php_error_docref(NULL, E_NOTICE, "Invalid OID specified"); RETURN_FALSE; } oid = (Oid)oid_long; + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "ss", &oid_string, &oid_strlen, &mode_string, &mode_strlen) == SUCCESS) { oid = (Oid)strtoul(oid_string, &end_ptr, 10); if ((oid_string+oid_strlen) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); + php_error_docref(NULL, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "ls", &oid_long, &mode_string, &mode_strlen) == SUCCESS) { if (oid_long <= InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified"); + php_error_docref(NULL, E_NOTICE, "Invalid OID specified"); RETURN_FALSE; } oid = (Oid)oid_long; - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 1 or 2 arguments"); + php_error_docref(NULL, E_WARNING, "Requires 1 or 2 arguments"); RETURN_FALSE; } - if (pgsql_link == NULL && id == -1) { + + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - /* 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()... (Jouni) @@ -3403,34 +3423,33 @@ PHP_FUNCTION(pg_lo_open) if (create) { if ((oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == 0) { efree(pgsql_lofp); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create PostgreSQL large object"); + 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 TSRMLS_CC, E_WARNING, "Something is really messed up! Your database is badly corrupted in a way NOT related to PHP"); + 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; } efree(pgsql_lofp); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open PostgreSQL large object"); + php_error_docref(NULL, E_WARNING, "Unable to open PostgreSQL large object"); RETURN_FALSE; } else { pgsql_lofp->conn = pgsql; pgsql_lofp->lofd = pgsql_lofd; - Z_LVAL_P(return_value) = zend_list_insert(pgsql_lofp, le_lofp TSRMLS_CC); - Z_TYPE_P(return_value) = IS_LONG; + RETURN_RES(zend_register_resource(pgsql_lofp, le_lofp)); } } } else { efree(pgsql_lofp); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open PostgreSQL large object"); + php_error_docref(NULL, E_WARNING, "Unable to open PostgreSQL large object"); RETURN_FALSE; } } else { pgsql_lofp->conn = pgsql; pgsql_lofp->lofd = pgsql_lofd; - ZEND_REGISTER_RESOURCE(return_value, pgsql_lofp, le_lofp); + RETURN_RES(zend_register_resource(pgsql_lofp, le_lofp)); } } /* }}} */ @@ -3442,20 +3461,22 @@ PHP_FUNCTION(pg_lo_close) zval *pgsql_lofp; pgLofp *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_lofp) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_lofp) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_lofp, -1, "PostgreSQL large object", le_lofp); - + if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_lofp), "PostgreSQL large object", le_lofp)) == NULL) { + RETURN_FALSE; + } + if (lo_close((PGconn *)pgsql->conn, pgsql->lofd) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to close PostgreSQL large object descriptor %d", pgsql->lofd); + php_error_docref(NULL, E_WARNING, "Unable to close PostgreSQL large object descriptor %d", pgsql->lofd); RETVAL_FALSE; } else { RETVAL_TRUE; } - zend_list_delete(Z_RESVAL_P(pgsql_lofp)); + zend_list_close(Z_RES_P(pgsql_lofp)); return; } /* }}} */ @@ -3467,29 +3488,33 @@ PHP_FUNCTION(pg_lo_close) PHP_FUNCTION(pg_lo_read) { zval *pgsql_id; - long len; - int buf_len = PGSQL_LO_READ_BUF_SIZE, nbytes, argc = ZEND_NUM_ARGS(); - char *buf; + zend_long len; + size_t buf_len = PGSQL_LO_READ_BUF_SIZE; + int nbytes, argc = ZEND_NUM_ARGS(); + zend_string *buf; pgLofp *pgsql; - if (zend_parse_parameters(argc TSRMLS_CC, "r|l", &pgsql_id, &len) == FAILURE) { + if (zend_parse_parameters(argc, "r|l", &pgsql_id, &len) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp); + if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { + RETURN_FALSE; + } if (argc > 1) { - buf_len = len; + buf_len = len < 0 ? 0 : len; } - - buf = (char *) safe_emalloc(sizeof(char), (buf_len+1), 0); - if ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, buf_len))<0) { - efree(buf); + + buf = zend_string_alloc(buf_len, 0); + if ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf->val, buf->len))<0) { + zend_string_free(buf); RETURN_FALSE; } - buf[nbytes] = '\0'; - RETURN_STRINGL(buf, nbytes, 0); + buf->len = nbytes; + buf->val[buf->len] = '\0'; + RETURN_NEW_STR(buf); } /* }}} */ @@ -3499,23 +3524,23 @@ PHP_FUNCTION(pg_lo_write) { zval *pgsql_id; char *str; - long z_len; - int str_len, nbytes; - int len; + zend_long z_len; + size_t str_len, nbytes; + size_t len; pgLofp *pgsql; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rs|l", &pgsql_id, &str, &str_len, &z_len) == FAILURE) { + if (zend_parse_parameters(argc, "rs|l", &pgsql_id, &str, &str_len, &z_len) == FAILURE) { return; } if (argc > 2) { - if (z_len > str_len) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write more than buffer size %d. Tried to write %ld", str_len, z_len); + if (z_len > (zend_long)str_len) { + php_error_docref(NULL, E_WARNING, "Cannot write more than buffer size %d. Tried to write %pd", str_len, z_len); RETURN_FALSE; } if (z_len < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Buffer size must be larger than 0, but %ld was specified", z_len); + php_error_docref(NULL, E_WARNING, "Buffer size must be larger than 0, but %pd was specified", z_len); RETURN_FALSE; } len = z_len; @@ -3524,7 +3549,9 @@ PHP_FUNCTION(pg_lo_write) len = str_len; } - ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp); + if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { + RETURN_FALSE; + } if ((nbytes = lo_write((PGconn *)pgsql->conn, pgsql->lofd, str, len)) == -1) { RETURN_FALSE; @@ -3543,12 +3570,14 @@ PHP_FUNCTION(pg_lo_read_all) volatile int nbytes; char buf[PGSQL_LO_READ_BUF_SIZE]; pgLofp *pgsql; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_id) == FAILURE) { + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_id) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp); + if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { + RETURN_FALSE; + } tbytes = 0; while ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, PGSQL_LO_READ_BUF_SIZE))>0) { @@ -3565,42 +3594,42 @@ PHP_FUNCTION(pg_lo_import) { zval *pgsql_link = NULL, *oid = NULL; char *file_in; - int id = -1, name_len; + size_t name_len; int argc = ZEND_NUM_ARGS(); PGconn *pgsql; Oid returned_oid; + zend_resource *link; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "rp|z", &pgsql_link, &file_in, &name_len, &oid) == SUCCESS) { - ; + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "p|z", &file_in, &name_len, &oid) == SUCCESS) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } /* old calling convention, deprecated since PHP 4.2 */ - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "pr", &file_in, &name_len, &pgsql_link ) == SUCCESS) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Old API is used"); + php_error_docref(NULL, E_NOTICE, "Old API is used"); + link = Z_RES_P(pgsql_link); } else { WRONG_PARAM_COUNT; } - - if (php_check_open_basedir(file_in TSRMLS_CC)) { + + if (php_check_open_basedir(file_in)) { RETURN_FALSE; } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (oid) { #ifndef HAVE_PG_LO_IMPORT_WITH_OID - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OID value passing not supported"); + php_error_docref(NULL, E_NOTICE, "OID value passing not supported"); #else Oid wanted_oid; switch (Z_TYPE_P(oid)) { @@ -3610,20 +3639,20 @@ PHP_FUNCTION(pg_lo_import) wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10); if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed"); + php_error_docref(NULL, E_NOTICE, "invalid OID value passed"); RETURN_FALSE; } } break; case IS_LONG: - if (Z_LVAL_P(oid) < (long)InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed"); + if (Z_LVAL_P(oid) < (zend_long)InvalidOid) { + php_error_docref(NULL, E_NOTICE, "invalid OID value passed"); RETURN_FALSE; } wanted_oid = (Oid)Z_LVAL_P(oid); break; default: - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed"); + php_error_docref(NULL, E_NOTICE, "invalid OID value passed"); RETURN_FALSE; } @@ -3652,85 +3681,88 @@ PHP_FUNCTION(pg_lo_export) { zval *pgsql_link = NULL; char *file_out, *oid_string, *end_ptr; - int oid_strlen; - int id = -1, name_len; - long oid_long; + size_t oid_strlen; + size_t name_len; + zend_long oid_long; Oid oid; PGconn *pgsql; int argc = ZEND_NUM_ARGS(); + zend_resource *link; /* allow string to handle large OID value correctly */ - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "rlp", &pgsql_link, &oid_long, &file_out, &name_len) == SUCCESS) { if (oid_long <= InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified"); + php_error_docref(NULL, E_NOTICE, "Invalid OID specified"); RETURN_FALSE; } oid = (Oid)oid_long; + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "rss", &pgsql_link, &oid_string, &oid_strlen, &file_out, &name_len) == SUCCESS) { oid = (Oid)strtoul(oid_string, &end_ptr, 10); if ((oid_string+oid_strlen) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); + php_error_docref(NULL, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "lp", &oid_long, &file_out, &name_len) == SUCCESS) { if (oid_long <= InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified"); + php_error_docref(NULL, E_NOTICE, "Invalid OID specified"); RETURN_FALSE; } oid = (Oid)oid_long; - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "sp", &oid_string, &oid_strlen, &file_out, &name_len) == SUCCESS) { oid = (Oid)strtoul(oid_string, &end_ptr, 10); if ((oid_string+oid_strlen) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); + php_error_docref(NULL, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "spr", &oid_string, &oid_strlen, &file_out, &name_len, &pgsql_link) == SUCCESS) { oid = (Oid)strtoul(oid_string, &end_ptr, 10); if ((oid_string+oid_strlen) != end_ptr) { /* wrong integer format */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); + php_error_docref(NULL, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } + link = Z_RES_P(pgsql_link); } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, + else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "lpr", &oid_long, &file_out, &name_len, &pgsql_link) == SUCCESS) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Old API is used"); + php_error_docref(NULL, E_NOTICE, "Old API is used"); if (oid_long <= InvalidOid) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified"); + php_error_docref(NULL, E_NOTICE, "Invalid OID specified"); RETURN_FALSE; } oid = (Oid)oid_long; + link = Z_RES_P(pgsql_link); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 2 or 3 arguments"); + php_error_docref(NULL, E_WARNING, "Requires 2 or 3 arguments"); RETURN_FALSE; } - - if (php_check_open_basedir(file_out TSRMLS_CC)) { + + if (php_check_open_basedir(file_out)) { RETURN_FALSE; } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (lo_export(pgsql, oid, file_out) == -1) { RETURN_FALSE; } @@ -3743,25 +3775,27 @@ PHP_FUNCTION(pg_lo_export) PHP_FUNCTION(pg_lo_seek) { zval *pgsql_id = NULL; - long result, offset = 0, whence = SEEK_CUR; + zend_long result, offset = 0, whence = SEEK_CUR; pgLofp *pgsql; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rl|l", &pgsql_id, &offset, &whence) == FAILURE) { + if (zend_parse_parameters(argc, "rl|l", &pgsql_id, &offset, &whence) == FAILURE) { return; } if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid whence parameter"); + php_error_docref(NULL, E_WARNING, "Invalid whence parameter"); return; } - ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp); + if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { + RETURN_FALSE; + } #if HAVE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { - result = lo_lseek64((PGconn *)pgsql->conn, pgsql->lofd, offset, whence); + result = lo_lseek64((PGconn *)pgsql->conn, pgsql->lofd, offset, (int)whence); } else { - result = lo_lseek((PGconn *)pgsql->conn, pgsql->lofd, offset, whence); + result = lo_lseek((PGconn *)pgsql->conn, pgsql->lofd, (int)offset, (int)whence); } #else result = lo_lseek((PGconn *)pgsql->conn, pgsql->lofd, offset, whence); @@ -3779,15 +3813,17 @@ PHP_FUNCTION(pg_lo_seek) PHP_FUNCTION(pg_lo_tell) { zval *pgsql_id = NULL; - long offset = 0; + zend_long offset = 0; pgLofp *pgsql; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "r", &pgsql_id) == FAILURE) { + if (zend_parse_parameters(argc, "r", &pgsql_id) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp); + if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { + RETURN_FALSE; + } #if HAVE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { @@ -3813,11 +3849,13 @@ PHP_FUNCTION(pg_lo_truncate) int argc = ZEND_NUM_ARGS(); int result; - if (zend_parse_parameters(argc TSRMLS_CC, "rl", &pgsql_id, &size) == FAILURE) { + if (zend_parse_parameters(argc, "rl", &pgsql_id, &size) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp); + if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { + RETURN_FALSE; + } #if HAVE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { @@ -3843,31 +3881,30 @@ PHP_FUNCTION(pg_lo_truncate) PHP_FUNCTION(pg_set_error_verbosity) { zval *pgsql_link = NULL; - long verbosity; - int id = -1, argc = ZEND_NUM_ARGS(); + zend_long verbosity; + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; + zend_resource *link; if (argc == 1) { - if (zend_parse_parameters(argc TSRMLS_CC, "l", &verbosity) == FAILURE) { + if (zend_parse_parameters(argc, "l", &verbosity) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rl", &pgsql_link, &verbosity) == FAILURE) { + if (zend_parse_parameters(argc, "rl", &pgsql_link, &verbosity) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + } if (verbosity & (PQERRORS_TERSE|PQERRORS_DEFAULT|PQERRORS_VERBOSE)) { - Z_LVAL_P(return_value) = PQsetErrorVerbosity(pgsql, verbosity); - Z_TYPE_P(return_value) = IS_LONG; + RETURN_LONG(PQsetErrorVerbosity(pgsql, verbosity)); } else { RETURN_FALSE; } @@ -3881,31 +3918,30 @@ PHP_FUNCTION(pg_set_error_verbosity) PHP_FUNCTION(pg_set_client_encoding) { char *encoding; - int encoding_len; + size_t encoding_len; zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; + zend_resource *link; if (argc == 1) { - if (zend_parse_parameters(argc TSRMLS_CC, "s", &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(argc, "s", &encoding, &encoding_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rs", &pgsql_link, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(argc, "rs", &pgsql_link, &encoding, &encoding_len) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - - Z_LVAL_P(return_value) = PQsetClientEncoding(pgsql, encoding); - Z_TYPE_P(return_value) = IS_LONG; + RETURN_LONG(PQsetClientEncoding(pgsql, encoding)); } /* }}} */ @@ -3914,30 +3950,28 @@ PHP_FUNCTION(pg_set_client_encoding) PHP_FUNCTION(pg_client_encoding) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; + zend_resource *link; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(argc, "|r", &pgsql_link) == FAILURE) { return; } - + if (argc == 0) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + } /* Just do the same as found in PostgreSQL sources... */ - Z_STRVAL_P(return_value) = (char *) pg_encoding_to_char(PQclientEncoding(pgsql)); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + RETURN_STRING((char *) pg_encoding_to_char(PQclientEncoding(pgsql))); } /* }}} */ #endif @@ -3951,25 +3985,26 @@ PHP_FUNCTION(pg_client_encoding) PHP_FUNCTION(pg_end_copy) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int argc = ZEND_NUM_ARGS(); PGconn *pgsql; int result = 0; + zend_resource *link; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(argc, "|r", &pgsql_link) == FAILURE) { return; } - + if (argc == 0) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); + } else { + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - result = PQendcopy(pgsql); if (result!=0) { @@ -3980,34 +4015,33 @@ PHP_FUNCTION(pg_end_copy) } /* }}} */ - /* {{{ proto bool pg_put_line([resource connection,] string query) Send null-terminated string to backend server*/ PHP_FUNCTION(pg_put_line) { char *query; zval *pgsql_link = NULL; - int query_len, id = -1; + size_t query_len; PGconn *pgsql; + zend_resource *link; int result = 0, argc = ZEND_NUM_ARGS(); if (argc == 1) { - if (zend_parse_parameters(argc TSRMLS_CC, "s", &query, &query_len) == FAILURE) { + if (zend_parse_parameters(argc, "s", &query, &query_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); } else { - if (zend_parse_parameters(argc TSRMLS_CC, "rs", &pgsql_link, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(argc, "rs", &pgsql_link, &query, &query_len) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + } result = PQputline(pgsql, query); if (result==EOF) { @@ -4024,9 +4058,8 @@ PHP_FUNCTION(pg_copy_to) { zval *pgsql_link; char *table_name, *pg_delim = NULL, *pg_null_as = NULL; - int table_name_len, pg_delim_len, pg_null_as_len, free_pg_null = 0; + size_t table_name_len, pg_delim_len, pg_null_as_len, free_pg_null = 0; char *query; - int id = -1; PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; @@ -4038,7 +4071,7 @@ PHP_FUNCTION(pg_copy_to) int ret; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rs|ss", + if (zend_parse_parameters(argc, "rs|ss", &pgsql_link, &table_name, &table_name_len, &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len) == FAILURE) { return; @@ -4047,10 +4080,12 @@ PHP_FUNCTION(pg_copy_to) pg_delim = "\t"; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } if (!pg_null_as) { - pg_null_as = safe_estrdup("\\\\N"); + pg_null_as = estrdup("\\\\N"); free_pg_null = 1; } @@ -4090,7 +4125,7 @@ PHP_FUNCTION(pg_copy_to) RETURN_FALSE; break; default: - add_next_index_string(return_value, csv, 1); + add_next_index_string(return_value, csv); PQfreemem(csv); break; } @@ -4117,13 +4152,13 @@ PHP_FUNCTION(pg_copy_to) csv = (char *)erealloc(csv, strlen(csv) + sizeof(char)*(COPYBUFSIZ+1)); strcat(csv, copybuf); } - + switch (ret) { case EOF: copydone = 1; case 0: - add_next_index_string(return_value, csv, 1); + add_next_index_string(return_value, csv); efree(csv); csv = (char *)NULL; break; @@ -4159,19 +4194,17 @@ PHP_FUNCTION(pg_copy_to) PHP_FUNCTION(pg_copy_from) { zval *pgsql_link = NULL, *pg_rows; - zval **tmp; + zval *value; char *table_name, *pg_delim = NULL, *pg_null_as = NULL; - int table_name_len, pg_delim_len, pg_null_as_len; + size_t table_name_len, pg_delim_len, pg_null_as_len; int pg_null_as_free = 0; char *query; - HashPosition pos; - int id = -1; PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|ss", + if (zend_parse_parameters(argc, "rsa|ss", &pgsql_link, &table_name, &table_name_len, &pg_rows, &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len) == FAILURE) { return; @@ -4180,11 +4213,13 @@ PHP_FUNCTION(pg_copy_from) pg_delim = "\t"; } if (!pg_null_as) { - pg_null_as = safe_estrdup("\\\\N"); + pg_null_as = estrdup("\\\\N"); pg_null_as_free = 1; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, *pg_delim, pg_null_as); while ((pgsql_result = PQgetResult(pgsql))) { @@ -4208,59 +4243,50 @@ PHP_FUNCTION(pg_copy_from) if (pgsql_result) { int command_failed = 0; PQclear(pgsql_result); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pg_rows), &pos); #if HAVE_PQPUTCOPYDATA - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) { - zval *value; - ALLOC_ZVAL(value); - INIT_PZVAL_COPY(value, *tmp); - zval_copy_ctor(value); - convert_to_string_ex(&value); - query = (char *)emalloc(Z_STRLEN_P(value) + 2); - strlcpy(query, Z_STRVAL_P(value), Z_STRLEN_P(value) + 2); - if(Z_STRLEN_P(value) > 0 && *(query + Z_STRLEN_P(value) - 1) != '\n') { - strlcat(query, "\n", Z_STRLEN_P(value) + 2); + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), value) { + zval tmp; + ZVAL_DUP(&tmp, value); + convert_to_string_ex(&tmp); + query = (char *)emalloc(Z_STRLEN(tmp) + 2); + strlcpy(query, Z_STRVAL(tmp), Z_STRLEN(tmp) + 2); + if(Z_STRLEN(tmp) > 0 && *(query + Z_STRLEN(tmp) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN(tmp) + 2); } - if (PQputCopyData(pgsql, query, strlen(query)) != 1) { + if (PQputCopyData(pgsql, query, (int)strlen(query)) != 1) { efree(query); - zval_dtor(value); - efree(value); + zval_dtor(&tmp); PHP_PQ_ERROR("copy failed: %s", pgsql); RETURN_FALSE; } efree(query); - zval_dtor(value); - efree(value); - zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos); - } + zval_dtor(&tmp); + } ZEND_HASH_FOREACH_END(); + if (PQputCopyEnd(pgsql, NULL) != 1) { PHP_PQ_ERROR("putcopyend failed: %s", pgsql); RETURN_FALSE; } #else - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) { - zval *value; - ALLOC_ZVAL(value); - INIT_PZVAL_COPY(value, *tmp); - zval_copy_ctor(value); - convert_to_string_ex(&value); - query = (char *)emalloc(Z_STRLEN_P(value) + 2); - strlcpy(query, Z_STRVAL_P(value), Z_STRLEN_P(value) + 2); - if(Z_STRLEN_P(value) > 0 && *(query + Z_STRLEN_P(value) - 1) != '\n') { - strlcat(query, "\n", Z_STRLEN_P(value) + 2); + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), value) { + zval tmp; + ZVAL_DUP(&tmp, value); + convert_to_string_ex(&tmp); + query = (char *)emalloc(Z_STRLEN(tmp) + 2); + strlcpy(query, Z_STRVAL(tmp), Z_STRLEN(tmp) + 2); + if(Z_STRLEN(tmp) > 0 && *(query + Z_STRLEN(tmp) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN(tmp) + 2); } if (PQputline(pgsql, query)==EOF) { efree(query); - zval_dtor(value); - efree(value); + zval_dtor(&tmp); PHP_PQ_ERROR("copy failed: %s", pgsql); RETURN_FALSE; } efree(query); - zval_dtor(value); - efree(value); - zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos); - } + zval_dtor(&tmp); + } ZEND_HASH_FOREACH_END(); + if (PQputline(pgsql, "\\.\n") == EOF) { PHP_PQ_ERROR("putline failed: %s", pgsql); RETURN_FALSE; @@ -4300,41 +4326,43 @@ PHP_FUNCTION(pg_copy_from) Escape string for text/char type */ PHP_FUNCTION(pg_escape_string) { - char *from = NULL, *to = NULL; + zend_string *from = NULL, *to = NULL; zval *pgsql_link; + zend_resource *link; #ifdef HAVE_PQESCAPE_CONN PGconn *pgsql; #endif - int to_len; - int from_len; - int id = -1; switch (ZEND_NUM_ARGS()) { case 1: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &from) == FAILURE) { return; } - pgsql_link = NULL; - id = PGG(default_link); + link = FETCH_DEFAULT_LINK(); break; - default: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &pgsql_link, &from) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); break; } - to = (char *) safe_emalloc(from_len, 2, 1); + to = zend_string_alloc(from->len * 2, 0); #ifdef HAVE_PQESCAPE_CONN - if (pgsql_link != NULL || id != -1) { - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - to_len = (int) PQescapeStringConn(pgsql, to, from, (size_t)from_len, NULL); + if (link) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } + to->len = PQescapeStringConn(pgsql, to->val, from->val, from->len, NULL); } else #endif - to_len = (int) PQescapeString(to, from, (size_t)from_len); + { + to->len = PQescapeString(to->val, from->val, from->len); + } - RETURN_STRINGL(to, to_len, 0); + to = zend_string_truncate(to, to->len, 0); + RETURN_NEW_STR(to); } /* }}} */ @@ -4344,38 +4372,39 @@ PHP_FUNCTION(pg_escape_bytea) { char *from = NULL, *to = NULL; size_t to_len; - int from_len, id = -1; + size_t from_len; #ifdef HAVE_PQESCAPE_BYTEA_CONN PGconn *pgsql; #endif zval *pgsql_link; + zend_resource *link; switch (ZEND_NUM_ARGS()) { case 1: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &from, &from_len) == FAILURE) { return; } - pgsql_link = NULL; - id = PGG(default_link); + link = FETCH_DEFAULT_LINK(); break; - default: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &from, &from_len) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); break; } #ifdef HAVE_PQESCAPE_BYTEA_CONN - if (pgsql_link != NULL || id != -1) { - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if (link) { + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } to = (char *)PQescapeByteaConn(pgsql, (unsigned char *)from, (size_t)from_len, &to_len); - } else + } else #endif to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len); - RETVAL_STRINGL(to, to_len-1, 1); /* to_len includes additional '\0' */ - PQfreemem(to); + RETVAL_STRINGL(to, to_len-1); /* to_len includes additional '\0' */ } /* }}} */ @@ -4403,7 +4432,7 @@ PHP_FUNCTION(pg_escape_bytea) * 5 \' * 6 \\ */ -static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen) +static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen) /* {{{ */ { size_t buflen; unsigned char *buffer, @@ -4460,7 +4489,7 @@ static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t * if (isdigit(*sp)) /* state=4 */ { unsigned char *start, *end, buf[4]; /* 000 + '\0' */ - + bp -= 3; memcpy(buf, sp-2, 3); buf[3] = '\0'; @@ -4483,6 +4512,7 @@ static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t * *retbuflen = buflen; return buffer; } +/* }}} */ #endif /* {{{ proto string pg_unescape_bytea(string data) @@ -4491,8 +4521,8 @@ PHP_FUNCTION(pg_unescape_bytea) { char *from = NULL, *to = NULL, *tmp = NULL; size_t to_len; - int from_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", + size_t from_len; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &from, &from_len) == FAILURE) { return; } @@ -4505,47 +4535,47 @@ PHP_FUNCTION(pg_unescape_bytea) to = (char *)php_pgsql_unescape_bytea((unsigned char*)from, &to_len); #endif if (!to) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Invalid parameter"); + php_error_docref(NULL, E_WARNING,"Invalid parameter"); RETURN_FALSE; } - RETVAL_STRINGL(to, to_len, 0); + RETVAL_STRINGL(to, to_len); + efree(to); } /* }}} */ #endif #ifdef HAVE_PQESCAPE -static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_literal) { - char *from = NULL, *to = NULL; +static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_literal) /* {{{ */ { + char *from = NULL; zval *pgsql_link = NULL; PGconn *pgsql; - int from_len; - int id = -1; + size_t from_len; char *tmp; + zend_resource *link; switch (ZEND_NUM_ARGS()) { case 1: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &from, &from_len) == FAILURE) { return; } - pgsql_link = NULL; - id = PGG(default_link); + link = FETCH_DEFAULT_LINK(); + CHECK_DEFAULT_LINK(link); break; default: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &from, &from_len) == FAILURE) { return; } + link = Z_RES_P(pgsql_link); break; } - if (pgsql_link == NULL && id == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get default pgsql link"); + if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); if (pgsql == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get pgsql link"); + php_error_docref(NULL, E_WARNING,"Cannot get pgsql link"); RETURN_FALSE; } @@ -4555,14 +4585,14 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l tmp = PGSQLescapeIdentifier(pgsql, from, (size_t)from_len); } if (!tmp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Failed to escape"); + php_error_docref(NULL, E_WARNING,"Failed to escape"); RETURN_FALSE; } - to = estrdup(tmp); - PGSQLfree(tmp); - RETURN_STRING(to, 0); + RETVAL_STRING(tmp); + PGSQLfree(tmp); } +/* }}} */ /* {{{ proto string pg_escape_literal([resource connection,] string data) Escape parameter as string literal (i.e. parameter) */ @@ -4581,7 +4611,6 @@ PHP_FUNCTION(pg_escape_identifier) /* }}} */ #endif - /* {{{ proto string pg_result_error(resource result) Get error message associated with result */ PHP_FUNCTION(pg_result_error) @@ -4591,40 +4620,43 @@ PHP_FUNCTION(pg_result_error) pgsql_result_handle *pg_result; char *err = NULL; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &result) == FAILURE) { RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; if (!pgsql_result) { RETURN_FALSE; } err = (char *)PQresultErrorMessage(pgsql_result); - RETURN_STRING(err,1); + RETURN_STRING(err); } /* }}} */ - #if HAVE_PQRESULTERRORFIELD /* {{{ proto string pg_result_error_field(resource result, int fieldcode) Get error message field associated with result */ PHP_FUNCTION(pg_result_error_field) { zval *result; - long fieldcode; + zend_long fieldcode; PGresult *pgsql_result; pgsql_result_handle *pg_result; char *field = NULL; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "rl", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "rl", &result, &fieldcode) == FAILURE) { RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; if (!pgsql_result) { @@ -4640,11 +4672,11 @@ PHP_FUNCTION(pg_result_error_field) #endif |PG_DIAG_CONTEXT|PG_DIAG_SOURCE_FILE|PG_DIAG_SOURCE_LINE |PG_DIAG_SOURCE_FUNCTION)) { - field = (char *)PQresultErrorField(pgsql_result, fieldcode); + field = (char *)PQresultErrorField(pgsql_result, (int)fieldcode); if (field == NULL) { RETURN_NULL(); } else { - RETURN_STRING(field, 1); + RETURN_STRING(field); } } else { RETURN_FALSE; @@ -4653,43 +4685,43 @@ PHP_FUNCTION(pg_result_error_field) /* }}} */ #endif - /* {{{ proto int pg_connection_status(resource connection) Get connection status */ PHP_FUNCTION(pg_connection_status) { zval *pgsql_link = NULL; - int id = -1; PGconn *pgsql; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } RETURN_LONG(PQstatus(pgsql)); } /* }}} */ - #if HAVE_PGTRANSACTIONSTATUS /* {{{ proto int pg_transaction_status(resource connection) Get transaction status */ PHP_FUNCTION(pg_transaction_status) { zval *pgsql_link = NULL; - int id = -1; PGconn *pgsql; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } RETURN_LONG(PQtransactionStatus(pgsql)); } @@ -4697,22 +4729,22 @@ PHP_FUNCTION(pg_transaction_status) /* }}} */ - /* {{{ proto bool pg_connection_reset(resource connection) Reset connection (reconnect) */ PHP_FUNCTION(pg_connection_reset) { zval *pgsql_link; - int id = -1; PGconn *pgsql; - - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } + PQreset(pgsql); if (PQstatus(pgsql) == CONNECTION_BAD) { RETURN_FALSE; @@ -4721,20 +4753,18 @@ PHP_FUNCTION(pg_connection_reset) } /* }}} */ - #define PHP_PG_ASYNC_IS_BUSY 1 #define PHP_PG_ASYNC_REQUEST_CANCEL 2 - /* {{{ php_pgsql_flush_query */ -static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC) +static int php_pgsql_flush_query(PGconn *pgsql) { PGresult *res; int leftover = 0; - + if (PQ_SETNONBLOCKING(pgsql, 1)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to nonblocking mode"); + php_error_docref(NULL, E_NOTICE,"Cannot set connection to nonblocking mode"); return -1; } while ((res = PQgetResult(pgsql))) { @@ -4746,48 +4776,46 @@ static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC) } /* }}} */ - /* {{{ php_pgsql_do_async */ -static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) +static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { zval *pgsql_link; - int id = -1; PGconn *pgsql; PGresult *pgsql_result; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } if (PQ_SETNONBLOCKING(pgsql, 1)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to nonblocking mode"); RETURN_FALSE; } switch(entry_type) { case PHP_PG_ASYNC_IS_BUSY: PQconsumeInput(pgsql); - Z_LVAL_P(return_value) = PQisBusy(pgsql); - Z_TYPE_P(return_value) = IS_LONG; + RETVAL_LONG(PQisBusy(pgsql)); break; case PHP_PG_ASYNC_REQUEST_CANCEL: - Z_LVAL_P(return_value) = PQrequestCancel(pgsql); - Z_TYPE_P(return_value) = IS_LONG; + RETVAL_LONG(PQrequestCancel(pgsql)); while ((pgsql_result = PQgetResult(pgsql))) { PQclear(pgsql_result); } break; default: - php_error_docref(NULL TSRMLS_CC, E_ERROR, "PostgreSQL module error, please report this error"); + php_error_docref(NULL, E_ERROR, "PostgreSQL module error, please report this error"); break; } if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to blocking mode"); } - convert_to_boolean_ex(&return_value); + convert_to_boolean_ex(return_value); } /* }}} */ @@ -4807,7 +4835,7 @@ PHP_FUNCTION(pg_connection_busy) } /* }}} */ -static int _php_pgsql_link_has_results(PGconn *pgsql) +static int _php_pgsql_link_has_results(PGconn *pgsql) /* {{{ */ { PGresult *result; while ((result = PQgetResult(pgsql))) { @@ -4816,6 +4844,7 @@ static int _php_pgsql_link_has_results(PGconn *pgsql) } return 0; } +/* }}} */ /* {{{ proto bool pg_send_query(resource connection, string query) Send asynchronous query */ @@ -4823,27 +4852,28 @@ PHP_FUNCTION(pg_send_query) { zval *pgsql_link; char *query; - int len; - int id = -1; + size_t len; PGconn *pgsql; int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &query, &len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pgsql_link, &query, &len) == FAILURE) { return; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } is_non_blocking = PQisnonblocking(pgsql); if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to nonblocking mode"); RETURN_FALSE; } if (_php_pgsql_link_has_results(pgsql)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, + php_error_docref(NULL, E_NOTICE, "There are results on this connection. Call pg_get_result() until it returns FALSE"); } @@ -4865,14 +4895,14 @@ PHP_FUNCTION(pg_send_query) /* Wait to finish sending buffer */ while ((ret = PQflush(pgsql))) { if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + php_error_docref(NULL, E_NOTICE, "Could not empty PostgreSQL send buffer"); break; } usleep(10000); } if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to blocking mode"); } } @@ -4891,68 +4921,60 @@ PHP_FUNCTION(pg_send_query) Send asynchronous parameterized query */ PHP_FUNCTION(pg_send_query_params) { - zval *pgsql_link, *pv_param_arr, **tmp; + zval *pgsql_link, *pv_param_arr, *tmp; int num_params = 0; char **params = NULL; char *query; - int query_len, id = -1; + size_t query_len; PGconn *pgsql; int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa/", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa/", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { return; } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - is_non_blocking = PQisnonblocking(pgsql); if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to nonblocking mode"); RETURN_FALSE; } if (_php_pgsql_link_has_results(pgsql)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, + php_error_docref(NULL, E_NOTICE, "There are results on this connection. Call pg_get_result() until it returns FALSE"); } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr)); num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - - for(i = 0; i < num_params; i++) { - if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); - _php_pgsql_free_params(params, num_params); - RETURN_FALSE; - } - if (Z_TYPE_PP(tmp) == IS_NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { + + if (Z_TYPE_P(tmp) == IS_NULL) { params[i] = NULL; } else { - zval tmp_val = **tmp; - zval_copy_ctor(&tmp_val); + zval tmp_val; + ZVAL_COPY(&tmp_val, tmp); convert_to_string(&tmp_val); if (Z_TYPE(tmp_val) != IS_STRING) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter"); - zval_dtor(&tmp_val); + php_error_docref(NULL, E_WARNING,"Error converting parameter"); + zval_ptr_dtor(&tmp_val); _php_pgsql_free_params(params, num_params); RETURN_FALSE; } params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); - zval_dtor(&tmp_val); + zval_ptr_dtor(&tmp_val); } - zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr)); - } + i++; + } ZEND_HASH_FOREACH_END(); } if (PQsendQueryParams(pgsql, query, num_params, NULL, (const char * const *)params, NULL, NULL, 0)) { @@ -4976,14 +4998,14 @@ PHP_FUNCTION(pg_send_query_params) /* Wait to finish sending buffer */ while ((ret = PQflush(pgsql))) { if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + php_error_docref(NULL, E_NOTICE, "Could not empty PostgreSQL send buffer"); break; } usleep(10000); } if (PQ_SETNONBLOCKING(pgsql, 0) != 0) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to blocking mode"); } } @@ -5005,30 +5027,28 @@ PHP_FUNCTION(pg_send_prepare) { zval *pgsql_link; char *query, *stmtname; - int stmtname_len, query_len, id = -1; + size_t stmtname_len, query_len; PGconn *pgsql; int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { return; } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - is_non_blocking = PQisnonblocking(pgsql); if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to nonblocking mode"); RETURN_FALSE; } if (_php_pgsql_link_has_results(pgsql)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, + php_error_docref(NULL, E_NOTICE, "There are results on this connection. Call pg_get_result() until it returns FALSE"); } @@ -5051,13 +5071,13 @@ PHP_FUNCTION(pg_send_prepare) /* Wait to finish sending buffer */ while ((ret = PQflush(pgsql))) { if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + php_error_docref(NULL, E_NOTICE, "Could not empty PostgreSQL send buffer"); break; } usleep(10000); } if (PQ_SETNONBLOCKING(pgsql, 0) != 0) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to blocking mode"); } } @@ -5078,68 +5098,60 @@ PHP_FUNCTION(pg_send_prepare) PHP_FUNCTION(pg_send_execute) { zval *pgsql_link; - zval *pv_param_arr, **tmp; + zval *pv_param_arr, *tmp; int num_params = 0; char **params = NULL; char *stmtname; - int stmtname_len, id = -1; + size_t stmtname_len; PGconn *pgsql; int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { return; } - if (pgsql_link == NULL && id == -1) { + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - is_non_blocking = PQisnonblocking(pgsql); if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to nonblocking mode"); RETURN_FALSE; } if (_php_pgsql_link_has_results(pgsql)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, + php_error_docref(NULL, E_NOTICE, "There are results on this connection. Call pg_get_result() until it returns FALSE"); } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr)); num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - for (i = 0; i < num_params; i++) { - if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); - _php_pgsql_free_params(params, num_params); - RETURN_FALSE; - } + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { - if (Z_TYPE_PP(tmp) == IS_NULL) { + if (Z_TYPE_P(tmp) == IS_NULL) { params[i] = NULL; } else { - zval tmp_val = **tmp; - zval_copy_ctor(&tmp_val); + zval tmp_val; + ZVAL_COPY(&tmp_val, tmp); convert_to_string(&tmp_val); if (Z_TYPE(tmp_val) != IS_STRING) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter"); - zval_dtor(&tmp_val); + php_error_docref(NULL, E_WARNING,"Error converting parameter"); + zval_ptr_dtor(&tmp_val); _php_pgsql_free_params(params, num_params); RETURN_FALSE; } params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); - zval_dtor(&tmp_val); + zval_ptr_dtor(&tmp_val); } - zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr)); - } + i++; + } ZEND_HASH_FOREACH_END(); } if (PQsendQueryPrepared(pgsql, stmtname, num_params, (const char * const *)params, NULL, NULL, 0)) { @@ -5163,13 +5175,13 @@ PHP_FUNCTION(pg_send_execute) /* Wait to finish sending buffer */ while ((ret = PQflush(pgsql))) { if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + php_error_docref(NULL, E_NOTICE, "Could not empty PostgreSQL send buffer"); break; } usleep(10000); } if (PQ_SETNONBLOCKING(pgsql, 0) != 0) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to blocking mode"); } } @@ -5189,17 +5201,18 @@ PHP_FUNCTION(pg_send_execute) PHP_FUNCTION(pg_get_result) { zval *pgsql_link; - int id = -1; PGconn *pgsql; PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + RETURN_FALSE; + } + + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - pgsql_result = PQgetResult(pgsql); if (!pgsql_result) { /* no result */ @@ -5209,7 +5222,7 @@ PHP_FUNCTION(pg_get_result) pg_result->conn = pgsql; pg_result->result = pgsql_result; pg_result->row = 0; - ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result); + RETURN_RES(zend_register_resource(pg_result, le_result)); } /* }}} */ @@ -5218,17 +5231,19 @@ PHP_FUNCTION(pg_get_result) PHP_FUNCTION(pg_result_status) { zval *result; - long result_type = PGSQL_STATUS_LONG; + zend_long result_type = PGSQL_STATUS_LONG; ExecStatusType status; PGresult *pgsql_result; pgsql_result_handle *pg_result; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r|l", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r|l", &result, &result_type) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); + if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { + RETURN_FALSE; + } pgsql_result = pg_result->result; if (result_type == PGSQL_STATUS_LONG) { @@ -5236,35 +5251,35 @@ PHP_FUNCTION(pg_result_status) RETURN_LONG((int)status); } else if (result_type == PGSQL_STATUS_STRING) { - RETURN_STRING(PQcmdStatus(pgsql_result), 1); + RETURN_STRING(PQcmdStatus(pgsql_result)); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Optional 2nd parameter should be PGSQL_STATUS_LONG or PGSQL_STATUS_STRING"); + php_error_docref(NULL, E_WARNING, "Optional 2nd parameter should be PGSQL_STATUS_LONG or PGSQL_STATUS_STRING"); RETURN_FALSE; } } /* }}} */ - /* {{{ proto array pg_get_notify([resource connection[, result_type]]) Get asynchronous notification */ PHP_FUNCTION(pg_get_notify) { zval *pgsql_link; - int id = -1; - long result_type = PGSQL_ASSOC; + zend_long result_type = PGSQL_ASSOC; PGconn *pgsql; PGnotify *pgsql_notify; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r|l", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r|l", &pgsql_link, &result_type) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } if (!(result_type & PGSQL_BOTH)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type"); + php_error_docref(NULL, E_WARNING, "Invalid result type"); RETURN_FALSE; } @@ -5276,28 +5291,28 @@ PHP_FUNCTION(pg_get_notify) } array_init(return_value); if (result_type & PGSQL_NUM) { - add_index_string(return_value, 0, pgsql_notify->relname, 1); + add_index_string(return_value, 0, pgsql_notify->relname); add_index_long(return_value, 1, pgsql_notify->be_pid); -#if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS +#if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 9.0) { -#else +#else if (atof(PG_VERSION) >= 9.0) { -#endif +#endif #if HAVE_PQPARAMETERSTATUS - add_index_string(return_value, 2, pgsql_notify->extra, 1); + add_index_string(return_value, 2, pgsql_notify->extra); #endif } } if (result_type & PGSQL_ASSOC) { - add_assoc_string(return_value, "message", pgsql_notify->relname, 1); + add_assoc_string(return_value, "message", pgsql_notify->relname); add_assoc_long(return_value, "pid", pgsql_notify->be_pid); -#if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS +#if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 9.0) { -#else +#else if (atof(PG_VERSION) >= 9.0) { -#endif +#endif #if HAVE_PQPARAMETERSTATUS - add_assoc_string(return_value, "payload", pgsql_notify->extra, 1); + add_assoc_string(return_value, "payload", pgsql_notify->extra); #endif } } @@ -5310,41 +5325,46 @@ PHP_FUNCTION(pg_get_notify) PHP_FUNCTION(pg_get_pid) { zval *pgsql_link; - int id = -1; PGconn *pgsql; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } RETURN_LONG(PQbackendPID(pgsql)); } /* }}} */ -static size_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count) /* {{{ */ { return 0; } +/* }}} */ -static size_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count) /* {{{ */ { return 0; } +/* }}} */ -static int php_pgsql_fd_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_pgsql_fd_close(php_stream *stream, int close_handle) /* {{{ */ { return EOF; } +/* }}} */ -static int php_pgsql_fd_flush(php_stream *stream TSRMLS_DC) +static int php_pgsql_fd_flush(php_stream *stream) /* {{{ */ { return FAILURE; } +/* }}} */ -static int php_pgsql_fd_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +static int php_pgsql_fd_set_option(php_stream *stream, int option, int value, void *ptrparam) /* {{{ */ { PGconn *pgsql = (PGconn *) stream->abstract; switch (option) { @@ -5354,8 +5374,9 @@ static int php_pgsql_fd_set_option(php_stream *stream, int option, int value, vo return FAILURE; } } +/* }}} */ -static int php_pgsql_fd_cast(php_stream *stream, int cast_as, void **ret TSRMLS_DC) +static int php_pgsql_fd_cast(php_stream *stream, int cast_as, void **ret) /* {{{ */ { PGconn *pgsql = (PGconn *) stream->abstract; int fd_number; @@ -5377,6 +5398,7 @@ static int php_pgsql_fd_cast(php_stream *stream, int cast_as, void **ret TSRMLS_ return FAILURE; } } +/* }}} */ /* {{{ proto resource pg_socket(resource) Get a read-only handle to the socket underlying the pgsql connection */ @@ -5385,13 +5407,14 @@ PHP_FUNCTION(pg_socket) zval *pgsql_link; php_stream *stream; PGconn *pgsql; - int id = -1; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { return; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } stream = php_stream_alloc(&php_stream_pgsql_fd_ops, pgsql, NULL, "r"); @@ -5409,14 +5432,15 @@ PHP_FUNCTION(pg_socket) PHP_FUNCTION(pg_consume_input) { zval *pgsql_link; - int id = -1; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { return; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } RETURN_BOOL(PQconsumeInput(pgsql)); } @@ -5427,28 +5451,29 @@ PHP_FUNCTION(pg_consume_input) PHP_FUNCTION(pg_flush) { zval *pgsql_link; - int id = -1; PGconn *pgsql; int ret; int is_non_blocking; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { return; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } is_non_blocking = PQisnonblocking(pgsql); if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); + php_error_docref(NULL, E_NOTICE, "Cannot set connection to nonblocking mode"); RETURN_FALSE; } ret = PQflush(pgsql); if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 0) == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed resetting connection to blocking mode"); + php_error_docref(NULL, E_NOTICE, "Failed resetting connection to blocking mode"); } switch (ret) { @@ -5462,7 +5487,7 @@ PHP_FUNCTION(pg_flush) /* {{{ php_pgsql_meta_data * TODO: Add meta_data cache for better performance */ -PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended TSRMLS_DC) +PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended) { PGresult *pg_result; char *src, *tmp_name, *tmp_name2 = NULL; @@ -5470,10 +5495,10 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z smart_str querystr = {0}; size_t new_len; int i, num_rows; - zval *elem; + zval elem; if (!*table_name) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The table name must be specified"); + php_error_docref(NULL, E_WARNING, "The table name must be specified"); return FAILURE; } @@ -5528,9 +5553,9 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z smart_str_0(&querystr); efree(src); - pg_result = PQexec(pg_link, querystr.c); + pg_result = PQexec(pg_link, querystr.s->val); if (PQresultStatus(pg_result) != PGRES_TUPLES_OK || (num_rows = PQntuples(pg_result)) == 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Table '%s' doesn't exists", table_name); + php_error_docref(NULL, E_WARNING, "Table '%s' doesn't exists", table_name); smart_str_free(&querystr); PQclear(pg_result); return FAILURE; @@ -5539,69 +5564,67 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z for (i = 0; i < num_rows; i++) { char *name; - MAKE_STD_ZVAL(elem); - array_init(elem); + array_init(&elem); /* pg_attribute.attnum */ - add_assoc_long(elem, "num", atoi(PQgetvalue(pg_result,i,1))); + add_assoc_long_ex(&elem, "num", sizeof("num") - 1, atoi(PQgetvalue(pg_result, i, 1))); /* pg_type.typname */ - add_assoc_string(elem, "type", PQgetvalue(pg_result,i,2), 1); + add_assoc_string_ex(&elem, "type", sizeof("type") - 1, PQgetvalue(pg_result, i, 2)); /* pg_attribute.attlen */ - add_assoc_long(elem, "len", atoi(PQgetvalue(pg_result,i,3))); + add_assoc_long_ex(&elem, "len", sizeof("len") - 1, atoi(PQgetvalue(pg_result,i,3))); /* pg_attribute.attnonull */ - add_assoc_bool(elem, "not null", !strcmp(PQgetvalue(pg_result,i,4), "t")); + add_assoc_bool_ex(&elem, "not null", sizeof("not null") - 1, !strcmp(PQgetvalue(pg_result, i, 4), "t")); /* pg_attribute.atthasdef */ - add_assoc_bool(elem, "has default", !strcmp(PQgetvalue(pg_result,i,5), "t")); + add_assoc_bool_ex(&elem, "has default", sizeof("has default") - 1, !strcmp(PQgetvalue(pg_result,i,5), "t")); /* pg_attribute.attndims */ - add_assoc_long(elem, "array dims", atoi(PQgetvalue(pg_result,i,6))); + add_assoc_long_ex(&elem, "array dims", sizeof("array dims") - 1, atoi(PQgetvalue(pg_result, i, 6))); /* pg_type.typtype */ - add_assoc_bool(elem, "is enum", !strcmp(PQgetvalue(pg_result,i,7), "e")); + add_assoc_bool_ex(&elem, "is enum", sizeof("is enum") - 1, !strcmp(PQgetvalue(pg_result, i, 7), "e")); if (extended) { /* pg_type.typtype */ - add_assoc_bool(elem, "is base", !strcmp(PQgetvalue(pg_result,i,7), "b")); - add_assoc_bool(elem, "is composite", !strcmp(PQgetvalue(pg_result,i,7), "c")); - add_assoc_bool(elem, "is pesudo", !strcmp(PQgetvalue(pg_result,i,7), "p")); + add_assoc_bool_ex(&elem, "is base", sizeof("is base") - 1, !strcmp(PQgetvalue(pg_result, i, 7), "b")); + add_assoc_bool_ex(&elem, "is composite", sizeof("is composite") - 1, !strcmp(PQgetvalue(pg_result, i, 7), "c")); + add_assoc_bool_ex(&elem, "is pesudo", sizeof("is pesudo") - 1, !strcmp(PQgetvalue(pg_result, i, 7), "p")); /* pg_description.description */ - add_assoc_string(elem, "description", PQgetvalue(pg_result,i,8), 1); + add_assoc_string_ex(&elem, "description", sizeof("description") - 1, PQgetvalue(pg_result, i, 8)); } /* pg_attribute.attname */ name = PQgetvalue(pg_result,i,0); - add_assoc_zval(meta, name, elem); + add_assoc_zval(meta, name, &elem); } PQclear(pg_result); - + return SUCCESS; } /* }}} */ - /* {{{ proto array pg_meta_data(resource db, string table [, bool extended]) Get meta_data */ PHP_FUNCTION(pg_meta_data) { zval *pgsql_link; char *table_name; - uint table_name_len; + size_t table_name_len; zend_bool extended=0; PGconn *pgsql; - int id = -1; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|b", &pgsql_link, &table_name, &table_name_len, &extended) == FAILURE) { return; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } array_init(return_value); - if (php_pgsql_meta_data(pgsql, table_name, return_value, extended TSRMLS_CC) == FAILURE) { + if (php_pgsql_meta_data(pgsql, table_name, return_value, extended) == FAILURE) { zval_dtor(return_value); /* destroy array */ RETURN_FALSE; } } /* }}} */ - /* {{{ php_pgsql_get_data_type */ static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t len) @@ -5695,13 +5718,13 @@ static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t /* {{{ php_pgsql_convert_match * test field value with regular expression specified. */ -static int php_pgsql_convert_match(const char *str, size_t str_len, const char *regex , int icase TSRMLS_DC) +static int php_pgsql_convert_match(const char *str, size_t str_len, const char *regex , int icase) { - regex_t re; - regmatch_t *subs; - int regopt = REG_EXTENDED; - int regerr, ret = SUCCESS; - int i; + pcre *re; + const char *err_msg; + int err_offset; + int options = PCRE_NO_AUTO_CAPTURE, res; + size_t i; /* Check invalid chars for POSIX regex */ for (i = 0; i < str_len; i++) { @@ -5713,28 +5736,24 @@ static int php_pgsql_convert_match(const char *str, size_t str_len, const char * } if (icase) { - regopt |= REG_ICASE; + options |= PCRE_CASELESS; } - regerr = regcomp(&re, regex, regopt); - if (regerr) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot compile regex"); - regfree(&re); + if ((re = pcre_compile(regex, options, &err_msg, &err_offset, NULL)) == NULL) { + php_error_docref(NULL, E_WARNING, "Cannot compile regex"); return FAILURE; } - subs = (regmatch_t *)ecalloc(sizeof(regmatch_t), re.re_nsub+1); - regerr = regexec(&re, str, re.re_nsub+1, subs, 0); - if (regerr == REG_NOMATCH) { - ret = FAILURE; - } - else if (regerr) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot exec regex"); - ret = FAILURE; + res = pcre_exec(re, NULL, str, str_len, 0, 0, NULL, 0); + pcre_free(re); + + if (res == PCRE_ERROR_NOMATCH) { + return FAILURE; + } else if (res) { + php_error_docref(NULL, E_WARNING, "Cannot exec regex"); + return FAILURE; } - regfree(&re); - efree(subs); - return ret; + return SUCCESS; } /* }}} */ @@ -5742,7 +5761,7 @@ static int php_pgsql_convert_match(const char *str, size_t str_len, const char * /* {{{ php_pgsql_add_quote * add quotes around string. */ -static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) +static int php_pgsql_add_quotes(zval *src, zend_bool should_free) { smart_str str = {0}; @@ -5756,41 +5775,37 @@ static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) smart_str_0(&str); if (should_free) { - efree(Z_STRVAL_P(src)); + zval_ptr_dtor(src); } - Z_STRVAL_P(src) = str.c; - Z_STRLEN_P(src) = str.len; + ZVAL_NEW_STR(src, str.s); return SUCCESS; } /* }}} */ #define PGSQL_CONV_CHECK_IGNORE() \ - if (!err && Z_TYPE_P(new_val) == IS_STRING && !strcmp(Z_STRVAL_P(new_val), "NULL")) { \ - /* if new_value is string "NULL" and field has default value, remove element to use default value */ \ - if (!(opt & PGSQL_CONV_IGNORE_DEFAULT) && Z_BVAL_PP(has_default)) { \ - zval_dtor(new_val); \ - FREE_ZVAL(new_val); \ - skip_field = 1; \ - } \ - /* raise error if it's not null and cannot be ignored */ \ - else if (!(opt & PGSQL_CONV_IGNORE_NOT_NULL) && Z_BVAL_PP(not_null)) { \ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected NULL for 'NOT NULL' field '%s'", field ); \ - err = 1; \ - } \ - } + if (!err && Z_TYPE(new_val) == IS_STRING && !strcmp(Z_STRVAL(new_val), "NULL")) { \ + /* if new_value is string "NULL" and field has default value, remove element to use default value */ \ + if (!(opt & PGSQL_CONV_IGNORE_DEFAULT) && Z_TYPE_P(has_default) == IS_TRUE) { \ + zval_ptr_dtor(&new_val); \ + skip_field = 1; \ + } \ + /* raise error if it's not null and cannot be ignored */ \ + else if (!(opt & PGSQL_CONV_IGNORE_NOT_NULL) && Z_TYPE_P(not_null) == IS_TRUE) { \ + php_error_docref(NULL, E_NOTICE, "Detected NULL for 'NOT NULL' field '%s'", field->val); \ + err = 1; \ + } \ + } /* {{{ php_pgsql_convert * check and convert array values (fieldname=>vlaue pair) for sql */ -PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result, ulong opt TSRMLS_DC) +PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result, zend_ulong opt) { - HashPosition pos; - char *field = NULL; - uint field_len = -1; - ulong num_idx = -1; - zval *meta, **def, **type, **not_null, **has_default, **is_enum, **val, *new_val; - int key_type, err = 0, skip_field; + zend_string *field = NULL; + zend_ulong num_idx = -1; + zval meta, *def, *type, *not_null, *has_default, *is_enum, *val, new_val; + int err = 0, skip_field; php_pgsql_data_type data_type; assert(pg_link != NULL); @@ -5801,112 +5816,108 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con if (!table_name) { return FAILURE; } - MAKE_STD_ZVAL(meta); - array_init(meta); + array_init(&meta); /* table_name is escaped by php_pgsql_meta_data */ - if (php_pgsql_meta_data(pg_link, table_name, meta, 0 TSRMLS_CC) == FAILURE) { - zval_dtor(meta); - FREE_ZVAL(meta); + if (php_pgsql_meta_data(pg_link, table_name, &meta, 0) == FAILURE) { + zval_ptr_dtor(&meta); return FAILURE; } - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos); - zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&val, &pos) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos)) { + + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(values), num_idx, field, val) { skip_field = 0; - new_val = NULL; + ZVAL_NULL(&new_val); - if ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &field, &field_len, &num_idx, 0, &pos)) == HASH_KEY_NON_EXISTENT) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get array key type"); + if (!err && field == NULL) { + php_error_docref(NULL, E_WARNING, "Accepts only string key for values"); err = 1; } - if (!err && key_type == HASH_KEY_IS_LONG) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Accepts only string key for values"); - err = 1; - } - if (!err && key_type == HASH_KEY_NON_EXISTENT) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Accepts only string key for values"); - err = 1; - } - if (!err && zend_hash_find(Z_ARRVAL_P(meta), field, field_len, (void **)&def) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid field name (%s) in values", field); + + if (!err && (def = zend_hash_find(Z_ARRVAL(meta), field)) == NULL) { + php_error_docref(NULL, E_NOTICE, "Invalid field name (%s) in values", field->val); err = 1; } - if (!err && zend_hash_find(Z_ARRVAL_PP(def), "type", sizeof("type"), (void **)&type) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'type'"); + if (!err && (type = zend_hash_str_find(Z_ARRVAL_P(def), "type", sizeof("type") - 1)) == NULL) { + php_error_docref(NULL, E_NOTICE, "Detected broken meta data. Missing 'type'"); err = 1; } - if (!err && zend_hash_find(Z_ARRVAL_PP(def), "not null", sizeof("not null"), (void **)¬_null) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'not null'"); + if (!err && (not_null = zend_hash_str_find(Z_ARRVAL_P(def), "not null", sizeof("not null") - 1)) == NULL) { + php_error_docref(NULL, E_NOTICE, "Detected broken meta data. Missing 'not null'"); err = 1; } - if (!err && zend_hash_find(Z_ARRVAL_PP(def), "has default", sizeof("has default"), (void **)&has_default) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'has default'"); + if (!err && (has_default = zend_hash_str_find(Z_ARRVAL_P(def), "has default", sizeof("has default") - 1)) == NULL) { + php_error_docref(NULL, E_NOTICE, "Detected broken meta data. Missing 'has default'"); err = 1; } - if (!err && zend_hash_find(Z_ARRVAL_PP(def), "is enum", sizeof("is enum"), (void **)&is_enum) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'is enum'"); + if (!err && (is_enum = zend_hash_str_find(Z_ARRVAL_P(def), "is enum", sizeof("is enum") - 1)) == NULL) { + php_error_docref(NULL, E_NOTICE, "Detected broken meta data. Missing 'is enum'"); err = 1; } - if (!err && (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects scalar values as field values"); + if (!err && (Z_TYPE_P(val) == IS_ARRAY || Z_TYPE_P(val) == IS_OBJECT)) { + php_error_docref(NULL, E_NOTICE, "Expects scalar values as field values"); err = 1; } if (err) { break; /* break out for() */ } - ALLOC_INIT_ZVAL(new_val); - if (Z_BVAL_PP(is_enum)) { + convert_to_boolean(is_enum); + if (Z_TYPE_P(is_enum) == IS_TRUE) { /* enums need to be treated like strings */ data_type = PG_TEXT; - } - else { - data_type = php_pgsql_get_data_type(Z_STRVAL_PP(type), Z_STRLEN_PP(type)); + } else { + data_type = php_pgsql_get_data_type(Z_STRVAL_P(type), Z_STRLEN_P(type)); } switch(data_type) { case PG_BOOL: - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRING(new_val, "NULL", 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRING(&new_val, "NULL"); } else { - if (!strcmp(Z_STRVAL_PP(val), "t") || !strcmp(Z_STRVAL_PP(val), "T") || - !strcmp(Z_STRVAL_PP(val), "y") || !strcmp(Z_STRVAL_PP(val), "Y") || - !strcmp(Z_STRVAL_PP(val), "true") || !strcmp(Z_STRVAL_PP(val), "True") || - !strcmp(Z_STRVAL_PP(val), "yes") || !strcmp(Z_STRVAL_PP(val), "Yes") || - !strcmp(Z_STRVAL_PP(val), "1")) { - ZVAL_STRINGL(new_val, "'t'", sizeof("'t'")-1, 1); + if (!strcmp(Z_STRVAL_P(val), "t") || !strcmp(Z_STRVAL_P(val), "T") || + !strcmp(Z_STRVAL_P(val), "y") || !strcmp(Z_STRVAL_P(val), "Y") || + !strcmp(Z_STRVAL_P(val), "true") || !strcmp(Z_STRVAL_P(val), "True") || + !strcmp(Z_STRVAL_P(val), "yes") || !strcmp(Z_STRVAL_P(val), "Yes") || + !strcmp(Z_STRVAL_P(val), "1")) { + ZVAL_STRINGL(&new_val, "'t'", sizeof("'t'")-1); } - else if (!strcmp(Z_STRVAL_PP(val), "f") || !strcmp(Z_STRVAL_PP(val), "F") || - !strcmp(Z_STRVAL_PP(val), "n") || !strcmp(Z_STRVAL_PP(val), "N") || - !strcmp(Z_STRVAL_PP(val), "false") || !strcmp(Z_STRVAL_PP(val), "False") || - !strcmp(Z_STRVAL_PP(val), "no") || !strcmp(Z_STRVAL_PP(val), "No") || - !strcmp(Z_STRVAL_PP(val), "0")) { - ZVAL_STRINGL(new_val, "'f'", sizeof("'f'")-1, 1); + else if (!strcmp(Z_STRVAL_P(val), "f") || !strcmp(Z_STRVAL_P(val), "F") || + !strcmp(Z_STRVAL_P(val), "n") || !strcmp(Z_STRVAL_P(val), "N") || + !strcmp(Z_STRVAL_P(val), "false") || !strcmp(Z_STRVAL_P(val), "False") || + !strcmp(Z_STRVAL_P(val), "no") || !strcmp(Z_STRVAL_P(val), "No") || + !strcmp(Z_STRVAL_P(val), "0")) { + ZVAL_STRINGL(&new_val, "'f'", sizeof("'f'")-1); } else { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected invalid value (%s) for PostgreSQL %s field (%s)", Z_STRVAL_PP(val), Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Detected invalid value (%s) for PostgreSQL %s field (%s)", Z_STRVAL_P(val), Z_STRVAL_P(type), field->val); err = 1; } } break; case IS_LONG: - case IS_BOOL: - if (Z_LVAL_PP(val)) { - ZVAL_STRINGL(new_val, "'t'", sizeof("'t'")-1, 1); + if (Z_LVAL_P(val)) { + ZVAL_STRINGL(&new_val, "'t'", sizeof("'t'")-1); } else { - ZVAL_STRINGL(new_val, "'f'", sizeof("'f'")-1, 1); + ZVAL_STRINGL(&new_val, "'f'", sizeof("'f'")-1); } break; + case IS_TRUE: + ZVAL_STRINGL(&new_val, "'t'", sizeof("'t'")-1); + break; + + case IS_FALSE: + ZVAL_STRINGL(&new_val, "'f'", sizeof("'f'")-1); + break; + case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -5914,7 +5925,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), field->val); } break; @@ -5922,33 +5933,33 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con case PG_INT2: case PG_INT4: case PG_INT8: - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([+-]{0,1}[0-9]+)$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^([+-]{0,1}[0-9]+)$", 0) == FAILURE) { err = 1; } else { - ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1); + ZVAL_STRINGL(&new_val, Z_STRVAL_P(val), Z_STRLEN_P(val)); } } break; case IS_DOUBLE: - ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); + ZVAL_DOUBLE(&new_val, Z_DVAL_P(val)); convert_to_long_ex(&new_val); break; - + case IS_LONG: - ZVAL_LONG(new_val, Z_LVAL_PP(val)); + ZVAL_LONG(&new_val, Z_LVAL_P(val)); break; - + case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -5956,7 +5967,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for pgsql '%s' (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for pgsql '%s' (%s)", Z_STRVAL_P(type), field->val); } break; @@ -5964,37 +5975,37 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con case PG_MONEY: case PG_FLOAT4: case PG_FLOAT8: - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { /* better regex? */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$", 0 TSRMLS_CC) == FAILURE) { - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[+-]{0,1}(inf)(inity){0,1}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$", 0) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^[+-]{0,1}(inf)(inity){0,1}$", 1) == FAILURE) { err = 1; } else { - ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + ZVAL_STRING(&new_val, Z_STRVAL_P(val)); + php_pgsql_add_quotes(&new_val, 1); } } else { - ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); + ZVAL_STRING(&new_val, Z_STRVAL_P(val)); } } break; case IS_LONG: - ZVAL_LONG(new_val, Z_LVAL_PP(val)); + ZVAL_LONG(&new_val, Z_LVAL_P(val)); break; case IS_DOUBLE: - ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); + ZVAL_DOUBLE(&new_val, Z_DVAL_P(val)); break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6002,7 +6013,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), field->val); } break; @@ -6025,39 +6036,39 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con case PG_CIRCLE: /* unknown. JSON, Array etc */ case PG_UNKNOWN: - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { + if (Z_STRLEN_P(val) == 0) { if (opt & PGSQL_CONV_FORCE_NULL) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { - ZVAL_STRINGL(new_val, "''", sizeof("''")-1, 1); + ZVAL_STRINGL(&new_val, "''", sizeof("''")-1); } } else { - char *tmp; + zend_string *str; /* PostgreSQL ignores \0 */ - Z_TYPE_P(new_val) = IS_STRING; - tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1); + str = zend_string_alloc(Z_STRLEN_P(val) * 2, 0); /* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */ - Z_STRLEN_P(new_val) = (int)PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL); - Z_STRVAL_P(new_val) = tmp; - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + str->len = PQescapeStringConn(pg_link, str->val, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); + str = zend_string_truncate(str, str->len, 0); + ZVAL_NEW_STR(&new_val, str); + php_pgsql_add_quotes(&new_val, 1); } break; case IS_LONG: - ZVAL_LONG(new_val, Z_LVAL_PP(val)); + ZVAL_LONG(&new_val, Z_LVAL_P(val)); convert_to_string_ex(&new_val); break; case IS_DOUBLE: - ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); + ZVAL_DOUBLE(&new_val, Z_DVAL_P(val)); convert_to_string_ex(&new_val); break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6065,41 +6076,41 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), field->val); } break; case PG_UNIX_TIME: case PG_UNIX_TIME_INTERVAL: /* these are the actallay a integer */ - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { /* better regex? */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[0-9]+$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^[0-9]+$", 0) == FAILURE) { err = 1; } else { - ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1); + ZVAL_STRINGL(&new_val, Z_STRVAL_P(val), Z_STRLEN_P(val)); convert_to_long_ex(&new_val); } } break; case IS_DOUBLE: - ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); + ZVAL_DOUBLE(&new_val, Z_DVAL_P(val)); convert_to_long_ex(&new_val); break; case IS_LONG: - ZVAL_LONG(new_val, Z_LVAL_PP(val)); + ZVAL_LONG(&new_val, Z_LVAL_P(val)); break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6107,31 +6118,31 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for '%s' (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for '%s' (%s)", Z_STRVAL_P(type), field->val); } break; case PG_CIDR: case PG_INET: - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { /* better regex? IPV6 and IPV4 */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$", 0) == FAILURE) { err = 1; } else { - ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + ZVAL_STRINGL(&new_val, Z_STRVAL_P(val), Z_STRLEN_P(val)); + php_pgsql_add_quotes(&new_val, 1); } } break; - + case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6139,32 +6150,32 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for '%s' (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL or string for '%s' (%s)", Z_STRVAL_P(type), field->val); } break; case PG_TIME_WITH_TIMEZONE: case PG_TIMESTAMP: case PG_TIMESTAMP_WITH_TIMEZONE: - switch(Z_TYPE_PP(val)) { + switch(Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); - } else if (!strcasecmp(Z_STRVAL_PP(val), "now()")) { - ZVAL_STRINGL(new_val, "NOW()", sizeof("NOW()")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); + } else if (!strcasecmp(Z_STRVAL_P(val), "now()")) { + ZVAL_STRINGL(&new_val, "NOW()", sizeof("NOW()")-1); } else { /* better regex? */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$", 1) == FAILURE) { err = 1; } else { - ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + ZVAL_STRING(&new_val, Z_STRVAL_P(val)); + php_pgsql_add_quotes(&new_val, 1); } } break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6172,30 +6183,30 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), field->val); } break; case PG_DATE: - switch(Z_TYPE_PP(val)) { + switch(Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$", 1) == FAILURE) { err = 1; } else { - ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + ZVAL_STRINGL(&new_val, Z_STRVAL_P(val), Z_STRLEN_P(val)); + php_pgsql_add_quotes(&new_val, 1); } } break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6203,30 +6214,30 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), field->val); } break; case PG_TIME: - switch(Z_TYPE_PP(val)) { + switch(Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$", 1) == FAILURE) { err = 1; } else { - ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + ZVAL_STRINGL(&new_val, Z_STRVAL_P(val), Z_STRLEN_P(val)); + php_pgsql_add_quotes(&new_val, 1); } } break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6234,15 +6245,15 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), field->val); } break; case PG_INTERVAL: - switch(Z_TYPE_PP(val)) { + switch(Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRING(new_val, "NULL", 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRING(&new_val, "NULL"); } else { @@ -6250,19 +6261,19 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con interval values can be written with the following syntax: [@] quantity unit [quantity unit...] [direction] - + Where: quantity is a number (possibly signed); unit is second, minute, hour, day, week, month, year, decade, century, millennium, or abbreviations or plurals of these units [note not *all* abbreviations] ; direction can be ago or empty. The at sign (@) is optional noise. - + ... - + Quantities of days, hours, minutes, and seconds can be specified without explicit unit markings. For example, '1 12:59:10' is read the same as '1 day 12 hours 59 min 10 sec'. */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^(@?[ \\t]+)?(" /* Textual time units and their abbreviations: */ @@ -6273,7 +6284,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con "decades|decade|dec|decs|" "years|year|y|" "months|month|mon|" - "weeks|week|w|" + "weeks|week|w|" "days|day|d|" "hours|hour|hr|hrs|h|" "minutes|minute|mins|min|m|" @@ -6288,24 +6299,24 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con "years|year|y|" "months|month|mon|" "weeks|week|w|" - "days|day|d))+" + "days|day|d))+" "([-+]?[ \\t]+" "([0-9]+[ \\t]+)+" /* dd */ "(([0-9]{1,2}:){0,2}[0-9]{0,2})" /* hh:[mm:[ss]] */ ")?))" "([ \\t]+ago)?$", - 1 TSRMLS_CC) == FAILURE) { + 1) == FAILURE) { err = 1; } else { - ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + ZVAL_STRING(&new_val, Z_STRVAL_P(val)); + php_pgsql_add_quotes(&new_val, 1); } } break; case IS_NULL: - ZVAL_STRING(new_val, "NULL", 1); + ZVAL_STRING(&new_val, "NULL"); break; default: @@ -6313,51 +6324,47 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), field->val); } break; #ifdef HAVE_PQESCAPE case PG_BYTEA: - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRING(new_val, "NULL", 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRING(&new_val, "NULL"); } else { unsigned char *tmp; size_t to_len; smart_str s = {0}; #ifdef HAVE_PQESCAPE_BYTEA_CONN - tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_PP(val), Z_STRLEN_PP(val), &to_len); + tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val), &to_len); #else - tmp = PQescapeBytea(Z_STRVAL_PP(val), (unsigned char *)Z_STRLEN_PP(val), &to_len); + tmp = PQescapeBytea(Z_STRVAL_P(val), (unsigned char *)Z_STRLEN_P(val), &to_len); #endif - Z_TYPE_P(new_val) = IS_STRING; - Z_STRLEN_P(new_val) = to_len-1; /* PQescapeBytea's to_len includes additional '\0' */ - Z_STRVAL_P(new_val) = emalloc(to_len); - memcpy(Z_STRVAL_P(new_val), tmp, to_len); + ZVAL_STRINGL(&new_val, (char *)tmp, to_len - 1); /* PQescapeBytea's to_len includes additional '\0' */ PQfreemem(tmp); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); - smart_str_appendl(&s, Z_STRVAL_P(new_val), Z_STRLEN_P(new_val)); + php_pgsql_add_quotes(&new_val, 1); + smart_str_appendl(&s, Z_STRVAL(new_val), Z_STRLEN(new_val)); smart_str_0(&s); - efree(Z_STRVAL_P(new_val)); - Z_STRVAL_P(new_val) = s.c; - Z_STRLEN_P(new_val) = s.len; + zval_ptr_dtor(&new_val); + ZVAL_NEW_STR(&new_val, s.s); } break; case IS_LONG: - ZVAL_LONG(new_val, Z_LVAL_PP(val)); + ZVAL_LONG(&new_val, Z_LVAL_P(val)); convert_to_string_ex(&new_val); break; case IS_DOUBLE: - ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); + ZVAL_DOUBLE(&new_val, Z_DVAL_P(val)); convert_to_string_ex(&new_val); break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6365,30 +6372,30 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), field->val); } break; - + #endif case PG_MACADDR: - switch(Z_TYPE_PP(val)) { + switch(Z_TYPE_P(val)) { case IS_STRING: - if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + if (Z_STRLEN_P(val) == 0) { + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); } else { - if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$", 1) == FAILURE) { err = 1; } else { - ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1); - php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); + ZVAL_STRINGL(&new_val, Z_STRVAL_P(val), Z_STRLEN_P(val)); + php_pgsql_add_quotes(&new_val, 1); } } break; case IS_NULL: - ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1); break; default: @@ -6396,38 +6403,36 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } PGSQL_CONV_CHECK_IGNORE(); if (err) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), field->val); } break; default: /* should not happen */ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or system data type '%s' for '%s'. Report error", Z_STRVAL_PP(type), field); + php_error_docref(NULL, E_NOTICE, "Unknown or system data type '%s' for '%s'. Report error", Z_STRVAL_P(type), field->val); err = 1; break; } /* switch */ if (err) { - zval_dtor(new_val); - FREE_ZVAL(new_val); + zval_ptr_dtor(&new_val); break; /* break out for() */ } /* If field is NULL and HAS DEFAULT, should be skipped */ if (!skip_field) { char *escaped; - size_t field_len = strlen(field); - if (_php_pgsql_detect_identifier_escape(field, field_len) == SUCCESS) { - add_assoc_zval(result, field, new_val); + if (_php_pgsql_detect_identifier_escape(field->val, field->len) == SUCCESS) { + zend_hash_update(Z_ARRVAL_P(result), field, &new_val); } else { - escaped = PGSQLescapeIdentifier(pg_link, field, field_len); - add_assoc_zval(result, escaped, new_val); + escaped = PGSQLescapeIdentifier(pg_link, field->val, field->len); + add_assoc_zval(result, escaped, &new_val); PGSQLfree(escaped); } } - } /* for */ - zval_dtor(meta); - FREE_ZVAL(meta); + } ZEND_HASH_FOREACH_END(); /* for */ + + zval_ptr_dtor(&meta); if (err) { /* shouldn't destroy & free zval here */ @@ -6437,68 +6442,69 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } /* }}} */ - /* {{{ proto array pg_convert(resource db, string table, array values[, int options]) Check and convert values for PostgreSQL SQL statement */ PHP_FUNCTION(pg_convert) { zval *pgsql_link, *values; char *table_name; - int table_name_len; - ulong option = 0; + size_t table_name_len; + zend_ulong option = 0; PGconn *pg_link; - int id = -1; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa|l", &pgsql_link, &table_name, &table_name_len, &values, &option) == FAILURE) { return; } if (option & ~PGSQL_CONV_OPTS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified"); + php_error_docref(NULL, E_WARNING, "Invalid option is specified"); RETURN_FALSE; } if (!table_name_len) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Table name is invalid"); + php_error_docref(NULL, E_NOTICE, "Table name is invalid"); RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); + if (php_pgsql_flush_query(pg_link)) { + php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } array_init(return_value); - if (php_pgsql_convert(pg_link, table_name, values, return_value, option TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert(pg_link, table_name, values, return_value, option) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } } /* }}} */ -static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, ulong opt TSRMLS_DC) +static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, zend_ulong opt) /* {{{ */ { if (opt & PGSQL_DML_ASYNC) { - if (PQsendQuery(pg_link, querystr->c)) { + if (PQsendQuery(pg_link, querystr->s->val)) { return 0; } } else { PGresult *pg_result; - pg_result = PQexec(pg_link, querystr->c); + pg_result = PQexec(pg_link, querystr->s->val); if (PQresultStatus(pg_result) == expect) { PQclear(pg_result); return 0; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", PQresultErrorMessage(pg_result)); + php_error_docref(NULL, E_WARNING, "%s", PQresultErrorMessage(pg_result)); PQclear(pg_result); } } return -1; } +/* }}} */ -static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const char *table) +static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const char *table) /* {{{ */ { char *table_copy, *escaped, *tmp; const char *token; @@ -6533,24 +6539,25 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c } efree(table_copy); } +/* }}} */ /* {{{ php_pgsql_insert */ -PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array, ulong opt, char **sql TSRMLS_DC) +PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array, zend_ulong opt, zend_string **sql) { - zval **val, *converted = NULL; + zval *val, converted; char buf[256]; - char *fld, *tmp; + char *tmp; smart_str querystr = {0}; - int key_type, ret = FAILURE; - uint fld_len; - ulong num_idx; - HashPosition pos; + int ret = FAILURE; + zend_ulong num_idx; + zend_string *fld; assert(pg_link != NULL); assert(table != NULL); assert(Z_TYPE_P(var_array) == IS_ARRAY); + ZVAL_UNDEF(&converted); if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0) { smart_str_appends(&querystr, "INSERT INTO "); build_tablename(&querystr, pg_link, table); @@ -6561,77 +6568,70 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var /* convert input array if needed */ if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { - MAKE_STD_ZVAL(converted); - array_init(converted); - if (php_pgsql_convert(pg_link, table, var_array, converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { + array_init(&converted); + if (php_pgsql_convert(pg_link, table, var_array, &converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { goto cleanup; } - var_array = converted; + var_array = &converted; } smart_str_appends(&querystr, "INSERT INTO "); build_tablename(&querystr, pg_link, table); smart_str_appends(&querystr, " ("); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos); - while ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &fld, - &fld_len, &num_idx, 0, &pos)) != HASH_KEY_NON_EXISTENT) { - if (key_type == HASH_KEY_IS_LONG) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects associative array for values to be inserted"); + ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(var_array), num_idx, fld) { + if (fld == NULL) { + php_error_docref(NULL, E_NOTICE, "Expects associative array for values to be inserted"); goto cleanup; } if (opt & PGSQL_DML_ESCAPE) { - tmp = PGSQLescapeIdentifier(pg_link, fld, fld_len); + tmp = PGSQLescapeIdentifier(pg_link, fld->val, fld->len + 1); smart_str_appends(&querystr, tmp); PGSQLfree(tmp); } else { - smart_str_appendl(&querystr, fld, fld_len - 1); + smart_str_appendl(&querystr, fld->val, fld->len); } smart_str_appendc(&querystr, ','); - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); - } - querystr.len--; + } ZEND_HASH_FOREACH_END(); + querystr.s->len--; smart_str_appends(&querystr, ") VALUES ("); - + /* make values string */ - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos); - zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), (void **)&val, &pos) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos)) { - + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(var_array), val) { /* we can avoid the key_type check here, because we tested it in the other loop */ - switch(Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: if (opt & PGSQL_DML_ESCAPE) { size_t new_len; char *tmp; - tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1); - new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL); + tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1); + new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); smart_str_appendc(&querystr, '\''); smart_str_appendl(&querystr, tmp, new_len); smart_str_appendc(&querystr, '\''); efree(tmp); } else { - smart_str_appendl(&querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val)); + smart_str_appendl(&querystr, Z_STRVAL_P(val), Z_STRLEN_P(val)); } break; case IS_LONG: - smart_str_append_long(&querystr, Z_LVAL_PP(val)); + smart_str_append_long(&querystr, Z_LVAL_P(val)); break; case IS_DOUBLE: - smart_str_appendl(&querystr, buf, snprintf(buf, sizeof(buf), "%F", Z_DVAL_PP(val))); + smart_str_appendl(&querystr, buf, snprintf(buf, sizeof(buf), "%F", Z_DVAL_P(val))); break; case IS_NULL: smart_str_appendl(&querystr, "NULL", sizeof("NULL")-1); break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects scaler values. type = %d", Z_TYPE_PP(val)); + php_error_docref(NULL, E_WARNING, "Expects scaler values. type = %d", Z_TYPE_P(val)); goto cleanup; break; } smart_str_appendc(&querystr, ','); - } + } ZEND_HASH_FOREACH_END(); /* Remove the trailing "," */ - querystr.len--; + querystr.s->len--; smart_str_appends(&querystr, ");"); no_values: @@ -6639,20 +6639,17 @@ no_values: smart_str_0(&querystr); if ((opt & (PGSQL_DML_EXEC|PGSQL_DML_ASYNC)) && - do_exec(&querystr, PGRES_COMMAND_OK, pg_link, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == 0) { + do_exec(&querystr, PGRES_COMMAND_OK, pg_link, (opt & PGSQL_CONV_OPTS)) == 0) { ret = SUCCESS; } else if (opt & PGSQL_DML_STRING) { ret = SUCCESS; } - + cleanup: - if (!(opt & PGSQL_DML_NO_CONV) && converted) { - zval_dtor(converted); - FREE_ZVAL(converted); - } + zval_ptr_dtor(&converted); if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { - *sql = querystr.c; + *sql = querystr.s; } else { smart_str_free(&querystr); @@ -6666,41 +6663,44 @@ cleanup: PHP_FUNCTION(pg_insert) { zval *pgsql_link, *values; - char *table, *sql = NULL; - int table_len; - ulong option = PGSQL_DML_EXEC, return_sql; + char *table; + size_t table_len; + zend_ulong option = PGSQL_DML_EXEC, return_sql; PGconn *pg_link; PGresult *pg_result; ExecStatusType status; pgsql_result_handle *pgsql_handle; - int id = -1, argc = ZEND_NUM_ARGS(); + zend_string *sql = NULL; + int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l", + if (zend_parse_parameters(argc, "rsa|l", &pgsql_link, &table, &table_len, &values, &option) == FAILURE) { return; } if (option & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified"); + php_error_docref(NULL, E_WARNING, "Invalid option is specified"); + RETURN_FALSE; + } + + if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); + 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 */ option = option & ~PGSQL_DML_EXEC; - if (php_pgsql_insert(pg_link, table, values, option|PGSQL_DML_STRING, &sql TSRMLS_CC) == FAILURE) { + if (php_pgsql_insert(pg_link, table, values, option|PGSQL_DML_STRING, &sql) == FAILURE) { RETURN_FALSE; } - pg_result = PQexec(pg_link, sql); + pg_result = PQexec(pg_link, sql->val); if ((PGG(auto_reset_persistent) & 2) && PQstatus(pg_link) != CONNECTION_OK) { PQclear(pg_result); PQreset(pg_link); - pg_result = PQexec(pg_link, sql); + pg_result = PQexec(pg_link, sql->val); } efree(sql); @@ -6726,94 +6726,92 @@ PHP_FUNCTION(pg_insert) pgsql_handle->conn = pg_link; pgsql_handle->result = pg_result; pgsql_handle->row = 0; - ZEND_REGISTER_RESOURCE(return_value, pgsql_handle, le_result); - return; + RETURN_RES(zend_register_resource(pgsql_handle, le_result)); } else { PQclear(pg_result); RETURN_FALSE; } break; } - } else if (php_pgsql_insert(pg_link, table, values, option, &sql TSRMLS_CC) == FAILURE) { + } else if (php_pgsql_insert(pg_link, table, values, option, &sql) == FAILURE) { RETURN_FALSE; } if (return_sql) { - RETURN_STRING(sql, 0); + RETURN_STR(sql); + return; } RETURN_TRUE; } /* }}} */ -static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, HashTable *ht, int where_cond, const char *pad, int pad_len, ulong opt TSRMLS_DC) +static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, HashTable *ht, int where_cond, const char *pad, int pad_len, zend_ulong opt) /* {{{ */ { - HashPosition pos; - uint fld_len; - int key_type; - ulong num_idx; - char *fld, *tmp; + char *tmp; char buf[256]; - zval **val; - - for (zend_hash_internal_pointer_reset_ex(ht, &pos); - zend_hash_get_current_data_ex(ht, (void **)&val, &pos) == SUCCESS; - zend_hash_move_forward_ex(ht, &pos)) { - key_type = zend_hash_get_current_key_ex(ht, &fld, &fld_len, &num_idx, 0, &pos); - if (key_type == HASH_KEY_IS_LONG) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects associative array for values to be inserted"); + zend_ulong num_idx; + zend_string *fld; + zval *val; + + ZEND_HASH_FOREACH_KEY_VAL(ht, num_idx, fld, val) { + if (fld == NULL) { + php_error_docref(NULL, E_NOTICE, "Expects associative array for values to be inserted"); return -1; } if (opt & PGSQL_DML_ESCAPE) { - tmp = PGSQLescapeIdentifier(pg_link, fld, fld_len); + tmp = PGSQLescapeIdentifier(pg_link, fld->val, fld->len + 1); smart_str_appends(querystr, tmp); PGSQLfree(tmp); } else { - smart_str_appendl(querystr, fld, fld_len - 1); + smart_str_appendl(querystr, fld->val, fld->len); } - if (where_cond && (Z_TYPE_PP(val) == IS_BOOL || (Z_TYPE_PP(val) == IS_STRING && !strcmp(Z_STRVAL_PP(val), "NULL")))) { + if (where_cond && (Z_TYPE_P(val) == IS_TRUE || Z_TYPE_P(val) == IS_FALSE || (Z_TYPE_P(val) == IS_STRING && !strcmp(Z_STRVAL_P(val), "NULL")))) { smart_str_appends(querystr, " IS "); } else { smart_str_appendc(querystr, '='); } - switch(Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_STRING: if (opt & PGSQL_DML_ESCAPE) { size_t new_len; - tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1); - new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL); + tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1); + new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); smart_str_appendc(querystr, '\''); smart_str_appendl(querystr, tmp, new_len); smart_str_appendc(querystr, '\''); efree(tmp); } else { - smart_str_appendl(querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val)); + smart_str_appendl(querystr, Z_STRVAL_P(val), Z_STRLEN_P(val)); } break; case IS_LONG: - smart_str_append_long(querystr, Z_LVAL_PP(val)); + smart_str_append_long(querystr, Z_LVAL_P(val)); break; case IS_DOUBLE: - smart_str_appendl(querystr, buf, MIN(snprintf(buf, sizeof(buf), "%F", Z_DVAL_PP(val)), sizeof(buf)-1)); + smart_str_appendl(querystr, buf, MIN(snprintf(buf, sizeof(buf), "%F", Z_DVAL_P(val)), sizeof(buf)-1)); break; case IS_NULL: smart_str_appendl(querystr, "NULL", sizeof("NULL")-1); break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects scaler values. type=%d", Z_TYPE_PP(val)); + php_error_docref(NULL, E_WARNING, "Expects scaler values. type=%d", Z_TYPE_P(val)); return -1; } smart_str_appendl(querystr, pad, pad_len); + } ZEND_HASH_FOREACH_END(); + if (querystr->s) { + querystr->s->len -= pad_len; } - querystr->len -= pad_len; return 0; } +/* }}} */ /* {{{ php_pgsql_update */ -PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array, zval *ids_array, ulong opt, char **sql TSRMLS_DC) +PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array, zval *ids_array, zend_ulong opt, zend_string **sql) { - zval *var_converted = NULL, *ids_converted = NULL; + zval var_converted, ids_converted; smart_str querystr = {0}; int ret = FAILURE; @@ -6828,53 +6826,47 @@ PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *var return FAILURE; } + ZVAL_UNDEF(&var_converted); + ZVAL_UNDEF(&ids_converted); if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { - MAKE_STD_ZVAL(var_converted); - array_init(var_converted); - if (php_pgsql_convert(pg_link, table, var_array, var_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { + array_init(&var_converted); + if (php_pgsql_convert(pg_link, table, var_array, &var_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { goto cleanup; } - var_array = var_converted; - MAKE_STD_ZVAL(ids_converted); - array_init(ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { + var_array = &var_converted; + array_init(&ids_converted); + if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { goto cleanup; } - ids_array = ids_converted; + ids_array = &ids_converted; } smart_str_appends(&querystr, "UPDATE "); build_tablename(&querystr, pg_link, table); smart_str_appends(&querystr, " SET "); - if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(var_array), 0, ",", 1, opt TSRMLS_CC)) + if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(var_array), 0, ",", 1, opt)) goto cleanup; - + smart_str_appends(&querystr, " WHERE "); - - if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt TSRMLS_CC)) + + if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt)) goto cleanup; smart_str_appendc(&querystr, ';'); smart_str_0(&querystr); - if ((opt & PGSQL_DML_EXEC) && do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt TSRMLS_CC) == 0) { + if ((opt & PGSQL_DML_EXEC) && do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt) == 0) { ret = SUCCESS; } else if (opt & PGSQL_DML_STRING) { ret = SUCCESS; } cleanup: - if (var_converted) { - zval_dtor(var_converted); - FREE_ZVAL(var_converted); - } - if (ids_converted) { - zval_dtor(ids_converted); - FREE_ZVAL(ids_converted); - } + zval_ptr_dtor(&var_converted); + zval_ptr_dtor(&ids_converted); if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { - *sql = querystr.c; + *sql = querystr.s; } else { smart_str_free(&querystr); @@ -6888,31 +6880,34 @@ cleanup: PHP_FUNCTION(pg_update) { zval *pgsql_link, *values, *ids; - char *table, *sql = NULL; - int table_len; - ulong option = PGSQL_DML_EXEC; + char *table; + size_t table_len; + zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; - int id = -1, argc = ZEND_NUM_ARGS(); + zend_string *sql = NULL; + int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsaa|l", + if (zend_parse_parameters(argc, "rsaa|l", &pgsql_link, &table, &table_len, &values, &ids, &option) == FAILURE) { return; } if (option & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified"); + php_error_docref(NULL, E_WARNING, "Invalid option is specified"); RETURN_FALSE; } - - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); + if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } + + if (php_pgsql_flush_query(pg_link)) { + php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } - if (php_pgsql_update(pg_link, table, values, ids, option, &sql TSRMLS_CC) == FAILURE) { + if (php_pgsql_update(pg_link, table, values, ids, option, &sql) == FAILURE) { RETURN_FALSE; } if (option & PGSQL_DML_STRING) { - RETURN_STRING(sql, 0); + RETURN_STR(sql); } RETURN_TRUE; } @@ -6920,9 +6915,9 @@ PHP_FUNCTION(pg_update) /* {{{ php_pgsql_delete */ -PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, ulong opt, char **sql TSRMLS_DC) +PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, zend_ulong opt, zend_string **sql) { - zval *ids_converted = NULL; + zval ids_converted; smart_str querystr = {0}; int ret = FAILURE; @@ -6935,38 +6930,35 @@ PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids return FAILURE; } + ZVAL_UNDEF(&ids_converted); if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { - MAKE_STD_ZVAL(ids_converted); - array_init(ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { + array_init(&ids_converted); + if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { goto cleanup; } - ids_array = ids_converted; + ids_array = &ids_converted; } smart_str_appends(&querystr, "DELETE FROM "); build_tablename(&querystr, pg_link, table); smart_str_appends(&querystr, " WHERE "); - if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt TSRMLS_CC)) + if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt)) goto cleanup; smart_str_appendc(&querystr, ';'); smart_str_0(&querystr); - if ((opt & PGSQL_DML_EXEC) && do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt TSRMLS_CC) == 0) { + if ((opt & PGSQL_DML_EXEC) && do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt) == 0) { ret = SUCCESS; } else if (opt & PGSQL_DML_STRING) { ret = SUCCESS; } cleanup: - if (ids_converted) { - zval_dtor(ids_converted); - FREE_ZVAL(ids_converted); - } + zval_ptr_dtor(&ids_converted); if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { - *sql = querystr.c; + *sql = querystr.s; } else { smart_str_free(&querystr); @@ -6980,41 +6972,44 @@ cleanup: PHP_FUNCTION(pg_delete) { zval *pgsql_link, *ids; - char *table, *sql = NULL; - int table_len; - ulong option = PGSQL_DML_EXEC; + char *table; + size_t table_len; + zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; - int id = -1, argc = ZEND_NUM_ARGS(); + zend_string *sql; + int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l", + if (zend_parse_parameters(argc, "rsa|l", &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) { return; } if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified"); + php_error_docref(NULL, E_WARNING, "Invalid option is specified"); RETURN_FALSE; } - - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); + if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { + RETURN_FALSE; + } + + if (php_pgsql_flush_query(pg_link)) { + php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } - if (php_pgsql_delete(pg_link, table, ids, option, &sql TSRMLS_CC) == FAILURE) { + if (php_pgsql_delete(pg_link, table, ids, option, &sql) == FAILURE) { RETURN_FALSE; } if (option & PGSQL_DML_STRING) { - RETURN_STRING(sql, 0); + RETURN_STR(sql); } RETURN_TRUE; -} +} /* }}} */ /* {{{ php_pgsql_result2array */ -PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TSRMLS_DC) +PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array) { - zval *row; + zval row; char *field_name; size_t num_fields; int pg_numrows, pg_row; @@ -7025,28 +7020,22 @@ PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TS return FAILURE; } for (pg_row = 0; pg_row < pg_numrows; pg_row++) { - MAKE_STD_ZVAL(row); - array_init(row); - add_index_zval(ret_array, pg_row, row); + array_init(&row); for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) { if (PQgetisnull(pg_result, pg_row, i)) { field_name = PQfname(pg_result, i); - add_assoc_null(row, field_name); + add_assoc_null(&row, field_name); } else { char *element = PQgetvalue(pg_result, pg_row, i); if (element) { - char *data; - size_t data_len; const size_t element_len = strlen(element); - data = safe_estrndup(element, element_len); - data_len = element_len; - field_name = PQfname(pg_result, i); - add_assoc_stringl(row, field_name, data, data_len, 0); + add_assoc_stringl(&row, field_name, element, element_len); } } } + add_index_zval(ret_array, pg_row, &row); } return SUCCESS; } @@ -7054,9 +7043,9 @@ PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TS /* {{{ php_pgsql_select */ -PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, ulong opt, char **sql TSRMLS_DC) +PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, zend_ulong opt, zend_string **sql) { - zval *ids_converted = NULL; + zval ids_converted; smart_str querystr = {0}; int ret = FAILURE; PGresult *pg_result; @@ -7071,40 +7060,37 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids return FAILURE; } + ZVAL_UNDEF(&ids_converted); if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { - MAKE_STD_ZVAL(ids_converted); - array_init(ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { + array_init(&ids_converted); + if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { goto cleanup; } - ids_array = ids_converted; + ids_array = &ids_converted; } smart_str_appends(&querystr, "SELECT * FROM "); build_tablename(&querystr, pg_link, table); smart_str_appends(&querystr, " WHERE "); - if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt TSRMLS_CC)) + if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt)) goto cleanup; smart_str_appendc(&querystr, ';'); smart_str_0(&querystr); - pg_result = PQexec(pg_link, querystr.c); + pg_result = PQexec(pg_link, querystr.s->val); if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) { - ret = php_pgsql_result2array(pg_result, ret_array TSRMLS_CC); + ret = php_pgsql_result2array(pg_result, ret_array); } else { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed to execute '%s'", querystr.c); + php_error_docref(NULL, E_NOTICE, "Failed to execute '%s'", querystr.s->val); } PQclear(pg_result); cleanup: - if (ids_converted) { - zval_dtor(ids_converted); - FREE_ZVAL(ids_converted); - } + zval_ptr_dtor(&ids_converted); if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { - *sql = querystr.c; + *sql = querystr.s; } else { smart_str_free(&querystr); @@ -7118,34 +7104,37 @@ cleanup: PHP_FUNCTION(pg_select) { zval *pgsql_link, *ids; - char *table, *sql = NULL; - int table_len; - ulong option = PGSQL_DML_EXEC; + char *table; + size_t table_len; + zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; - int id = -1, argc = ZEND_NUM_ARGS(); + zend_string *sql = NULL; + int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l", + if (zend_parse_parameters(argc, "rsa|l", &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) { return; } if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified"); + php_error_docref(NULL, E_WARNING, "Invalid option is specified"); + RETURN_FALSE; + } + + if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { RETURN_FALSE; } - - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); + if (php_pgsql_flush_query(pg_link)) { + php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } array_init(return_value); - if (php_pgsql_select(pg_link, table, ids, return_value, option, &sql TSRMLS_CC) == FAILURE) { - zval_dtor(return_value); + if (php_pgsql_select(pg_link, table, ids, return_value, option, &sql) == FAILURE) { + zval_ptr_dtor(return_value); RETURN_FALSE; } if (option & PGSQL_DML_STRING) { - zval_dtor(return_value); - RETURN_STRING(sql, 0); + zval_ptr_dtor(return_value); + RETURN_STR(sql); } return; } |