rename php_pq_clear_res -> php_pqres_clear
[m6w6/ext-pq] / src / php_pq_misc.c
index 589be7713e4378b426901d143a0b925d8ae84f80..ba591834fe6c6abc2a75aea16298d7fc424df29f 100644 (file)
 
 #include "php_pq.h"
 #include "php_pqexc.h"
+#include "php_pqconn_event.h"
 #include "php_pq_misc.h"
+#undef PHP_PQ_TYPE
+#include "php_pq_type.h"
+
+
+/* clear result object associated with a result handle */
+void php_pqres_clear(PGresult *r) {
+       php_pq_object_t *o = PQresultInstanceData(r, php_pqconn_event);
+
+       if (o) {
+               TSRMLS_FETCH();
+               php_pq_object_delref(o TSRMLS_CC);
+       } else {
+               PQclear(r);
+       }
+}
+
+/* clear any asynchronous results */
+void php_pqconn_clear(PGconn *conn) {
+       PGresult *r;
+       php_pqconn_event_data_t *evdata = PQinstanceData(conn, php_pqconn_event);
+
+       while ((r = PQgetResult(conn))) {
+               php_pqres_clear(r);
+       }
+
+       if (evdata && evdata->obj) {
+               if (php_pq_callback_is_enabled(&evdata->obj->intern->onevent)) {
+                       TSRMLS_FETCH_FROM_CTX(evdata->ts);
+
+                       if (php_pq_callback_is_locked(&evdata->obj->intern->onevent TSRMLS_CC)) {
+                               php_pq_callback_disable(&evdata->obj->intern->onevent TSRMLS_CC);
+                       } else {
+                               php_pq_callback_dtor(&evdata->obj->intern->onevent);
+                       }
+               }
+       }
+}
+
+/* safe wrappers to clear any asynchronous wrappers before querying synchronously */
+PGresult *php_pq_exec(PGconn *conn, const char *query) {
+       php_pqconn_clear(conn);
+       return PQexec(conn, query);
+}
+PGresult *php_pq_exec_params(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat) {
+       php_pqconn_clear(conn);
+       return PQexecParams(conn, command, nParams, paramTypes, paramValues, paramLengths, paramFormats, resultFormat);
+}
+PGresult *php_pq_prepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes) {
+       php_pqconn_clear(conn);
+       return PQprepare(conn, stmtName, query, nParams, paramTypes);
+}
+PGresult *php_pq_exec_prepared(PGconn *conn, const char *stmtName, int nParams, const char *const * paramValues, const int *paramLengths, const int *paramFormats, int resultFormat) {
+       php_pqconn_clear(conn);
+       return PQexecPrepared(conn, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat);
+}
 
 char *php_pq_rtrim(char *e)
 {
@@ -82,7 +138,6 @@ static PHP_METHOD(pqdt, __toString)
 ZEND_BEGIN_ARG_INFO_EX(ai_pqdt_create_from_format, 0, 0, 2)
        ZEND_ARG_INFO(0, format)
        ZEND_ARG_INFO(0, datetime)
-       /* ZEND_ARG_OBJ_INFO(0, timezone, DateTimezone, 1) date's arginfo is not specific */
        ZEND_ARG_INFO(0, timezone)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(pqdt, createFromFormat)
@@ -91,7 +146,7 @@ static PHP_METHOD(pqdt, createFromFormat)
        char *fmt_str, *dt_str;
        int fmt_len, dt_len;
        zval *ztz = NULL;
-       STATUS rv;
+       ZEND_RESULT_CODE rv;
 
        zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
        rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|O", &fmt_str, &fmt_len, &dt_str, &dt_len, &ztz, php_date_get_timezone_ce());
@@ -236,7 +291,7 @@ static char caa(ArrayParserState *a, const char *any, unsigned advance)
        return 0;
 }
 
-static STATUS add_element(ArrayParserState *a, const char *start)
+static ZEND_RESULT_CODE add_element(ArrayParserState *a, const char *start)
 {
        zval *zelem;
        size_t el_len = a->ptr - start;
@@ -266,9 +321,9 @@ static STATUS add_element(ArrayParserState *a, const char *start)
        return zend_hash_next_index_insert(&a->list->ht, &zelem, sizeof(zval *), NULL);
 }
 
-static STATUS parse_array(ArrayParserState *a);
+static ZEND_RESULT_CODE parse_array(ArrayParserState *a);
 
-static STATUS parse_element(ArrayParserState *a)
+static ZEND_RESULT_CODE parse_element(ArrayParserState *a, char delim)
 {
        const char *el;
        TSRMLS_FETCH_FROM_CTX(a->ts);
@@ -285,6 +340,10 @@ static STATUS parse_element(ArrayParserState *a)
 
        for (el = a->ptr; a->ptr < a->end; ++a->ptr) {
                switch (*a->ptr) {
+               case '\\':
+                       a->escaped = !a->escaped;
+                       break;
+
                case '"':
                        if (a->escaped) {
                                a->escaped = 0;
@@ -301,20 +360,18 @@ static STATUS parse_element(ArrayParserState *a)
                        }
                        break;
 
-               case ',':
+               default:
+                       if (delim != *a->ptr) {
+                               a->escaped = 0;
+                               break;
+                       }
+                       /* no break */
                case '}':
                        if (!a->quotes) {
                                return add_element(a, el);
                        }
                        break;
 
-               case '\\':
-                       a->escaped = !a->escaped;
-                       break;
-
-               default:
-                       a->escaped = 0;
-                       break;
                }
        }
 
@@ -322,12 +379,13 @@ static STATUS parse_element(ArrayParserState *a)
        return FAILURE;
 }
 
-static STATUS parse_elements(ArrayParserState *a)
+static ZEND_RESULT_CODE parse_elements(ArrayParserState *a)
 {
+       char delims[] = {'}', PHP_PQ_DELIM_OF_ARRAY(a->typ), 0};
        TSRMLS_FETCH_FROM_CTX(a->ts);
 
-       while (SUCCESS == parse_element(a)) {
-               switch (caa(a, ",}", 0)) {
+       while (SUCCESS == parse_element(a, delims[1])) {
+               switch (caa(a, delims, 0)) {
                case 0:
                        return FAILURE;
 
@@ -346,7 +404,7 @@ static STATUS parse_elements(ArrayParserState *a)
        return FAILURE;
 }
 
-static STATUS parse_array(ArrayParserState *a)
+static ZEND_RESULT_CODE parse_array(ArrayParserState *a)
 {
        HashTableList *list;