From: Yasuo Ohgaki Date: Tue, 23 Apr 2002 03:42:26 +0000 (+0000) Subject: Make pg_convert/pg_insert/pg_select/pg_update/pg_delete a bit more flexible. X-Git-Tag: php-4.3.0dev-ZendEngine2-Preview1~484 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7e0eddadd0931c45208c393b340085e9c550852;p=php Make pg_convert/pg_insert/pg_select/pg_update/pg_delete a bit more flexible. pg_convert() may ignore, NOT NULL and/or DEFAULT. pg_insert/pg_update/pg_select/pg_update may return query string. --- diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index fe49782b36..9c98a71ee0 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -397,7 +397,15 @@ PHP_MINIT_FUNCTION(pgsql) REGISTER_LONG_CONSTANT("PGSQL_BAD_RESPONSE", PGRES_BAD_RESPONSE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_NONFATAL_ERROR", PGRES_NONFATAL_ERROR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_FATAL_ERROR", PGRES_FATAL_ERROR, CONST_CS | CONST_PERSISTENT); - + /* pg_convert options */ + REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_DEFAULT", PGSQL_CONV_IGNORE_DEFAULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PGSQL_CONV_FORCE_NULL", PGSQL_CONV_FORCE_NULL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_NOT_NULL", PGSQL_CONV_IGNORE_NOT_NULL, CONST_CS | CONST_PERSISTENT); + /* pg_insert/update/delete/select options */ + REGISTER_LONG_CONSTANT("PGSQL_DML_NO_CONV", PGSQL_DML_NO_CONV, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PGSQL_DML_EXEC", PGSQL_DML_EXEC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PGSQL_DML_ASYNC", PGSQL_DML_ASYNC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT); return SUCCESS; } /* }}} */ @@ -3047,10 +3055,26 @@ static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) } /* }}} */ +#define PGSQL_CONV_CHECK_IGNORE() \ + if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { \ + /* if value is NULL and has default, remove entry 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 */ \ + else if (Z_BVAL_PP(not_null)) { \ + php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", \ + get_active_function_name(TSRMLS_C), field ); \ + err = 1; \ + } \ + } + /* {{{ php_pgsql_convert * check and convert array values (fieldname=>vlaue pair) for sql */ -PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result TSRMLS_DC) +PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result, ulong opt TSRMLS_DC) { HashPosition pos; char *field = NULL; @@ -3062,6 +3086,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval assert(pg_link != NULL); assert(Z_TYPE_P(values) == IS_ARRAY); assert(Z_TYPE_P(result) == IS_ARRAY); + assert(!(opt & ~PGSQL_CONV_OPTS)); if (!table_name) { return FAILURE; @@ -3179,20 +3204,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string, null, long or boolelan value for pgsql '%s' (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3235,20 +3247,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string, null, long or double value for pgsql '%s' (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3290,20 +3289,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string, null, long or double value for pgsql '%s' (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3352,20 +3338,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string, null, long or double value for pgsql '%s' (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3408,20 +3381,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string, null, long or double value for '%s' (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3454,20 +3414,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string or null for '%s' (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3500,20 +3447,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string or null for pgsql %s field (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3545,20 +3479,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string or null for pgsql %s field (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3590,20 +3511,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string or null for pgsql %s field (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3636,20 +3544,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string or null for pgsql %s field (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3693,20 +3588,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string, null, long or double value for pgsql '%s' (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3738,20 +3620,7 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval default: err = 1; } - if (!err && !strcmp(Z_STRVAL_P(new_val), "NULL")) { - /* if value is NULL and has default, remove entry to use default value*/ - if (Z_BVAL_PP(has_default)) { - zval_dtor(new_val); - FREE_ZVAL(new_val); - skip_field = 1; - } - /* raise error if it's not null */ - else if (Z_BVAL_PP(not_null)) { - php_error(E_NOTICE, "%s() detected NULL for 'NOT NULL' field '%s'", - get_active_function_name(TSRMLS_C), field ); - err = 1; - } - } + PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error(E_NOTICE, "%s() expects string or null for pgsql %s field (%s)", get_active_function_name(TSRMLS_C), Z_STRVAL_PP(type), field); @@ -3806,21 +3675,26 @@ PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval /* }}} */ -/* {{{ proto array pg_convert(resource db, string table, array values) +/* {{{ 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; size_t table_name_len; + ulong option = 0; PGconn *pg_link; int id = -1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rsa", &pgsql_link, &table_name, &table_name_len, &values) == FAILURE) { + "rsa|l", &pgsql_link, &table_name, &table_name_len, &values, &option) == FAILURE) { return; } - + if (option & ~PGSQL_CONV_OPTS) { + php_error(E_WARNING, "%s() invalid option is spedified", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } if (!table_name_len) { php_error(E_NOTICE, "%s() table name is invalid", get_active_function_name(TSRMLS_C)); @@ -3834,16 +3708,16 @@ PHP_FUNCTION(pg_convert) get_active_function_name(TSRMLS_C)); } array_init(return_value); - if (php_pgsql_convert(pg_link, table_name, values, return_value TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert(pg_link, table_name, values, return_value, option TSRMLS_CC) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } } /* }}} */ -static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, zend_bool async TSRMLS_DC) +static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, ulong opt TSRMLS_DC) { - if (async) { + if (opt & PGSQL_DML_ASYNC) { if (PQsendQuery(pg_link, querystr->c)) { return 0; } @@ -3866,7 +3740,7 @@ static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, zend_bool a /* {{{ 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) +PHPAPI int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array, ulong opt, char **sql TSRMLS_DC) { zval **val, *converted = NULL; char buf[256]; @@ -3879,18 +3753,16 @@ PHPAPI int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array, assert(pg_link != NULL); assert(table != NULL); assert(Z_TYPE_P(var_array) == IS_ARRAY); - assert(convert == 1 || convert == 0); - assert(async == 1 || async == 0); if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0) { return FAILURE; } /* convert input array if needed */ - if (convert) { + if (!(opt & PGSQL_DML_NO_CONV)) { MAKE_STD_ZVAL(converted); array_init(converted); - if (php_pgsql_convert(pg_link, table, var_array, converted TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert(pg_link, table, var_array, converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { goto cleanup; } var_array = converted; @@ -3945,34 +3817,49 @@ PHPAPI int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array, smart_str_appends(&querystr, ");"); smart_str_0(&querystr); - if (do_exec(&querystr, PGRES_COMMAND_OK, pg_link, async TSRMLS_CC) == 0) + if ((opt & (PGSQL_DML_EXEC|PGSQL_DML_ASYNC)) && + do_exec(&querystr, PGRES_COMMAND_OK, pg_link, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == 0) { ret = SUCCESS; - + } + else if (opt & PGSQL_DML_STRING) { + ret = SUCCESS; + } + cleanup: - if (convert) { + if (!(opt & PGSQL_DML_NO_CONV)) { zval_dtor(converted); FREE_ZVAL(converted); } - smart_str_free(&querystr); + if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { + *sql = querystr.c; + } + else { + smart_str_free(&querystr); + } return ret; } /* }}} */ -/* {{{ proto bool pg_insert(resource db, string table, array values[, bool convert[, bool async]]) +/* {{{ proto bool pg_insert(resource db, string table, array values[, int options]) Insert values (filed=>value) to table */ PHP_FUNCTION(pg_insert) { zval *pgsql_link, *values; - char *table; + char *table, *sql = NULL; ulong table_len; - zend_bool convert = 1, async = 1; + ulong option = PGSQL_DML_EXEC; PGconn *pg_link; int id = -1, argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|bb", - &pgsql_link, &table, &table_len, &values, &convert, &async) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "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)) { + php_error(E_WARNING, "%s() invalid option is spedified", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3980,9 +3867,12 @@ PHP_FUNCTION(pg_insert) php_error(E_NOTICE, "%s detected unhandled result(s) in connection", get_active_function_name(TSRMLS_C)); } - if (php_pgsql_insert(pg_link, table, values, convert, async TSRMLS_CC) == FAILURE) { + if (php_pgsql_insert(pg_link, table, values, option, &sql TSRMLS_CC) == FAILURE) { RETURN_FALSE; } + if (option & PGSQL_DML_STRING) { + RETURN_STRING(sql, 0); + } RETURN_TRUE; } /* }}} */ @@ -4034,7 +3924,7 @@ static inline int build_assignment_string(smart_str *querystr, HashTable *ht, co /* {{{ 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) +PHPAPI int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array, zval *ids_array, ulong opt, char **sql TSRMLS_DC) { zval *var_converted = NULL, *ids_converted = NULL; smart_str querystr = {0}; @@ -4044,24 +3934,23 @@ PHPAPI int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array, assert(table != NULL); assert(Z_TYPE_P(var_array) == IS_ARRAY); assert(Z_TYPE_P(ids_array) == IS_ARRAY); - assert(convert == 1 || convert == 0); - assert(async == 1 || async == 0); + assert(!(opt & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING))); if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0 || zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) { return FAILURE; } - if (convert) { + if (!(opt & PGSQL_DML_NO_CONV)) { MAKE_STD_ZVAL(var_converted); array_init(var_converted); - if (php_pgsql_convert(pg_link, table, var_array, var_converted TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert(pg_link, table, var_array, var_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == 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) { + if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { goto cleanup; } ids_array = ids_converted; @@ -4082,7 +3971,7 @@ PHPAPI int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array, smart_str_appendc(&querystr, ';'); smart_str_0(&querystr); - if (do_exec(&querystr, PGRES_COMMAND_OK, pg_link, async TSRMLS_CC) == 0) + if (do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt TSRMLS_CC) == 0) ret = SUCCESS; cleanup: @@ -4094,26 +3983,36 @@ cleanup: zval_dtor(ids_converted); FREE_ZVAL(ids_converted); } - smart_str_free(&querystr); + if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { + *sql = querystr.c; + } + else { + smart_str_free(&querystr); + } return ret; } /* }}} */ -/* {{{ proto bool pg_update(resource db, string table, array fields, array ids[, bool convert[, bool async]]) +/* {{{ proto bool pg_update(resource db, string table, array fields, array ids[, int options]) Update table using values (field=>value) and ids (id=>value) */ PHP_FUNCTION(pg_update) { zval *pgsql_link, *values, *ids; - char *table; + char *table, *sql = NULL; ulong table_len; - zend_bool convert = 1, async = 1; + ulong option = PGSQL_DML_EXEC; PGconn *pg_link; int id = -1, argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsaa|bb", - &pgsql_link, &table, &table_len, &values, &ids, &convert, &async) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "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)) { + php_error(E_WARNING, "%s() invalid option is spedified", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -4121,16 +4020,19 @@ PHP_FUNCTION(pg_update) php_error(E_NOTICE, "%s detected unhandled result(s) in connection", get_active_function_name(TSRMLS_C)); } - if (php_pgsql_update(pg_link, table, values, ids, convert, async TSRMLS_CC) == FAILURE) { + if (php_pgsql_update(pg_link, table, values, ids, option, &sql TSRMLS_CC) == FAILURE) { RETURN_FALSE; } + if (option & PGSQL_DML_STRING) { + RETURN_STRING(sql, 0); + } RETURN_TRUE; } /* }}} */ /* {{{ php_pgsql_delete */ -PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, zend_bool convert, zend_bool async TSRMLS_DC) +PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, ulong opt, char **sql TSRMLS_DC) { zval *ids_converted = NULL; smart_str querystr = {0}; @@ -4139,17 +4041,16 @@ PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, assert(pg_link != NULL); assert(table != NULL); assert(Z_TYPE_P(ids_array) == IS_ARRAY); - assert(convert == 1 || convert == 0); - assert(async == 1 || async == 0); - + assert(!(opt & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_EXEC|PGSQL_DML_STRING))); + if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) { return FAILURE; } - if (convert) { + if (!(opt & PGSQL_DML_NO_CONV)) { MAKE_STD_ZVAL(ids_converted); array_init(ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, ids_converted TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { goto cleanup; } ids_array = ids_converted; @@ -4165,34 +4066,43 @@ PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, smart_str_appendc(&querystr, ';'); smart_str_0(&querystr); - if (do_exec(&querystr, PGRES_TUPLES_OK, pg_link, async TSRMLS_CC) == 0) + if (do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt TSRMLS_CC) == 0) ret = SUCCESS; cleanup: - if (convert) { + if (!(opt & PGSQL_DML_NO_CONV)) { zval_dtor(ids_converted); FREE_ZVAL(ids_converted); } - smart_str_free(&querystr); + if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { + *sql = estrdup(querystr.c); + } + else { + smart_str_free(&querystr); + } return ret; } /* }}} */ -/* {{{ proto bool pg_delete(resource db, string table, array ids[, bool convert[, bool async]]) +/* {{{ proto bool pg_delete(resource db, string table, array ids[, int options]) Delete records has ids (id=>value) */ PHP_FUNCTION(pg_delete) { zval *pgsql_link, *ids; - char *table; - ulong table_len; - zend_bool convert = 1, async = 1; + char *table, *sql = NULL; + ulong table_len, option = PGSQL_DML_EXEC; PGconn *pg_link; int id = -1, argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|bb", - &pgsql_link, &table, &table_len, &ids, &convert, &async) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "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)) { + php_error(E_WARNING, "%s() invalid option is spedified", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -4200,9 +4110,12 @@ PHP_FUNCTION(pg_delete) php_error(E_NOTICE, "%s detected unhandled result(s) in connection", get_active_function_name(TSRMLS_C)); } - if (php_pgsql_delete(pg_link, table, ids, convert, async TSRMLS_CC) == FAILURE) { + if (php_pgsql_delete(pg_link, table, ids, option, &sql TSRMLS_CC) == FAILURE) { RETURN_FALSE; } + if (option & PGSQL_DML_STRING) { + RETURN_STRING(sql, 0); + } RETURN_TRUE; } /* }}} */ @@ -4251,7 +4164,7 @@ PHPAPI int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TSRMLS_DC /* {{{ php_pgsql_select */ -PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, zend_bool convert TSRMLS_DC) +PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, ulong opt, char **sql TSRMLS_DC) { zval *ids_converted = NULL; smart_str querystr = {0}; @@ -4262,16 +4175,16 @@ PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, assert(table != NULL); assert(Z_TYPE_P(ids_array) == IS_ARRAY); assert(Z_TYPE_P(ret_array) == IS_ARRAY); - assert(convert == 1 || convert == 0); - + assert(!(opt & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING))); + if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) { return FAILURE; } - if (convert) { + if (!(opt & PGSQL_DML_NO_CONV)) { MAKE_STD_ZVAL(ids_converted); array_init(ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, ids_converted TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) { goto cleanup; } ids_array = ids_converted; @@ -4297,30 +4210,39 @@ PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, } cleanup: - if (convert) { + if (!(opt & PGSQL_DML_NO_CONV)) { zval_dtor(ids_converted); FREE_ZVAL(ids_converted); } - smart_str_free(&querystr); + if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { + *sql = querystr.c; + } + else { + smart_str_free(&querystr); + } return ret; } /* }}} */ -/* {{{ proto array pg_select(resource db, string table, array ids[, bool convert]) +/* {{{ proto array pg_select(resource db, string table, array ids[, int options]) Select records that has ids (id=>value) */ PHP_FUNCTION(pg_select) { zval *pgsql_link, *ids; - char *table; - ulong table_len; - zend_bool convert = 1; + char *table, *sql = NULL; + ulong table_len, option = PGSQL_DML_EXEC; PGconn *pg_link; int id = -1, argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|b", - &pgsql_link, &table, &table_len, &ids, &convert) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "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)) { + php_error(E_WARNING, "%s() invalid option is spedified", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -4329,10 +4251,14 @@ PHP_FUNCTION(pg_select) get_active_function_name(TSRMLS_C)); } array_init(return_value); - if (php_pgsql_select(pg_link, table, ids, return_value, convert TSRMLS_CC) == FAILURE) { + if (php_pgsql_select(pg_link, table, ids, return_value, option, &sql TSRMLS_CC) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } + if (option & PGSQL_DML_STRING) { + zval_dtor(return_value); + RETURN_STRING(sql, 0); + } return; } /* }}} */ diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index caab8a3ad9..a1d547e6e8 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -131,15 +131,27 @@ PHP_FUNCTION(pg_update); PHP_FUNCTION(pg_delete); PHP_FUNCTION(pg_select); +/* php_pgsql_convert options */ +#define PGSQL_CONV_IGNORE_DEFAULT (1<<1) /* Do not use DEAFULT value by removing field from returned array */ +#define PGSQL_CONV_FORCE_NULL (1<<2) /* Convert to NULL if string is null string */ +#define PGSQL_CONV_IGNORE_NOT_NULL (1<<3) /* Ignore NOT NULL constraints */ +#define PGSQL_CONV_OPTS (PGSQL_CONV_IGNORE_DEFAULT|PGSQL_CONV_FORCE_NULL|PGSQL_CONV_IGNORE_NOT_NULL) +/* php_pgsql_insert/update/select/delete options */ +#define PGSQL_DML_NO_CONV (1<<8) /* Call php_pgsql_convert() */ +#define PGSQL_DML_EXEC (1<<9) /* Execute query */ +#define PGSQL_DML_ASYNC (1<<10) /* Do async query */ +#define PGSQL_DML_STRING (1<<11) /* Return query string */ + +/* exported functions */ PHPAPI int php_pgsql_metadata(PGconn *pg_link, const char *table_name, zval *meta TSRMLS_DC); -PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result TSRMLS_DC); -PHPAPI int php_pgsql_insert(PGconn *pg_link, const char *table, zval *values, zend_bool convert, zend_bool async TSRMLS_DC); -PHPAPI int php_pgsql_update(PGconn *pg_link, const char *table, zval *values, zval *ids, zend_bool convert, zend_bool async TSRMLS_DC); -PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids, zend_bool convert, zend_bool async TSRMLS_DC); -PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids, zval *ret_array, zend_bool convert TSRMLS_DC); +PHPAPI int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result, ulong opt TSRMLS_DC); +PHPAPI int php_pgsql_insert(PGconn *pg_link, const char *table, zval *values, ulong opt, char **sql TSRMLS_DC); +PHPAPI int php_pgsql_update(PGconn *pg_link, const char *table, zval *values, zval *ids, ulong opt , char **sql TSRMLS_DC); +PHPAPI int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids, ulong opt, char **sql TSRMLS_DC); +PHPAPI int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids, zval *ret_array, ulong opt, char **sql TSRMLS_DC); +/* internal functions */ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent); -/* static int php_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS); */ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type); static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type); static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC); diff --git a/ext/pgsql/tests/12pg_insert.phpt b/ext/pgsql/tests/12pg_insert.phpt index 8070df1539..104b6fe662 100644 --- a/ext/pgsql/tests/12pg_insert.phpt +++ b/ext/pgsql/tests/12pg_insert.phpt @@ -7,4 +7,5 @@ PostgreSQL pg_insert() include("pg_insert.inc"); ?> --EXPECT-- +INSERT INTO php_pgsql_test (num,str,bin) VALUES (1234,'AAA','BBB'); Ok diff --git a/ext/pgsql/tests/13pg_select.phpt b/ext/pgsql/tests/13pg_select.phpt index 7c61436089..43c94c037f 100644 --- a/ext/pgsql/tests/13pg_select.phpt +++ b/ext/pgsql/tests/13pg_select.phpt @@ -18,4 +18,5 @@ array(1) { string(3) "BBB" } } +SELECT * FROM php_pgsql_test WHERE num=1234; Ok diff --git a/ext/pgsql/tests/14pg_update.phpt b/ext/pgsql/tests/14pg_update.phpt index da78eeac92..7dd4dd2d95 100644 --- a/ext/pgsql/tests/14pg_update.phpt +++ b/ext/pgsql/tests/14pg_update.phpt @@ -7,4 +7,5 @@ PostgreSQL pg_update() include("pg_update.inc"); ?> --EXPECT-- +UPDATE php_pgsql_test SET num=1234,str='ABC',bin='XYZ' WHERE num=1234; Ok diff --git a/ext/pgsql/tests/pg_delete.inc b/ext/pgsql/tests/pg_delete.inc index 33e001081b..33ba80e727 100644 --- a/ext/pgsql/tests/pg_delete.inc +++ b/ext/pgsql/tests/pg_delete.inc @@ -7,7 +7,7 @@ $db = pg_connect($conn_str); $fields = array('num'=>'1234', 'str'=>'XXX', 'bin'=>'YYY'); $ids = array('num'=>'1234'); -if (!pg_delete($db, $table_name, $ids, 1)) { +if (!pg_delete($db, $table_name, $ids)) { echo "Error\n"; } else { diff --git a/ext/pgsql/tests/pg_insert.inc b/ext/pgsql/tests/pg_insert.inc index bfb2e90e83..e0777a215e 100644 --- a/ext/pgsql/tests/pg_insert.inc +++ b/ext/pgsql/tests/pg_insert.inc @@ -4,13 +4,10 @@ error_reporting(E_ALL); include 'config.inc'; $db = pg_connect($conn_str); - $fields = array('num'=>'1234', 'str'=>'AAA', 'bin'=>'BBB'); -if (!pg_insert($db, $table_name, $fields, 1, 0)) { - echo "Error\n"; -} -else { - echo "Ok\n"; -} +pg_insert($db, $table_name, $fields) or print "Error in test 1\n"; +echo pg_insert($db, $table_name, $fields, PGSQL_DML_STRING)."\n"; + +echo "Ok\n"; ?> diff --git a/ext/pgsql/tests/pg_select.inc b/ext/pgsql/tests/pg_select.inc index 04ca501deb..4d251bc992 100644 --- a/ext/pgsql/tests/pg_select.inc +++ b/ext/pgsql/tests/pg_select.inc @@ -4,15 +4,12 @@ error_reporting(E_ALL); include 'config.inc'; $db = pg_connect($conn_str); - -$fields = array('num'=>'1234', 'str'=>'XXX', 'bin'=>'YYY'); +$fields = array('num'=>'1234', 'str'=>'ABC', 'bin'=>'XYZ'); $ids = array('num'=>'1234'); -if (!($res = pg_select($db, $table_name, $ids, 1))) { - echo "Error\n"; -} -else { - var_dump($res); - echo "Ok\n"; -} + +$res = pg_select($db, $table_name, $ids) or print "Error\n"; +var_dump($res); +echo pg_select($db, $table_name, $ids, PGSQL_DML_STRING)."\n"; +echo "Ok\n"; ?> \ No newline at end of file diff --git a/ext/pgsql/tests/pg_update.inc b/ext/pgsql/tests/pg_update.inc index 6501c09af5..8fc8bb168b 100644 --- a/ext/pgsql/tests/pg_update.inc +++ b/ext/pgsql/tests/pg_update.inc @@ -4,14 +4,12 @@ error_reporting(E_ALL); include 'config.inc'; $db = pg_connect($conn_str); - -$fields = array('num'=>'1234', 'str'=>'XXX', 'bin'=>'YYY'); +$fields = array('num'=>'1234', 'str'=>'ABC', 'bin'=>'XYZ'); $ids = array('num'=>'1234'); -if (!pg_update($db, $table_name, $fields, $ids, 1, 0)) { - echo "Error\n"; -} -else { - echo "Ok\n"; -} + +pg_update($db, $table_name, $fields, $ids) or print "Error in test 1\n"; +echo pg_update($db, $table_name, $fields, $ids, PGSQL_DML_STRING)."\n"; + +echo "Ok\n"; ?>