Improve FR #48532 implementation (Allow pg_fetch_all() to index numerically).

Made result type option be consistent with pg_fetch_row().
This commit is contained in:
Yasuo Ohgaki 2015-12-18 15:50:57 +09:00
parent 7517a62428
commit 283cbebe5b
3 changed files with 46 additions and 45 deletions

View File

@ -52,9 +52,9 @@ PHP 7.1 UPGRADE NOTES
PGSQL_NOTICE_CLEAR - Remove all stored notices PGSQL_NOTICE_CLEAR - Remove all stored notices
It returns empty string or array on successful PGSQL_NOTICE_LAST/ALL calls. It returns empty string or array on successful PGSQL_NOTICE_LAST/ALL calls.
It returned FALSE for empty notice previously. It returned FALSE for empty notice previously.
- pg_fetch_all() accepts optional 2nd bool parameter to get numerically indexed - pg_fetch_all() accepts 2nd optional result type parameter like
rows. pg_fetch_row().
- pg_select() accepts PGSQL_FETCH_NUM option to get numerically indexed rows. - pg_select() accepts 4th optional result type parameter like pg_fetch_row().
======================================== ========================================
6. New Functions 6. New Functions

View File

@ -281,7 +281,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 1) ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 1)
ZEND_ARG_INFO(0, result) ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, numeric_index) ZEND_ARG_INFO(0, result_type)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all_columns, 0, 0, 1) ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all_columns, 0, 0, 1)
@ -588,6 +588,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_select, 0, 0, 3)
ZEND_ARG_INFO(0, table) ZEND_ARG_INFO(0, table)
ZEND_ARG_INFO(0, ids) ZEND_ARG_INFO(0, ids)
ZEND_ARG_INFO(0, options) ZEND_ARG_INFO(0, options)
ZEND_ARG_INFO(0, result_type)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
/* }}} */ /* }}} */
@ -1204,7 +1205,6 @@ PHP_MINIT_FUNCTION(pgsql)
REGISTER_LONG_CONSTANT("PGSQL_DML_EXEC", PGSQL_DML_EXEC, 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_ASYNC", PGSQL_DML_ASYNC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PGSQL_FETCH_NUM", PGSQL_FETCH_NUM, CONST_CS | CONST_PERSISTENT);
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */
@ -2904,26 +2904,31 @@ PHP_FUNCTION(pg_fetch_object)
} }
/* }}} */ /* }}} */
/* {{{ proto array pg_fetch_all(resource result [, bool numeric_index]) /* {{{ proto array pg_fetch_all(resource result [, int result_type])
Fetch all rows into array */ Fetch all rows into array */
PHP_FUNCTION(pg_fetch_all) PHP_FUNCTION(pg_fetch_all)
{ {
zval *result; zval *result;
zend_bool numeric_index = 0; long result_type = PGSQL_ASSOC;
PGresult *pgsql_result; PGresult *pgsql_result;
pgsql_result_handle *pg_result; pgsql_result_handle *pg_result;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &result, &numeric_index) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &result, &result_type) == FAILURE) {
return; return;
} }
if (!(result_type & PGSQL_BOTH)) {
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) { if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) {
RETURN_FALSE; RETURN_FALSE;
} }
pgsql_result = pg_result->result; pgsql_result = pg_result->result;
array_init(return_value); array_init(return_value);
if (php_pgsql_result2array(pgsql_result, return_value, numeric_index) == FAILURE) { if (php_pgsql_result2array(pgsql_result, return_value, result_type) == FAILURE) {
zval_dtor(return_value); zval_dtor(return_value);
RETURN_FALSE; RETURN_FALSE;
} }
@ -7037,7 +7042,7 @@ PHP_FUNCTION(pg_delete)
/* {{{ php_pgsql_result2array /* {{{ php_pgsql_result2array
*/ */
PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, zend_bool numeric_index) PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, long result_type)
{ {
zval row; zval row;
char *field_name; char *field_name;
@ -7049,39 +7054,31 @@ PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, z
if ((pg_numrows = PQntuples(pg_result)) <= 0) { if ((pg_numrows = PQntuples(pg_result)) <= 0) {
return FAILURE; return FAILURE;
} }
if (numeric_index) { for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
for (pg_row = 0; pg_row < pg_numrows; pg_row++) { array_init(&row);
array_init(&row); for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) { field_name = PQfname(pg_result, i);
if (PQgetisnull(pg_result, pg_row, i)) { if (PQgetisnull(pg_result, pg_row, i)) {
if (result_type & PGSQL_ASSOC) {
add_assoc_null(&row, field_name);
}
if (result_type & PGSQL_NUM) {
add_next_index_null(&row); add_next_index_null(&row);
} else { }
char *element = PQgetvalue(pg_result, pg_row, i); } else {
if (element) { char *element = PQgetvalue(pg_result, pg_row, i);
const size_t element_len = strlen(element); if (element) {
const size_t element_len = strlen(element);
if (result_type & PGSQL_ASSOC) {
add_assoc_stringl(&row, field_name, element, element_len);
}
if (result_type & PGSQL_NUM) {
add_next_index_stringl(&row, element, element_len); add_next_index_stringl(&row, element, element_len);
} }
} }
} }
add_index_zval(ret_array, pg_row, &row);
}
} else {
for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
array_init(&row);
for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
field_name = PQfname(pg_result, i);
if (PQgetisnull(pg_result, pg_row, i)) {
add_assoc_null(&row, field_name);
} else {
char *element = PQgetvalue(pg_result, pg_row, i);
if (element) {
const size_t element_len = strlen(element);
add_assoc_stringl(&row, field_name, element, element_len);
}
}
}
add_index_zval(ret_array, pg_row, &row);
} }
add_index_zval(ret_array, pg_row, &row);
} }
return SUCCESS; return SUCCESS;
} }
@ -7089,7 +7086,7 @@ PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, z
/* {{{ php_pgsql_select /* {{{ php_pgsql_select
*/ */
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) PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, zend_ulong opt, long result_type, zend_string **sql)
{ {
zval ids_converted; zval ids_converted;
smart_str querystr = {0}; smart_str querystr = {0};
@ -7127,7 +7124,7 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids
pg_result = PQexec(pg_link, ZSTR_VAL(querystr.s)); pg_result = PQexec(pg_link, ZSTR_VAL(querystr.s));
if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) { if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) {
ret = php_pgsql_result2array(pg_result, ret_array, (opt & PGSQL_FETCH_NUM)); ret = php_pgsql_result2array(pg_result, ret_array, result_type);
} else { } else {
php_error_docref(NULL, E_NOTICE, "Failed to execute '%s'", ZSTR_VAL(querystr.s)); php_error_docref(NULL, E_NOTICE, "Failed to execute '%s'", ZSTR_VAL(querystr.s));
} }
@ -7145,7 +7142,7 @@ cleanup:
} }
/* }}} */ /* }}} */
/* {{{ proto mixed pg_select(resource db, string table, array ids[, int options]) /* {{{ proto mixed pg_select(resource db, string table, array ids[, int options [, int result_type])
Select records that has ids (id=>value) */ Select records that has ids (id=>value) */
PHP_FUNCTION(pg_select) PHP_FUNCTION(pg_select)
{ {
@ -7153,18 +7150,23 @@ PHP_FUNCTION(pg_select)
char *table; char *table;
size_t table_len; size_t table_len;
zend_ulong option = PGSQL_DML_EXEC; zend_ulong option = PGSQL_DML_EXEC;
long result_type = PGSQL_ASSOC;
PGconn *pg_link; PGconn *pg_link;
zend_string *sql = NULL; zend_string *sql = NULL;
int argc = ZEND_NUM_ARGS(); int argc = ZEND_NUM_ARGS();
if (zend_parse_parameters(argc, "rsa|l", if (zend_parse_parameters(argc, "rsa|l",
&pgsql_link, &table, &table_len, &ids, &option) == FAILURE) { &pgsql_link, &table, &table_len, &ids, &option, &result_type) == FAILURE) {
return; return;
} }
if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { 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, E_WARNING, "Invalid option is specified"); php_error_docref(NULL, E_WARNING, "Invalid option is specified");
RETURN_FALSE; RETURN_FALSE;
} }
if (!(result_type & PGSQL_BOTH)) {
php_error_docref(NULL, E_WARNING, "Invalid result type");
RETURN_FALSE;
}
if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) {
RETURN_FALSE; RETURN_FALSE;
@ -7174,7 +7176,7 @@ PHP_FUNCTION(pg_select)
php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection");
} }
array_init(return_value); array_init(return_value);
if (php_pgsql_select(pg_link, table, ids, return_value, option, &sql) == FAILURE) { if (php_pgsql_select(pg_link, table, ids, return_value, option, result_type, &sql) == FAILURE) {
zval_ptr_dtor(return_value); zval_ptr_dtor(return_value);
RETURN_FALSE; RETURN_FALSE;
} }

View File

@ -210,7 +210,6 @@ PHP_FUNCTION(pg_select);
#define PGSQL_DML_ASYNC (1<<10) /* Do async query */ #define PGSQL_DML_ASYNC (1<<10) /* Do async query */
#define PGSQL_DML_STRING (1<<11) /* Return query string */ #define PGSQL_DML_STRING (1<<11) /* Return query string */
#define PGSQL_DML_ESCAPE (1<<12) /* No convert, but escape only */ #define PGSQL_DML_ESCAPE (1<<12) /* No convert, but escape only */
#define PGSQL_FETCH_NUM (1<<13) /* Fetch result with numeric index */
/* exported functions */ /* exported functions */
PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended); PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended);
@ -218,8 +217,8 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *values, zend_ulong opt, zend_string **sql); PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *values, zend_ulong opt, zend_string **sql);
PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *values, zval *ids, zend_ulong opt , zend_string **sql); PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *values, zval *ids, zend_ulong opt , zend_string **sql);
PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids, zend_ulong opt, zend_string **sql); PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids, zend_ulong opt, zend_string **sql);
PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids, zval *ret_array, zend_ulong opt, zend_string **sql ); PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids, zval *ret_array, zend_ulong opt, long fetch_option, zend_string **sql );
PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, zend_bool numeric_index); PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, long fetch_option);
/* internal functions */ /* internal functions */
static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent); static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent);