#include "php_pqres.h"
#include "php_pqstm.h"
#include "php_pqtxn.h"
+#include "php_pqcur.h"
zend_class_entry *php_pqconn_class_entry;
static zend_object_handlers php_pqconn_object_handlers;
fprintf(stderr, "FREE conn(#%d) %p\n", obj->zv.handle, obj);
#endif
if (obj->intern) {
+ php_pq_callback_dtor(&obj->intern->onevent);
php_resource_factory_handle_dtor(&obj->intern->factory, obj->intern->conn TSRMLS_CC);
php_resource_factory_dtor(&obj->intern->factory);
- php_pq_callback_dtor(&obj->intern->onevent);
zend_hash_destroy(&obj->intern->listeners);
zend_hash_destroy(&obj->intern->converters);
zend_hash_destroy(&obj->intern->eventhandlers);
{
php_pqconn_object_t *obj = o;
- obj->intern->unbuffered = zend_is_true(value);
+ obj->intern->unbuffered = z_is_true(value);
}
static void php_pqconn_object_read_db(zval *object, void *o, zval *return_value TSRMLS_DC)
zend_hash_apply_with_arguments(&evdata->obj->intern->listeners TSRMLS_CC, apply_unlisten, 1, evdata->obj);
/* release instance data */
- memset(evdata, 0, sizeof(*evdata));
+ //memset(evdata, 0, sizeof(*evdata));
efree(evdata);
}
}
zend_error_handling zeh;
char *channel_str = NULL;
int channel_len = 0;
- php_pq_callback_t listener;
+ php_pq_callback_t listener = {{0}};
STATUS rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
zend_error_handling zeh;
char *channel_str = NULL;
int channel_len = 0;
- php_pq_callback_t listener;
+ php_pq_callback_t listener = {{0}};
STATUS rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare, 0, 0, 2)
- ZEND_ARG_INFO(0, type)
+ ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, types, 1)
ZEND_END_ARG_INFO();
}
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async, 0, 0, 2)
-ZEND_ARG_INFO(0, type)
+ ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, types, 1)
ZEND_END_ARG_INFO();
}
}
+static inline char *declare_str(const char *name_str, size_t name_len, unsigned flags, const char *query_str, size_t query_len)
+{
+ size_t decl_len = name_len + query_len + sizeof("DECLARE BINARY INSENSITIVE NO SCROLL CURSOR WITHOUT HOLD FOR ");
+ char *decl_str;
+
+ decl_str = emalloc(decl_len);
+ decl_len = slprintf(decl_str, decl_len, "DECLARE %s %s %s %s CURSOR %s FOR %s",
+ name_str,
+ (flags & PHP_PQ_DECLARE_BINARY) ? "BINARY" : "",
+ (flags & PHP_PQ_DECLARE_INSENSITIVE) ? "INSENSITIVE" : "",
+ (flags & PHP_PQ_DECLARE_NO_SCROLL) ? "NO SCROLL" :
+ (flags & PHP_PQ_DECLARE_SCROLL) ? "SCROLL" : "",
+ (flags & PHP_PQ_DECLARE_WITH_HOLD) ? "WITH HOLD" : "",
+ query_str
+ );
+ return decl_str;
+}
+
+STATUS php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC)
+{
+ PGresult *res;
+ STATUS rv;
+
+ if (!obj) {
+ obj = zend_object_store_get_object(object TSRMLS_CC);
+ }
+
+ res = PQexec(obj->intern->conn, decl);
+
+ if (!res) {
+ rv = FAILURE;
+ throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
+ } else {
+ rv = php_pqres_success(res TSRMLS_CC);
+ PHP_PQclear(res);
+ php_pqconn_notify_listeners(obj TSRMLS_CC);
+ }
+
+ return rv;
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare, 0, 0, 3)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, query)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqconn, declare) {
+ zend_error_handling zeh;
+ char *name_str, *query_str;
+ int name_len, query_len;
+ long flags;
+ STATUS rv;
+
+ zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
+ rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &name_str, &name_len, &flags, &query_str, &query_len);
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+
+ if (SUCCESS == rv) {
+ php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (!obj->intern) {
+ throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
+ } else {
+ char *decl = declare_str(name_str, name_len, flags, query_str, query_len);
+
+ if (SUCCESS != php_pqconn_declare(getThis(), obj, decl TSRMLS_CC)) {
+ efree(decl);
+ } else {
+ php_pqcur_t *cur = ecalloc(1, sizeof(*cur));
+
+ php_pq_object_addref(obj TSRMLS_CC);
+ cur->conn = obj;
+ cur->open = 1;
+ cur->name = estrdup(name_str);
+ cur->decl = decl;
+
+ return_value->type = IS_OBJECT;
+ return_value->value.obj = php_pqcur_create_object_ex(php_pqcur_class_entry, cur, NULL TSRMLS_CC);
+ }
+ }
+ }
+}
+
+STATUS php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC)
+{
+ STATUS rv;
+
+ if (!obj) {
+ obj = zend_object_store_get_object(object TSRMLS_CC);
+ }
+
+ if (!PQsendQuery(obj->intern->conn, decl)) {
+ rv = FAILURE;
+ throw_exce(EX_IO TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
+ } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) {
+ rv = FAILURE;
+ throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn));
+ } else {
+ rv = SUCCESS;
+ obj->intern->poller = PQconsumeInput;
+ php_pqconn_notify_listeners(obj TSRMLS_CC);
+ }
+
+ return rv;
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare_async, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, query)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqconn, declareAsync) {
+ zend_error_handling zeh;
+ char *name_str, *query_str;
+ int name_len, query_len;
+ long flags;
+ STATUS rv;
+
+ zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
+ rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &name_str, &name_len, &flags, &query_str, &query_len);
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+
+ if (SUCCESS == rv) {
+ php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (!obj->intern) {
+ throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
+ } else {
+ char *decl = declare_str(name_str, name_len, flags, query_str, query_len);
+
+ if (SUCCESS != php_pqconn_declare_async(getThis(), obj, decl TSRMLS_CC)) {
+ efree(decl);
+ } else {
+ php_pqcur_t *cur = ecalloc(1, sizeof(*cur));
+
+ php_pq_object_addref(obj TSRMLS_CC);
+ cur->conn = obj;
+ cur->open = 1;
+ cur->name = estrdup(name_str);
+ cur->decl = decl;
+
+ return_value->type = IS_OBJECT;
+ return_value->value.obj = php_pqcur_create_object_ex(php_pqcur_class_entry, cur, NULL TSRMLS_CC);
+ }
+ }
+ }
+}
+
ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote, 0, 0, 1)
ZEND_ARG_INFO(0, string)
ZEND_END_ARG_INFO();
zend_error_handling zeh;
char *type_str;
int type_len;
- php_pq_callback_t cb;
+ php_pq_callback_t cb = {{0}};
STATUS rv;
zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
PHP_ME(pqconn, execParamsAsync, ai_pqconn_exec_params_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, prepare, ai_pqconn_prepare, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, prepareAsync, ai_pqconn_prepare_async, ZEND_ACC_PUBLIC)
+ PHP_ME(pqconn, declare, ai_pqconn_declare, ZEND_ACC_PUBLIC)
+ PHP_ME(pqconn, declareAsync, ai_pqconn_declare_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, listen, ai_pqconn_listen, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, listenAsync, ai_pqconn_listen_async, ZEND_ACC_PUBLIC)
PHP_ME(pqconn, notify, ai_pqconn_notify, ZEND_ACC_PUBLIC)