summaryrefslogtreecommitdiff
path: root/ext/pgsql
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>2002-04-21 09:46:29 +0000
committerSascha Schumann <sas@php.net>2002-04-21 09:46:29 +0000
commit7e597b260a83f293e2ddf1c212bf23c1ac388b97 (patch)
tree33f30338e112e688146412f267e94aa6e30866fb /ext/pgsql
parentdc8c2c9a6cce5e564bb30a63eddf2b45e71e2048 (diff)
downloadphp-git-7e597b260a83f293e2ddf1c212bf23c1ac388b97.tar.gz
My patch as posted to php-dev + warnings/errors fixed as seen in
Yasuo's reply.
Diffstat (limited to 'ext/pgsql')
-rw-r--r--ext/pgsql/pgsql.c903
1 files changed, 214 insertions, 689 deletions
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index a2c7a6ea21..247a3860cd 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -32,6 +32,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/php_standard.h"
+#include "ext/standard/php_smart_str.h"
#include "php_pgsql.h"
#include "php_globals.h"
@@ -1040,15 +1041,16 @@ PHP_FUNCTION(pg_last_notice)
static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC)
{
PGresult *result;
- char hashed_oid_key[32];
+ smart_str str = {0};
list_entry *field_type;
char *ret=NULL;
/* try to lookup the type in the resource list */
- snprintf(hashed_oid_key,31,"pgsql_oid_%u", oid);
- hashed_oid_key[31]=0;
+ smart_str_appends(&str, "pgsql_oid_");
+ smart_str_append_unsigned(&str, oid);
+ smart_str_0(&str);
- if (zend_hash_find(list,hashed_oid_key,strlen(hashed_oid_key)+1,(void **) &field_type)==SUCCESS) {
+ if (zend_hash_find(list,str.c,str.len+1,(void **) &field_type)==SUCCESS) {
ret = estrdup((char *)field_type->ptr);
} else { /* hash all oid's */
int i,num_rows;
@@ -1057,6 +1059,7 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC)
list_entry new_oid_entry;
if ((result = PQexec(pgsql,"select oid,typname from pg_type")) == NULL) {
+ smart_str_free(&str);
return empty_string;
}
num_rows = PQntuples(result);
@@ -1067,18 +1070,25 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC)
if ((tmp_oid = PQgetvalue(result,i,oid_offset))==NULL) {
continue;
}
- snprintf(hashed_oid_key,31,"pgsql_oid_%s",tmp_oid);
+
+ str.len = 0;
+ smart_str_appends(&str, "pgsql_oid_");
+ smart_str_appends(&str, tmp_oid);
+ smart_str_0(&str);
+
if ((tmp_name = PQgetvalue(result,i,name_offset))==NULL) {
continue;
}
Z_TYPE(new_oid_entry) = le_string;
new_oid_entry.ptr = estrdup(tmp_name);
- zend_hash_update(list,hashed_oid_key,strlen(hashed_oid_key)+1,(void *) &new_oid_entry, sizeof(list_entry), NULL);
+ zend_hash_update(list,str.c,str.len+1,(void *) &new_oid_entry, sizeof(list_entry), NULL);
if (!ret && strtoul(tmp_oid, &end_ptr, 10)==oid) {
ret = estrdup(tmp_name);
}
}
}
+
+ smart_str_free(&str);
return ret;
}
/* }}} */
@@ -1481,7 +1491,6 @@ PHP_FUNCTION(pg_last_oid)
PGresult *pgsql_result;
pgsql_result_handle *pg_result;
Oid oid;
- char *oid_str;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result)==FAILURE) {
WRONG_PARAM_COUNT;
@@ -1494,9 +1503,11 @@ PHP_FUNCTION(pg_last_oid)
if (oid == InvalidOid) {
RETURN_FALSE;
} else if (oid > LONG_MAX) {
- oid_str = (char *)emalloc(PGSQL_MAX_LENGTH_OF_LONG+1);
- sprintf(oid_str, "%u", oid);
- RETURN_STRING(oid_str, 0);
+ smart_str s = {0};
+
+ smart_str_append_unsigned(&s, oid);
+
+ RETURN_STRINGL(s.c, s.len, 0);
}
RETURN_LONG((long)oid);
#else
@@ -1603,7 +1614,6 @@ PHP_FUNCTION(pg_lo_create)
zval **pgsql_link = NULL;
PGconn *pgsql;
Oid pgsql_oid;
- char *oid_str;
int id = -1;
switch(ZEND_NUM_ARGS()) {
@@ -1637,9 +1647,11 @@ PHP_FUNCTION(pg_lo_create)
RETURN_FALSE;
}
if (pgsql_oid > LONG_MAX) {
- oid_str = (char *)emalloc(PGSQL_MAX_LENGTH_OF_LONG+1);
- sprintf(oid_str, "%u", pgsql_oid);
- RETURN_STRING(oid_str, 0);
+ smart_str s = {0};
+
+ smart_str_append_unsigned(&s, pgsql_oid);
+
+ RETURN_STRINGL(str.c, str.len, 0);
}
RETURN_LONG((long)pgsql_oid);
}
@@ -1985,7 +1997,7 @@ PHP_FUNCTION(pg_lo_read_all)
PHP_FUNCTION(pg_lo_import)
{
zval *pgsql_link = NULL;
- char *file_in, *oid_str;
+ char *file_in;
int id = -1, name_len;
int argc = ZEND_NUM_ARGS();
PGconn *pgsql;
@@ -2020,9 +2032,11 @@ PHP_FUNCTION(pg_lo_import)
RETURN_FALSE;
}
if (oid > LONG_MAX) {
- oid_str = (char *)emalloc(PGSQL_MAX_LENGTH_OF_LONG+1);
- sprintf(oid_str, "%u", oid);
- RETURN_STRING(oid_str, 0);
+ smart_str s = {0};
+
+ smart_str_append_unsigned(&s, oid);
+
+ RETURN_STRINGL(s.c, s.len, 0);
}
RETURN_LONG((long)oid);
}
@@ -3875,15 +3889,38 @@ PHP_FUNCTION(pg_convert)
}
/* }}} */
+static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, zend_bool async)
+{
+ if (async) {
+ if (PQsendQuery(pg_link, querystr->c)) {
+ return 0;
+ }
+ }
+ else {
+ PGresult *pg_result;
+
+ pg_result = PQexec(pg_link, querystr->c);
+ if (PQresultStatus(pg_result) == expect) {
+ return 0;
+ } else {
+ php_error(E_NOTICE, "%s() failed to execute '%s'",
+ get_active_function_name(TSRMLS_C), querystr->c);
+ PQclear(pg_result);
+ }
+ }
+
+ return -1;
+}
+
/* {{{ php_pgsql_insert
*/
PHPAPI int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array, zend_bool convert, zend_bool async TSRMLS_DC)
{
zval **val, *converted = NULL;
- char *query_tpl = "INSERT INTO %s (%s) VALUES (%s);";
- char *query, *fields, *fields_pos, *values, *values_pos, *fld, buf[256];
- size_t fields_len = 1, values_len = 1;
- int key_type, fld_len, ret = SUCCESS;
+ char buf[256];
+ char *fld;
+ smart_str querystr = {0};
+ int key_type, fld_len, ret = FAILURE;
ulong num_idx;
HashPosition pos;
@@ -3898,171 +3935,71 @@ PHPAPI int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array,
MAKE_STD_ZVAL(converted);
array_init(converted);
if (php_pgsql_convert(pg_link, table, var_array, converted TSRMLS_CC) == FAILURE) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- return FAILURE;
+ goto cleanup;
}
var_array = converted;
}
- /* compute length */
- 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)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &fld, &fld_len, &num_idx, 0, &pos);
+
+ if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0) {
+ goto cleanup;
+ }
+
+ smart_str_appends(&querystr, "INSERT INTO ");
+ smart_str_appends(&querystr, 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_EXISTANT) {
if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- values_len += Z_STRLEN_PP(val)+1;
- break;
- case IS_LONG:
- values_len += PGSQL_MAX_LENGTH_OF_LONG+1;
- break;
- case IS_DOUBLE:
- values_len += PGSQL_MAX_LENGTH_OF_DOUBLE+1;
- break;
- default:
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
- php_error(E_NOTICE, "%s() expects scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- fields_len += fld_len+1;
- }
- if (fields_len == 1 || values_len == 1) {
- /* there aren't any fields to insert */
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
+ goto cleanup;
}
- return FAILURE;
+ smart_str_appendl(&querystr, fld, fld_len);
+ zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos);
}
+ smart_str_appends(&querystr, ") VALUES (");
- fields = (char *)emalloc(fields_len+1);
- if (fields == NULL) {
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- fields_pos = fields;
- values = (char *)emalloc(values_len+1);
- if (values == NULL) {
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
- efree(fields);
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- values_pos = values;
- query = (char *)emalloc(strlen(query_tpl)+strlen(table)+fields_len+values_len+1);
- if (query == NULL) {
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
- efree(fields);
- efree(values);
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
-
- /* make fields and values string */
+ /* 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)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
- efree(fields);
- efree(values);
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
+
+ /* we can avoid the key_type check here, because we tested it in the other loop */
switch(Z_TYPE_PP(val)) {
case IS_STRING:
- memcpy(values_pos, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
- values_pos += Z_STRLEN_PP(val);
+ smart_str_appendl(&querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
break;
case IS_LONG:
- sprintf(buf, "%ld", Z_LVAL_PP(val));
- memcpy(values_pos, buf, strlen(buf));
- values_pos += strlen(buf);
+ smart_str_append_long(&querystr, Z_LVAL_PP(val));
break;
case IS_DOUBLE:
- sprintf(buf, "%f", Z_DVAL_PP(val));
- memcpy(values_pos, buf, strlen(buf));
- values_pos += strlen(buf);
+ smart_str_appendl(&querystr, buf, sprintf(buf, "%f", Z_DVAL_PP(val)));
break;
default:
/* should not happen */
- if (convert) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
- efree(fields);
- efree(values);
php_error(E_WARNING, "%s(): Report this error to php-dev@lists.php.net",
get_active_function_name(TSRMLS_C));
- return FAILURE;
+ goto cleanup;
break;
}
- *values_pos = ',';
- values_pos++;
-
- memcpy(fields_pos, fld, fld_len-1);
- fields_pos += fld_len-1;
- *fields_pos = ',';
- fields_pos++;
- }
- values_pos--;
- *values_pos = '\0';
- fields_pos--;
- *fields_pos = '\0';
+ smart_str_appendc(&querystr, ',');
+ }
+ /* Remove the trailing "," */
+ querystr.len--;
+ smart_str_appends(&querystr, ");");
+ smart_str_0(&querystr);
+
+ if (do_exec(&querystr, PGRES_COMMAND_OK, pg_link, async) == 0)
+ ret = SUCCESS;
+
+cleanup:
if (convert) {
zval_dtor(converted);
FREE_ZVAL(converted);
}
- sprintf(query, query_tpl, table, fields, values);
- efree(fields);
- efree(values);
- if (async) {
- if (!PQsendQuery(pg_link, query)) {
- ret = FAILURE;
- }
- }
- else {
- PGresult *pg_result;
- pg_result = PQexec(pg_link, query);
- if (PQresultStatus(pg_result) != PGRES_COMMAND_OK) {
- ret = FAILURE;
- php_error(E_NOTICE, "%s() failed to insert '%s'",
- get_active_function_name(TSRMLS_C), query);
- PQclear(pg_result);
- }
- }
- efree(query);
+ smart_str_free(&querystr);
return ret;
}
/* }}} */
@@ -4095,18 +4032,59 @@ PHP_FUNCTION(pg_insert)
RETURN_TRUE;
}
/* }}} */
-
+
+static inline int build_assignment_string(smart_str *querystr, HashTable *ht, const char *pad, int pad_len TSRMLS_DC)
+{
+ HashPosition pos;
+ size_t fld_len;
+ int key_type;
+ ulong num_idx;
+ char *fld;
+ 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(E_NOTICE,"%s() expects associative array for values to be inserted",
+ get_active_function_name(TSRMLS_C));
+ return -1;
+ }
+ smart_str_appendl(querystr, fld, fld_len);
+ smart_str_appendc(querystr, '=');
+
+ switch(Z_TYPE_PP(val)) {
+ case IS_STRING:
+ smart_str_appendl(querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
+ break;
+ case IS_LONG:
+ smart_str_append_long(querystr, Z_LVAL_PP(val));
+ break;
+ case IS_DOUBLE:
+ smart_str_appendl(querystr, buf, sprintf(buf, "%f", Z_DVAL_PP(val)));
+ break;
+ default:
+ /* should not happen */
+ php_error(E_NOTICE, "%s() expect scaler values other than null. Need to convert?",
+ get_active_function_name(TSRMLS_C));
+ return -1;
+ }
+ smart_str_appendl(querystr, pad, pad_len);
+ }
+ querystr->len -= pad_len;
+
+ return 0;
+}
+
/* {{{ php_pgsql_update
*/
PHPAPI int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array, zval *ids_array, zend_bool convert, zend_bool async TSRMLS_DC)
{
- zval **val, *var_converted = NULL, *ids_converted = NULL;
- char *query_tpl = "UPDATE %s SET %s WHERE %s;";
- char *query, *values, *values_pos, *ids, *ids_pos, *fld, buf[256];
- size_t fields_len = 1, values_len = 1, idsf_len = 1, idsv_len = 1, fld_len;
- int key_type, ret = SUCCESS;
- ulong num_idx;
- HashPosition pos;
+ zval *var_converted = NULL, *ids_converted = NULL;
+ smart_str querystr = {0};
+ int ret = SUCCESS;
assert(pg_link != NULL);
assert(table != NULL);
@@ -4119,277 +4097,50 @@ PHPAPI int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array,
MAKE_STD_ZVAL(var_converted);
array_init(var_converted);
if (php_pgsql_convert(pg_link, table, var_array, var_converted TSRMLS_CC) == FAILURE) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- return 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 TSRMLS_CC) == FAILURE) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- return FAILURE;
+ goto cleanup;
}
ids_array = ids_converted;
}
- /* compute length */
- 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)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- }
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- values_len += Z_STRLEN_PP(val)+1;
- break;
- case IS_LONG:
- values_len += PGSQL_MAX_LENGTH_OF_LONG+1;
- break;
- case IS_DOUBLE:
- values_len += PGSQL_MAX_LENGTH_OF_DOUBLE+1;
- break;
- default:
- php_error(E_NOTICE, "%s() expect scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- }
- break;
- }
- fields_len += fld_len+2; /* field name + '=' + ',' */
+ if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0
+ || zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) {
+ goto cleanup;
}
- if (fields_len == 1 || values_len == 1) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- }
- return FAILURE;
- }
-
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ids_array), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(ids_array), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(ids_array), &pos)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(ids_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- idsv_len += Z_STRLEN_PP(val)+1;
- break;
- case IS_LONG:
- idsv_len += PGSQL_MAX_LENGTH_OF_LONG+1;
- break;
- case IS_DOUBLE:
- idsv_len += PGSQL_MAX_LENGTH_OF_DOUBLE+1;
- break;
- default:
- php_error(E_NOTICE, "%s() expects scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- return FAILURE;
- }
- idsf_len += fld_len+6; /* field name + '=' + ' AND ' */
- }
+ smart_str_appends(&querystr, "UPDATE ");
+ smart_str_appends(&querystr, table);
+ smart_str_appends(&querystr, " SET ");
- if (fields_len == 1 || values_len == 1 || idsv_len == 1 || idsf_len == 1) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- return FAILURE;
- }
+ if (build_assignment_string(&querystr, Z_ARRVAL_P(var_array), ",", 1 TSRMLS_CC))
+ goto cleanup;
- values = (char *)emalloc(fields_len + values_len);
- if (values == NULL) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- values_pos = values;
- ids = (char *)emalloc(idsf_len + idsv_len);
- if (ids == NULL) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(values);
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- ids_pos = ids;
+ smart_str_appends(&querystr, " WHERE ");
+
+ if (build_assignment_string(&querystr, Z_ARRVAL_P(ids_array), " AND ", sizeof(" AND ")-1 TSRMLS_CC))
+ goto cleanup;
- query = (char *)emalloc(strlen(query_tpl) + strlen(table) + fields_len + values_len + idsf_len + idsv_len);
- if (query == NULL) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(values);
- efree(ids);
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- /* make values and ids 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)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(ids);
- efree(values);
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- memcpy(values_pos, fld, fld_len-1);
- values_pos += fld_len-1;
- *values_pos = '=';
- values_pos++;
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- memcpy(values_pos, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
- values_pos += Z_STRLEN_PP(val);
- break;
- case IS_LONG:
- sprintf(buf, "%ld", Z_LVAL_PP(val));
- memcpy(values_pos, buf, strlen(buf));
- values_pos += strlen(buf);
- break;
- case IS_DOUBLE:
- sprintf(buf, "%f", Z_DVAL_PP(val));
- memcpy(values_pos, buf, strlen(buf));
- values_pos += strlen(buf);
- break;
- default:
- /* should not happen */
- php_error(E_NOTICE, "%s() expect scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- }
- *values_pos = ',';
- values_pos++;
- }
- values_pos--;
- *values_pos = '\0';
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ids_array), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(ids_array), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(ids_array), &pos)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(ids_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(ids);
- efree(values);
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- memcpy(ids_pos, fld, fld_len-1);
- ids_pos += fld_len-1;
- *ids_pos = '=';
- ids_pos++;
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- memcpy(ids_pos, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
- ids_pos += Z_STRLEN_PP(val);
- break;
- case IS_LONG:
- sprintf(buf, "%ld", Z_LVAL_PP(val));
- memcpy(ids_pos, buf, strlen(buf));
- ids_pos += strlen(buf);
- break;
- case IS_DOUBLE:
- sprintf(buf, "%f", Z_DVAL_PP(val));
- memcpy(ids_pos, buf, strlen(buf));
- ids_pos += strlen(buf);
- break;
- default:
- /* should not happen */
- php_error(E_NOTICE, "%s() expect scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- }
- memcpy(ids_pos, " AND ", 5);
- ids_pos += 5;
- }
- ids_pos -= 5;
- *ids_pos = '\0';
- if (convert) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
+ smart_str_appendc(&querystr, ';');
+ smart_str_0(&querystr);
- sprintf(query, query_tpl, table, values, ids);
- efree(ids);
- efree(values);
- if (async) {
- if (!PQsendQuery(pg_link, query)) {
- ret = FAILURE;
- }
+ if (do_exec(&querystr, PGRES_COMMAND_OK, pg_link, async) == 0)
+ ret = SUCCESS;
+
+cleanup:
+ if (var_converted) {
+ zval_dtor(var_converted);
+ FREE_ZVAL(var_converted);
}
- else {
- PGresult *pg_result;
- pg_result = PQexec(pg_link, query);
- if (PQresultStatus(pg_result) != PGRES_COMMAND_OK) {
- ret = FAILURE;
- php_error(E_NOTICE, "%s() failed to update '%s'",
- get_active_function_name(TSRMLS_C), query);
- PQclear(pg_result);
- }
+ if (ids_converted) {
+ zval_dtor(ids_converted);
+ FREE_ZVAL(ids_converted);
}
- efree(query);
+ smart_str_free(&querystr);
return ret;
}
/* }}} */
@@ -4427,13 +4178,9 @@ PHP_FUNCTION(pg_update)
*/
PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, zend_bool convert, zend_bool async TSRMLS_DC)
{
- zval **val, *ids_converted = NULL;
- char *query_tpl = "DELETE FROM %s WHERE %s;";
- char *query, *ids, *ids_pos, *fld, buf[256];
- size_t idsf_len = 1, idsv_len = 1, fld_len;
- int key_type, ret = SUCCESS;
- ulong num_idx;
- HashPosition pos;
+ zval *ids_converted = NULL;
+ smart_str querystr = {0};
+ int ret = FAILURE;
assert(pg_link != NULL);
assert(table != NULL);
@@ -4445,147 +4192,33 @@ PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array,
MAKE_STD_ZVAL(ids_converted);
array_init(ids_converted);
if (php_pgsql_convert(pg_link, table, ids_array, ids_converted TSRMLS_CC) == FAILURE) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- return FAILURE;
+ goto cleanup;
}
ids_array = ids_converted;
}
- /* compute length */
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ids_array), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(ids_array), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(ids_array), &pos)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(ids_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- idsv_len += Z_STRLEN_PP(val)+1;
- break;
- case IS_LONG:
- idsv_len += PGSQL_MAX_LENGTH_OF_LONG+1;
- break;
- case IS_DOUBLE:
- idsv_len += PGSQL_MAX_LENGTH_OF_DOUBLE+1;
- break;
- default:
- php_error(E_NOTICE, "%s() expects scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- return FAILURE;
- }
- idsf_len += fld_len+6; /* field name + '=' + ' AND ' */
+ if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) {
+ goto cleanup;
}
- if (idsv_len == 1 || idsf_len == 1) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- return FAILURE;
- }
-
- ids = (char *)emalloc(idsf_len + idsv_len);
- if (ids == NULL) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- ids_pos = ids;
+ smart_str_appends(&querystr, "DELETE FROM ");
+ smart_str_appends(&querystr, table);
+ smart_str_appends(&querystr, " WHERE ");
- query = (char *)emalloc(strlen(query_tpl)+strlen(table)+idsf_len+idsv_len);
- if (query == NULL) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(ids);
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- /* make values and ids string */
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ids_array), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(ids_array), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(ids_array), &pos)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(ids_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(ids);
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- memcpy(ids_pos, fld, fld_len-1);
- ids_pos += fld_len-1;
- *ids_pos = '=';
- ids_pos++;
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- memcpy(ids_pos, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
- ids_pos += Z_STRLEN_PP(val);
- break;
- case IS_LONG:
- sprintf(buf, "%ld", Z_LVAL_PP(val));
- memcpy(ids_pos, buf, strlen(buf));
- ids_pos += strlen(buf);
- break;
- case IS_DOUBLE:
- sprintf(buf, "%f", Z_DVAL_PP(val));
- memcpy(ids_pos, buf, strlen(buf));
- ids_pos += strlen(buf);
- break;
- default:
- /* should not happen */
- php_error(E_NOTICE, "%s() expect scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- }
- memcpy(ids_pos, " AND ", 5);
- ids_pos += 5;
- }
- ids_pos -= 5;
- *ids_pos = '\0';
+ if (build_assignment_string(&querystr, Z_ARRVAL_P(ids_array), " AND ", sizeof(" AND ")-1 TSRMLS_CC))
+ goto cleanup;
+
+ smart_str_appendc(&querystr, ';');
+
+ if (do_exec(&querystr, PGRES_TUPLES_OK, pg_link, async) == 0)
+ ret = SUCCESS;
+
+cleanup:
if (convert) {
zval_dtor(ids_converted);
FREE_ZVAL(ids_converted);
}
-
- sprintf(query, query_tpl, table, ids);
- efree(ids);
- if (async) {
- if (!PQsendQuery(pg_link, query)) {
- ret = FAILURE;
- }
- }
- else {
- PGresult *pg_result;
- pg_result = PQexec(pg_link, query);
- if (PQresultStatus(pg_result) != PGRES_TUPLES_OK) {
- ret = FAILURE;
- php_error(E_NOTICE, "%s() failed to update '%s'",
- get_active_function_name(TSRMLS_C), query);
- PQclear(pg_result);
- }
- }
- efree(query);
+ smart_str_free(&querystr);
return ret;
}
/* }}} */
@@ -4665,14 +4298,10 @@ PHPAPI int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TSRMLS_DC
*/
PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, zend_bool convert TSRMLS_DC)
{
- zval **val, *ids_converted = NULL;
- char *query_tpl = "SELECT * FROM %s WHERE %s;";
- char *query, *ids, *ids_pos, *fld, buf[256];
- size_t idsf_len = 1, idsv_len = 1, fld_len;
- int key_type, ret = SUCCESS;
+ zval *ids_converted = NULL;
+ smart_str querystr = {0};
+ int ret = FAILURE;
PGresult *pg_result;
- ulong num_idx;
- HashPosition pos;
assert(pg_link != NULL);
assert(table != NULL);
@@ -4684,143 +4313,39 @@ PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array,
MAKE_STD_ZVAL(ids_converted);
array_init(ids_converted);
if (php_pgsql_convert(pg_link, table, ids_array, ids_converted TSRMLS_CC) == FAILURE) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- return FAILURE;
+ goto cleanup;
}
ids_array = ids_converted;
}
- /* compute length */
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ids_array), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(ids_array), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(ids_array), &pos)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(ids_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- idsv_len += Z_STRLEN_PP(val)+1;
- break;
- case IS_LONG:
- idsv_len += PGSQL_MAX_LENGTH_OF_LONG+1;
- break;
- case IS_DOUBLE:
- idsv_len += PGSQL_MAX_LENGTH_OF_DOUBLE+1;
- break;
- default:
- php_error(E_NOTICE, "%s() expects scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- return FAILURE;
- }
- idsf_len += fld_len+6; /* field name + '=' + ' AND ' */
+ if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) {
+ goto cleanup;
}
- if (idsv_len == 1 || idsf_len == 1) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- return FAILURE;
- }
-
- ids = (char *)emalloc(idsf_len + idsv_len);
- if (ids == NULL) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- ids_pos = ids;
+ smart_str_appends(&querystr, "SELECT * FROM ");
+ smart_str_appends(&querystr, table);
+ smart_str_appends(&querystr, " WHERE ");
- query = (char *)emalloc(strlen(query_tpl)+strlen(table)+idsf_len+idsv_len);
- if (query == NULL) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(ids);
- php_error(E_WARNING, "%s() cannot allocate memory",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- /* make values and ids string */
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ids_array), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(ids_array), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(ids_array), &pos)) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(ids_array), &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- efree(ids);
- php_error(E_NOTICE,"%s() expects associative array for values to be inserted",
- get_active_function_name(TSRMLS_C));
- return FAILURE;
- }
- memcpy(ids_pos, fld, fld_len-1);
- ids_pos += fld_len-1;
- *ids_pos = '=';
- ids_pos++;
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- memcpy(ids_pos, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
- ids_pos += Z_STRLEN_PP(val);
- break;
- case IS_LONG:
- sprintf(buf, "%ld", Z_LVAL_PP(val));
- memcpy(ids_pos, buf, strlen(buf));
- ids_pos += strlen(buf);
- break;
- case IS_DOUBLE:
- sprintf(buf, "%f", Z_DVAL_PP(val));
- memcpy(ids_pos, buf, strlen(buf));
- ids_pos += strlen(buf);
- break;
- default:
- /* should not happen */
- php_error(E_NOTICE, "%s() expect scaler values other than null. Need to convert?",
- get_active_function_name(TSRMLS_C));
- }
- memcpy(ids_pos, " AND ", 5);
- ids_pos += 5;
- }
- ids_pos -= 5;
- *ids_pos = '\0';
- if (convert) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
+ if (build_assignment_string(&querystr, Z_ARRVAL_P(ids_array), " AND ", sizeof(" AND ")-1 TSRMLS_CC))
+ goto cleanup;
- sprintf(query, query_tpl, table, ids);
- efree(ids);
- pg_result = PQexec(pg_link, query);
- if (PQresultStatus(pg_result) != PGRES_TUPLES_OK) {
- ret = FAILURE;
- php_error(E_NOTICE, "%s() failed to update '%s'",
- get_active_function_name(TSRMLS_C), query);
+ smart_str_appendc(&querystr, ';');
+
+ pg_result = PQexec(pg_link, querystr.c);
+ if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) {
+ ret = php_pgsql_result2array(pg_result, ret_array TSRMLS_CC);
+ } else {
+ php_error(E_NOTICE, "%s() failed to execute '%s'",
+ get_active_function_name(TSRMLS_C), querystr.c);
PQclear(pg_result);
}
- efree(query);
- if (ret == SUCCESS) {
- ret = php_pgsql_result2array(pg_result, ret_array TSRMLS_CC);
+cleanup:
+ if (convert) {
+ zval_dtor(ids_converted);
+ FREE_ZVAL(ids_converted);
}
+ smart_str_free(&querystr);
return ret;
}
/* }}} */