X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-pq;a=blobdiff_plain;f=src%2Fphp_pqtypes.c;h=8f4b53d697af6e1e36fee0a4b205864489549193;hp=fc9a16e19a4ec8cc6451104e90a8c1b1f7950c63;hb=da7b5981c5ae28504434c492d468913645111d66;hpb=9f5cecf26bd70a92ed013f31afec59e272623ac1 diff --git a/src/php_pqtypes.c b/src/php_pqtypes.c index fc9a16e..8f4b53d 100644 --- a/src/php_pqtypes.c +++ b/src/php_pqtypes.c @@ -136,6 +136,7 @@ static int php_pqtypes_object_has_dimension(zval *object, zval *member, int chec return Z_TYPE_PP(data) != IS_NULL; } efree(key_str); + key_str = NULL; } else { if (SUCCESS == zend_hash_index_find(&obj->intern->types, index, (void *) &data)) { return Z_TYPE_PP(data) != IS_NULL; @@ -172,9 +173,10 @@ static zval *php_pqtypes_object_read_dimension(zval *object, zval *member, int t return *data; } } - if (key_str) { - efree(key_str); - } + } + + if (key_str) { + efree(key_str); } return NULL; @@ -205,7 +207,7 @@ static PHP_METHOD(pqtypes, __construct) { obj->intern = ecalloc(1, sizeof(*obj->intern)); obj->intern->conn = conn_obj; php_pq_object_addref(conn_obj TSRMLS_CC); - zend_hash_init(&obj->intern->types, 300, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(&obj->intern->types, 512, NULL, ZVAL_PTR_DTOR, 0); if (znsp) { zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", &retval, znsp); @@ -225,7 +227,32 @@ static PHP_METHOD(pqtypes, __construct) { "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \ "where typisdefined " \ "and typrelid=0" -#define PHP_PQ_OID_TEXT 25 +#ifndef PHP_PQ_OID_TEXT +# define PHP_PQ_OID_TEXT 25 +#endif + +static int apply_nsp(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +{ + zval **zp = p; + unsigned pcount, tcount; + php_pq_params_t *params = va_arg(argv, php_pq_params_t *); + smart_str *str = va_arg(argv, smart_str *); + + tcount = php_pq_params_add_type_oid(params, PHP_PQ_OID_TEXT); + pcount = php_pq_params_add_param(params, *zp); + + if (tcount != pcount) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Param/Type count mismatch"); + return ZEND_HASH_APPLY_STOP; + } + if (pcount > 1) { + smart_str_appendc(str, ','); + } + smart_str_appendc(str, '$'); + smart_str_append_unsigned(str, pcount); + + return ZEND_HASH_APPLY_KEEP; +} ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh, 0, 0, 0) ZEND_ARG_ARRAY_INFO(0, namespaces, 1) @@ -250,33 +277,18 @@ static PHP_METHOD(pqtypes, refresh) { if (!nsp || !zend_hash_num_elements(nsp)) { res = PQexec(obj->intern->conn->intern->conn, PHP_PQ_TYPES_QUERY " and nspname in ('public', 'pg_catalog')"); } else { - int i, count; - Oid *oids; - char **params = NULL; - HashTable zdtor; smart_str str = {0}; + php_pq_params_t *params = php_pq_params_init(&obj->intern->conn->intern->converters, NULL, NULL TSRMLS_CC); smart_str_appends(&str, PHP_PQ_TYPES_QUERY " and nspname in("); - zend_hash_init(&zdtor, 0, NULL, ZVAL_PTR_DTOR, 0); - count = php_pq_params_to_array(nsp, ¶ms, &zdtor TSRMLS_CC); - oids = ecalloc(count + 1, sizeof(*oids)); - for (i = 0; i < count; ++i) { - oids[i] = PHP_PQ_OID_TEXT; - if (i) { - smart_str_appendc(&str, ','); - } - smart_str_appendc(&str, '$'); - smart_str_append_unsigned(&str, i+1); - } + zend_hash_apply_with_arguments(nsp TSRMLS_CC, apply_nsp, 2, params, &str); smart_str_appendc(&str, ')'); smart_str_0(&str); - res = PQexecParams(obj->intern->conn->intern->conn, str.c, count, oids, (const char *const*) params, NULL, NULL, 0); + res = PQexecParams(obj->intern->conn->intern->conn, str.c, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0); smart_str_free(&str); - efree(oids); - efree(params); - zend_hash_destroy(&zdtor); + php_pq_params_free(¶ms); } if (!res) { @@ -293,7 +305,7 @@ static PHP_METHOD(pqtypes, refresh) { Z_ADDREF_P(row); zend_hash_index_update(&obj->intern->types, oid, (void *) &row, sizeof(zval *), NULL); - zend_hash_add(&obj->intern->types, name, strlen(name) + 1, (void *) &row, sizeof(zval *), NULL); + zend_hash_update(&obj->intern->types, name, strlen(name) + 1, (void *) &row, sizeof(zval *), NULL); } } @@ -310,6 +322,12 @@ static zend_function_entry php_pqtypes_methods[] = { {0} }; +PHP_MSHUTDOWN_FUNCTION(pqtypes) +{ + zend_hash_destroy(&php_pqtypes_object_prophandlers); + return SUCCESS; +} + PHP_MINIT_FUNCTION(pqtypes) { zend_class_entry ce = {0}; @@ -319,11 +337,17 @@ PHP_MINIT_FUNCTION(pqtypes) php_pqtypes_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); php_pqtypes_class_entry->create_object = php_pqtypes_create_object; + /* + zend_class_implements(php_pqtypes_class_entry TSRMLS_CC, 1, zend_ce_arrayaccess); + */ + memcpy(&php_pqtypes_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); php_pqtypes_object_handlers.read_property = php_pq_object_read_prop; php_pqtypes_object_handlers.write_property = php_pq_object_write_prop; php_pqtypes_object_handlers.clone_obj = NULL; php_pqtypes_object_handlers.get_property_ptr_ptr = NULL; + php_pqtypes_object_handlers.get_gc = NULL; + php_pqtypes_object_handlers.get_properties = php_pq_object_properties; php_pqtypes_object_handlers.get_debug_info = php_pq_object_debug_info; php_pqtypes_object_handlers.has_dimension = php_pqtypes_object_has_dimension; php_pqtypes_object_handlers.read_dimension = php_pqtypes_object_read_dimension; @@ -336,6 +360,10 @@ 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); +# 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" + return SUCCESS; }