From d662d7beb20a15ca8ca95761543f6b9d3b6bff29 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 6 Oct 2014 12:13:04 +0200 Subject: [PATCH] pq\Cursor::__construct --- src/php_pqconn.c | 22 ++------------ src/php_pqcur.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/php_pqcur.h | 2 ++ tests/cursor001.phpt | 26 ++++++++++++++++ 4 files changed, 102 insertions(+), 20 deletions(-) diff --git a/src/php_pqconn.c b/src/php_pqconn.c index b65023c..0527a7b 100644 --- a/src/php_pqconn.c +++ b/src/php_pqconn.c @@ -1343,24 +1343,6 @@ static PHP_METHOD(pqconn, prepareAsync) { } } -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; @@ -1406,7 +1388,7 @@ static PHP_METHOD(pqconn, declare) { 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); + char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len); if (SUCCESS != php_pqconn_declare(getThis(), obj, decl TSRMLS_CC)) { efree(decl); @@ -1471,7 +1453,7 @@ static PHP_METHOD(pqconn, declareAsync) { 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); + char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len); if (SUCCESS != php_pqconn_declare_async(getThis(), obj, decl TSRMLS_CC)) { efree(decl); diff --git a/src/php_pqcur.c b/src/php_pqcur.c index 19c31a9..afaa6b3 100644 --- a/src/php_pqcur.c +++ b/src/php_pqcur.c @@ -161,6 +161,77 @@ static void php_pqcur_object_read_connection(zval *object, void *o, zval *return php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); } +char *php_pqcur_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; +} + +ZEND_BEGIN_ARG_INFO_EX(ai_pqcur___construct, 0, 0, 4) + ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, query) + ZEND_ARG_INFO(0, async) +ZEND_END_ARG_INFO(); +static PHP_METHOD(pqcur, __construct) { + zend_error_handling zeh; + char *name_str, *query_str; + int name_len, query_len; + long flags; + zval *zconn; + STATUS rv; + zend_bool async = 0; + + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Osls|b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &flags, &query_str, &query_len, &async); + zend_restore_error_handling(&zeh TSRMLS_CC); + + if (SUCCESS == rv) { + php_pqcur_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + + if (obj->intern) { + throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\Cursor already initialized"); + } if (!conn_obj->intern) { + throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + } else { + char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len); + + if (async) { + rv = php_pqconn_declare_async(zconn, conn_obj, decl TSRMLS_CC); + } else { + rv = php_pqconn_declare(zconn, conn_obj, decl TSRMLS_CC); + } + + if (SUCCESS != rv) { + efree(decl); + } else { + php_pqcur_t *cur = ecalloc(1, sizeof(*cur)); + + php_pq_object_addref(conn_obj TSRMLS_CC); + cur->conn = conn_obj; + cur->open = 1; + cur->name = estrdup(name_str); + cur->decl = decl; + obj->intern = cur; + } + } + } +} + ZEND_BEGIN_ARG_INFO_EX(ai_pqcur_open, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqcur, open) @@ -242,6 +313,7 @@ static PHP_METHOD(pqcur, moveAsync) } static zend_function_entry php_pqcur_methods[] = { + PHP_ME(pqcur, __construct, ai_pqcur___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_ME(pqcur, open, ai_pqcur_open, ZEND_ACC_PUBLIC) PHP_ME(pqcur, close, ai_pqcur_close, ZEND_ACC_PUBLIC) PHP_ME(pqcur, fetch, ai_pqcur_fetch, ZEND_ACC_PUBLIC) diff --git a/src/php_pqcur.h b/src/php_pqcur.h index 31641b0..cc142e8 100644 --- a/src/php_pqcur.h +++ b/src/php_pqcur.h @@ -39,6 +39,8 @@ typedef struct php_pqcur_object { zend_class_entry *php_pqcur_class_entry; zend_object_value php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern, php_pqcur_object_t **ptr TSRMLS_DC); +char *php_pqcur_declare_str(const char *name_str, size_t name_len, unsigned flags, const char *query_str, size_t query_len); + PHP_MINIT_FUNCTION(pqcur); PHP_MSHUTDOWN_FUNCTION(pqcur); diff --git a/tests/cursor001.phpt b/tests/cursor001.phpt index 1e912b5..f4493f0 100644 --- a/tests/cursor001.phpt +++ b/tests/cursor001.phpt @@ -19,6 +19,22 @@ for ($r = $p->fetch(2); $r->numRows; $p->move(1), $r = $p->fetch(2)) { echo "\n"; } } +try { + $p = new pq\Cursor($c, "mycursor", pq\Cursor::WITH_HOLD, + "SELECT * FROM generate_series(0,29) s WHERE (s%2)=0"); +} catch (Exception $ex) { + $p->close(); +} +$p = new pq\Cursor($c, "mycursor", pq\Cursor::WITH_HOLD, + "SELECT * FROM generate_series(0,29) s WHERE (s%2)=0"); +for ($r = $p->fetch(2); $r->numRows; $p->move(1), $r = $p->fetch(2)) { + foreach ($r as $row) { + foreach ($row as $col) { + echo " $col"; + } + echo "\n"; + } +} ?> ===DONE=== --EXPECT-- @@ -33,4 +49,14 @@ Test 20 24 26 + 0 + 2 + 6 + 8 + 12 + 14 + 18 + 20 + 24 + 26 ===DONE===