From 359b3471d6ed843d8ecf9d5fb0b85f06af446800 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 12 Sep 2014 16:42:03 +0200 Subject: [PATCH] refactor auto conversion add default connection property, for pq\Result->$autoConvert: pq\Connection->$defaultAutoConvert add autp conversion constants: * pq\Result::CONV_BOOL * pq\Result::CONV_INT * pq\Result::CONV_FLOAT * pq\Result::CONV_SCALAR (includes all previous) * pq\Result::CONV_ARRAY * pq\Result::CONV_DATETIME * pq\Result::CONV_ALL (includes all, default) --- config.m4 | 23 ----------------- package.xml | 1 + src/php_pq_misc.h | 3 ++- src/php_pq_params.c | 10 ++------ src/php_pqconn.c | 39 +++++++++++++++++++++++++++- src/php_pqconn.h | 1 + src/php_pqres.c | 62 +++++++++++++++++++++++++++++++++++---------- src/php_pqres.h | 11 +++++--- src/php_pqtypes.c | 5 ---- 9 files changed, 100 insertions(+), 55 deletions(-) diff --git a/config.m4 b/config.m4 index cb35a05..ed20d56 100644 --- a/config.m4 +++ b/config.m4 @@ -1,7 +1,5 @@ PHP_ARG_WITH(pq, [whether to enable libpq (PostgreSQL) support], [ --with-pq[=DIR] Include libpq support]) -PHP_ARG_WITH(pq-postgresql, [where to find PostgreSQL server headers], -[ --with-pq-postgresql[=DIR] PQ: Define some standard type OIDs from catalog/pg_type.h], $PHP_PQ, no) if test "$PHP_PQ" != "no"; then SEARCH_PATH="/usr/local /usr /opt" @@ -57,26 +55,5 @@ if test "$PHP_PQ" != "no"; then PHP_ADD_INCLUDE($ext_srcdir/src) PHP_ADD_EXTENSION_DEP(pq, raphf) - if test "$PHP_PQ_POSTGRESQL" != "no"; then - if test "$PHP_PQ_POSTGRESQL" != "yes"; then - SEARCH_PATH="$PHP_PQ_POSTGRESQL $SEARCH_PATH" - fi - CATALOG_PATH="" - for i in $SEARCH_PATH; do - CATALOG_PATH="$i/include/server/catalog/pg_type.h $CATALOG_PATH" - CATALOG_PATH="$i/include/postgresql/server/catalog/pg_type.h $CATALOG_PATH" - done - for CATALOG in $CATALOG_PATH; do - AC_MSG_CHECKING(for $CATALOG) - if test -f "$CATALOG"; then - AC_MSG_RESULT(yep) - AC_PROG_AWK() - $AWK -f $ext_srcdir/php_pq_type.awk < "$CATALOG" > $ext_srcdir/php_pq_type.h - AC_DEFINE(HAVE_PHP_PQ_TYPE_H, 1, Have PostgreSQL type OID defs) - break - fi - AC_MSG_RESULT(nope) - done - fi fi diff --git a/package.xml b/package.xml index 808e5b9..079796d 100644 --- a/package.xml +++ b/package.xml @@ -52,6 +52,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + diff --git a/src/php_pq_misc.h b/src/php_pq_misc.h index d515d29..196b35c 100644 --- a/src/php_pq_misc.h +++ b/src/php_pq_misc.h @@ -15,10 +15,11 @@ #define PHP_PQ_ERROR_H #include -#include "php_pqres.h" typedef int STATUS; /* SUCCESS/FAILURE */ +#include "php_pqres.h" + /* TSRM morony */ #if PHP_VERSION_ID >= 50700 # define z_is_true(z) zend_is_true(z TSRMLS_CC) diff --git a/src/php_pq_params.c b/src/php_pq_params.c index f753ad8..149da75 100644 --- a/src/php_pq_params.c +++ b/src/php_pq_params.c @@ -24,6 +24,8 @@ #include "php_pq.h" #include "php_pq_params.h" +#undef PHP_PQ_TYPE +#include "php_pq_type.h" void php_pq_params_set_type_conv(php_pq_params_t *p, HashTable *conv) { @@ -192,14 +194,6 @@ static void php_pq_params_set_param(php_pq_params_t *p, unsigned index, zval **z case IS_ARRAY: { - -#if HAVE_PHP_PQ_TYPE_H -# undef PHP_PQ_TYPE -# include "php_pq_type.h" -#else -# define PHP_PQ_TYPE_OF_ARRAY(oid) 0 -#endif - zval *tmp; MAKE_STD_ZVAL(tmp); Z_TYPE_P(tmp) = IS_STRING; diff --git a/src/php_pqconn.c b/src/php_pqconn.c index 4378404..2588d42 100644 --- a/src/php_pqconn.c +++ b/src/php_pqconn.c @@ -435,6 +435,36 @@ static void php_pqconn_object_write_def_txn_deferrable(zval *object, void *o, zv obj->intern->default_txn_deferrable = zend_is_true(value); } +static void php_pqconn_object_read_def_auto_conv(zval *object, void *o, zval *return_value TSRMLS_DC) +{ + php_pqconn_object_t *obj = o; + + RETVAL_LONG(obj->intern->default_auto_convert); +} +static void php_pqconn_object_write_def_auto_conv(zval*object, void *o, zval *value TSRMLS_DC) +{ + php_pqconn_object_t *obj = o; + zval *zac = value; + + if (Z_TYPE_P(zac) != IS_LONG) { + if (Z_REFCOUNT_P(zac) > 1) { + zval *tmp; + MAKE_STD_ZVAL(tmp); + ZVAL_ZVAL(tmp, zac, 1, 0); + convert_to_long(tmp); + zac = tmp; + } else { + convert_to_long_ex(&zac); + } + } + + obj->intern->default_auto_convert = Z_LVAL_P(zac) & 0xff; + + if (zac != value) { + zval_ptr_dtor(&zac); + } +} + static STATUS php_pqconn_update_socket(zval *this_ptr, php_pqconn_object_t *obj TSRMLS_DC) { zval *zsocket, zmember; @@ -590,7 +620,6 @@ static void php_pqconn_retire(php_persistent_handle_factory_t *f, void **handle zend_hash_apply_with_arguments(&evdata->obj->intern->listeners TSRMLS_CC, apply_unlisten, 1, evdata->obj); /* release instance data */ - //memset(evdata, 0, sizeof(*evdata)); efree(evdata); } } @@ -621,6 +650,8 @@ static PHP_METHOD(pqconn, __construct) { obj->intern = ecalloc(1, sizeof(*obj->intern)); + obj->intern->default_auto_convert = PHP_PQRES_CONV_ALL; + zend_hash_init(&obj->intern->listeners, 0, NULL, (dtor_func_t) zend_hash_destroy, 0); zend_hash_init(&obj->intern->converters, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&obj->intern->eventhandlers, 0, NULL, (dtor_func_t) zend_hash_destroy, 0); @@ -2020,6 +2051,12 @@ PHP_MINIT_FUNCTION(pqconn) zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable"), (void *) &ph, sizeof(ph), NULL); ph.write = NULL; + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqconn_object_read_def_auto_conv; + ph.write = php_pqconn_object_write_def_auto_conv; + zend_hash_add(&php_pqconn_object_prophandlers, "defaultAutoConvert", sizeof("defaultAutoConvert"), (void *) &ph, sizeof(ph), NULL); + ph.write = NULL; + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC); zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC); zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC); diff --git a/src/php_pqconn.h b/src/php_pqconn.h index 1a283d0..4f4b56c 100644 --- a/src/php_pqconn.h +++ b/src/php_pqconn.h @@ -34,6 +34,7 @@ typedef struct php_pqconn { unsigned default_txn_isolation:2; unsigned default_txn_readonly:1; unsigned default_txn_deferrable:1; + unsigned default_auto_convert:16; } php_pqconn_t; typedef struct php_pqconn_object { diff --git a/src/php_pqres.c b/src/php_pqres.c index cbaf933..8233d66 100644 --- a/src/php_pqres.c +++ b/src/php_pqres.c @@ -24,6 +24,8 @@ #include "php_pq_object.h" #include "php_pqexc.h" #include "php_pqres.h" +#undef PHP_PQ_TYPE +#include "php_pq_type.h" zend_class_entry *php_pqres_class_entry; static zend_object_handlers php_pqres_object_handlers; @@ -109,9 +111,6 @@ zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRM } switch (typ) { -#ifdef HAVE_PHP_PQ_TYPE_H -# undef PHP_PQ_TYPE -# include "php_pq_type.h" case PHP_PQ_OID_BOOL: if (!(res->auto_convert & PHP_PQRES_CONV_BOOL)) { goto noconversion; @@ -179,15 +178,6 @@ zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRM ZVAL_STRINGL(zv, val, len, 1); } break; -#else - case 16: /* BOOL */ - if (res->auto_convert & PHP_PQRES_CONV_BOOL) { - ZVAL_BOOL(zv, *val == 't'); - break; - } - default: - ZVAL_STRINGL(zv, val, len, 1); -#endif } return zv; @@ -233,7 +223,7 @@ zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch } else { zval *zv; - zv = php_pq_typed_zval(&res_obj->intern->converters, PQgetvalue(res, row, c), PQgetlength(res, row, c), PQftype(res, c) TSRMLS_CC); + zv = php_pqres_typed_zval(res_obj->intern, PQgetvalue(res, row, c), PQgetlength(res, row, c), PQftype(res, c) TSRMLS_CC); switch (fetch_type) { case PHP_PQRES_FETCH_OBJECT: @@ -365,6 +355,7 @@ void php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *conn_obj, zend_hash_init(&r->converters, 0, 0, ZVAL_PTR_DTOR, 0); zend_hash_copy(&r->converters, &conn_obj->intern->converters, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + r->auto_convert = conn_obj->intern->default_auto_convert; r->default_fetch_type = conn_obj->intern->default_fetch_type; php_pqres_create_object_ex(php_pqres_class_entry, r, &obj TSRMLS_CC); @@ -517,6 +508,37 @@ static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value } } +static void php_pqres_object_read_auto_conv(zval *object, void *o, zval *return_value TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + + RETVAL_LONG(obj->intern->auto_convert); +} + +static void php_pqres_object_write_auto_conv(zval *object, void *o, zval *value TSRMLS_DC) +{ + php_pqres_object_t *obj = o; + zval *zauto_conv = value; + + if (Z_TYPE_P(value) != IS_LONG) { + if (Z_REFCOUNT_P(value) > 1) { + zval *tmp; + MAKE_STD_ZVAL(tmp); + ZVAL_ZVAL(tmp, zauto_conv, 1, 0); + convert_to_long(tmp); + zauto_conv = tmp; + } else { + convert_to_long_ex(&zauto_conv); + } + } + + obj->intern->auto_convert = Z_LVAL_P(zauto_conv); + + if (zauto_conv != value) { + zval_ptr_dtor(&zauto_conv); + } +} + static STATUS php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC) { STATUS rv; @@ -1067,6 +1089,12 @@ PHP_MINIT_FUNCTION(pqres) zend_hash_add(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType"), (void *) &ph, sizeof(ph), NULL); ph.write = NULL; + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.read = php_pqres_object_read_auto_conv; + ph.write = php_pqres_object_write_auto_conv; + zend_hash_add(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert"), (void *) &ph, sizeof(ph), NULL); + ph.write = NULL; + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC); @@ -1082,6 +1110,14 @@ PHP_MINIT_FUNCTION(pqres) zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL TSRMLS_CC); + return SUCCESS; } diff --git a/src/php_pqres.h b/src/php_pqres.h index 507c3a4..4afff39 100644 --- a/src/php_pqres.h +++ b/src/php_pqres.h @@ -15,6 +15,7 @@ #define PHP_PQRES_H #include "php_pqconn.h" + typedef enum php_pqres_fetch { PHP_PQRES_FETCH_ARRAY, PHP_PQRES_FETCH_ASSOC, @@ -24,8 +25,10 @@ typedef enum php_pqres_fetch { #define PHP_PQRES_CONV_BOOL 0x01 #define PHP_PQRES_CONV_INT 0x02 #define PHP_PQRES_CONV_FLOAT 0x04 -#define PHP_PQRES_CONV_ARRAY 0x08 -#define PHP_PQRES_CONV_DATETIME 0x10 +#define PHP_PQRES_CONV_SCALAR 0x0f +#define PHP_PQRES_CONV_ARRAY 0x10 +#define PHP_PQRES_CONV_DATETIME 0x20 +#define PHP_PQRES_CONV_ALL 0xff typedef struct php_pqres_iterator { zend_object_iterator zi; @@ -39,8 +42,8 @@ typedef struct php_pqres { php_pqres_iterator_t *iter; HashTable bound; HashTable converters; - unsigned default_fetch_type:2; - unsigned auto_convert:6; + unsigned auto_convert; + php_pqres_fetch_t default_fetch_type; } php_pqres_t; typedef struct php_pqres_object { diff --git a/src/php_pqtypes.c b/src/php_pqtypes.c index e5733da..ff9c10d 100644 --- a/src/php_pqtypes.c +++ b/src/php_pqtypes.c @@ -356,14 +356,9 @@ PHP_MINIT_FUNCTION(pqtypes) ph.read = php_pqtypes_object_read_connection; zend_hash_add(&php_pqtypes_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); -#ifdef HAVE_PHP_PQ_TYPE_H # undef PHP_PQ_TYPE # define PHP_PQ_TYPE(name, oid) zend_declare_class_constant_long(php_pqtypes_class_entry, ZEND_STRL(name), oid TSRMLS_CC); # include "php_pq_type.h" - zend_declare_class_constant_bool(php_pqtypes_class_entry, ZEND_STRL("DEFINED"), 1 TSRMLS_CC); -#else - zend_declare_class_constant_bool(php_pqtypes_class_entry, ZEND_STRL("DEFINED"), 0 TSRMLS_CC); -#endif return SUCCESS; } -- 2.30.2