X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-pq;a=blobdiff_plain;f=src%2Fphp_pqstm.c;h=4b71038a63f10167c2266b5d2fb966f834c75707;hp=83496df4f8b75d1ad2b1719e3ff6200cd9658537;hb=94be2af75078af30116718bb2df201d9e5a47e5b;hpb=6c838021951716e5b37a0c891cd40c669268de8c diff --git a/src/php_pqstm.c b/src/php_pqstm.c index 83496df..4b71038 100644 --- a/src/php_pqstm.c +++ b/src/php_pqstm.c @@ -58,6 +58,9 @@ static void php_pqstm_object_free(void *o TSRMLS_DC) php_pq_object_delref(obj->intern->conn TSRMLS_CC); efree(obj->intern->name); zend_hash_destroy(&obj->intern->bound); + if (obj->intern->params) { + php_pq_params_free(&obj->intern->params); + } efree(obj->intern); obj->intern = NULL; } @@ -110,7 +113,7 @@ static void php_pqstm_object_read_connection(zval *object, void *o, zval *return ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct, 0, 0, 3) ZEND_ARG_OBJ_INFO(0, Connection, pq\\Connection, 0) - ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, name) ZEND_ARG_INFO(0, query) ZEND_ARG_ARRAY_INFO(0, types, 1) ZEND_ARG_INFO(0, async) @@ -134,10 +137,12 @@ static PHP_METHOD(pqstm, __construct) { if (!conn_obj->intern) { throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); } else { + php_pq_params_t *params = php_pq_params_init(&conn_obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL TSRMLS_CC); + if (async) { - rv = php_pqconn_prepare_async(zconn, conn_obj, name_str, query_str, ztypes ? Z_ARRVAL_P(ztypes) : NULL TSRMLS_CC); + rv = php_pqconn_prepare_async(zconn, conn_obj, name_str, query_str, params TSRMLS_CC); } else { - rv = php_pqconn_prepare(zconn, conn_obj, name_str, query_str, ztypes ? Z_ARRVAL_P(ztypes) : NULL TSRMLS_CC); + rv = php_pqconn_prepare(zconn, conn_obj, name_str, query_str, params TSRMLS_CC); } if (SUCCESS == rv) { @@ -146,6 +151,7 @@ static PHP_METHOD(pqstm, __construct) { php_pq_object_addref(conn_obj TSRMLS_CC); stm->conn = conn_obj; stm->name = estrdup(name_str); + stm->params = params; ZEND_INIT_SYMTABLE(&stm->bound); obj->intern = stm; } @@ -159,8 +165,14 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqstm, bind) { long param_no; zval *param_ref; + zend_error_handling zeh; + STATUS rv; + + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", ¶m_no, ¶m_ref); + zend_restore_error_handling(&zeh TSRMLS_CC); - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", ¶m_no, ¶m_ref)) { + if (SUCCESS == rv) { php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); if (!obj->intern) { @@ -191,25 +203,11 @@ static PHP_METHOD(pqstm, exec) { if (!obj->intern) { throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); } else { - int count = 0; - char **params = NULL; - HashTable zdtor; PGresult *res; - ZEND_INIT_SYMTABLE(&zdtor); - - if (zparams) { - count = php_pq_params_to_array(Z_ARRVAL_P(zparams), ¶ms, &zdtor TSRMLS_CC); - } else { - count = php_pq_params_to_array(&obj->intern->bound, ¶ms, &zdtor TSRMLS_CC); - } - - res = PQexecPrepared(obj->intern->conn->intern->conn, obj->intern->name, count, (const char *const*) params, NULL, NULL, 0); - - if (params) { - efree(params); - } - zend_hash_destroy(&zdtor); + php_pq_params_set_params(obj->intern->params, zparams ? Z_ARRVAL_P(zparams) : &obj->intern->bound); + res = PQexecPrepared(obj->intern->conn->intern->conn, obj->intern->name, obj->intern->params->param.count, (const char *const*) obj->intern->params->param.strings, NULL, NULL, 0); + php_pq_params_set_params(obj->intern->params, NULL); if (!res) { throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); @@ -241,35 +239,21 @@ static PHP_METHOD(pqstm, execAsync) { if (!obj->intern) { throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); } else { - int count; - char **params = NULL; - HashTable zdtor; + int rc; - if (zparams) { - ZEND_INIT_SYMTABLE(&zdtor); - count = php_pq_params_to_array(Z_ARRVAL_P(zparams), ¶ms, &zdtor TSRMLS_CC); - } + php_pq_params_set_params(obj->intern->params, zparams ? Z_ARRVAL_P(zparams) : &obj->intern->bound); + rc = PQsendQueryPrepared(obj->intern->conn->intern->conn, obj->intern->name, obj->intern->params->param.count, (const char *const*) obj->intern->params->param.strings, NULL, NULL, 0); + php_pq_params_set_params(obj->intern->params, NULL); - if (!PQsendQueryPrepared(obj->intern->conn->intern->conn, obj->intern->name, count, (const char *const*) params, NULL, NULL, 0)) { + if (!rc) { throw_exce(EX_IO TSRMLS_CC, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else if (obj->intern->conn->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn->intern->conn)) { throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pq_callback_dtor(&obj->intern->conn->intern->onevent); - if (resolver.fci.size > 0) { - obj->intern->conn->intern->onevent = resolver; - php_pq_callback_addref(&obj->intern->conn->intern->onevent); - } + php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); obj->intern->conn->intern->poller = PQconsumeInput; } - if (params) { - efree(params); - } - if (zparams) { - zend_hash_destroy(&zdtor); - } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); } } @@ -311,14 +295,16 @@ static PHP_METHOD(pqstm, desc) { } } -ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async, 0, 0, 0) +ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async, 0, 0, 1) + ZEND_ARG_INFO(0, callable) ZEND_END_ARG_INFO(); static PHP_METHOD(pqstm, descAsync) { zend_error_handling zeh; + php_pq_callback_t resolver = {{0}}; STATUS rv; zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters_none(); + rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &resolver.fci, &resolver.fcc); zend_restore_error_handling(&zeh TSRMLS_CC); if (SUCCESS == rv) { @@ -329,6 +315,7 @@ static PHP_METHOD(pqstm, descAsync) { } else if (!PQsendDescribePrepared(obj->intern->conn->intern->conn, obj->intern->name)) { throw_exce(EX_IO TSRMLS_CC, "Failed to describe statement: %s", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { + php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); obj->intern->conn->intern->poller = PQconsumeInput; php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); } @@ -345,6 +332,12 @@ static zend_function_entry php_pqstm_methods[] = { {0} }; +PHP_MSHUTDOWN_FUNCTION(pqstm) +{ + zend_hash_destroy(&php_pqstm_object_prophandlers); + return SUCCESS; +} + PHP_MINIT_FUNCTION(pqstm) { zend_class_entry ce = {0}; @@ -359,6 +352,7 @@ PHP_MINIT_FUNCTION(pqstm) php_pqstm_object_handlers.write_property = php_pq_object_write_prop; php_pqstm_object_handlers.clone_obj = NULL; php_pqstm_object_handlers.get_property_ptr_ptr = NULL; + php_pqstm_object_handlers.get_gc = NULL; php_pqstm_object_handlers.get_properties = php_pq_object_properties; php_pqstm_object_handlers.get_debug_info = php_pq_object_debug_info;