X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-pq;a=blobdiff_plain;f=src%2Fphp_pq_misc.c;h=619559d0fe724d393d299b72b467c0b84cd5a673;hp=484d760ff085cb024a7ac505efa0a755aec7651e;hb=843fc4cf789fa12ef08e6beefc4653498fe73bfd;hpb=6e28a8741be3fccdaca960e492c31bc26837a4ed diff --git a/src/php_pq_misc.c b/src/php_pq_misc.c index 484d760..619559d 100644 --- a/src/php_pq_misc.c +++ b/src/php_pq_misc.c @@ -25,9 +25,60 @@ #include "php_pq.h" #include "php_pqexc.h" #include "php_pq_misc.h" +#include "php_pqconn_event.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) { + php_pq_object_delref(o); + } 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)) { + if (php_pq_callback_is_locked(&evdata->obj->intern->onevent)) { + php_pq_callback_disable(&evdata->obj->intern->onevent); + } 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) { size_t l = strlen(e); @@ -54,18 +105,23 @@ const char *php_pq_strmode(long mode) int php_pq_compare_index(const void *lptr, const void *rptr) { - const Bucket *l = *(const Bucket **) lptr; - const Bucket *r = *(const Bucket **) rptr; + zend_ulong l = ((const Bucket *) lptr)->h; + zend_ulong r = ((const Bucket *) rptr)->h; - if (l->h < r->h) { + if (l < r) { return -1; } - if (l->h > r->h) { + if (l > r) { return 1; } return 0; } +void php_pq_hash_ptr_dtor(zval *p) +{ + efree(Z_PTR_P(p)); +} + zend_class_entry *php_pqdt_class_entry; ZEND_BEGIN_ARG_INFO_EX(ai_pqdt_to_string, 0, 0, 0) @@ -83,13 +139,17 @@ 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) +#if PHP_VERSION_ID >= 70200 + ZEND_ARG_OBJ_INFO(0, object, DateTimeZone, 1) +#else ZEND_ARG_INFO(0, timezone) +#endif ZEND_END_ARG_INFO(); static PHP_METHOD(pqdt, createFromFormat) { zend_error_handling zeh; char *fmt_str, *dt_str; - int fmt_len, dt_len; + size_t fmt_len, dt_len; zval *ztz = NULL; ZEND_RESULT_CODE rv; @@ -258,6 +318,9 @@ static ZEND_RESULT_CODE parse_element(ArrayParserState *a, char delim) case '{': return parse_array(a); + case '}': + return SUCCESS; + case '"': a->quotes = 1; ++a->ptr; @@ -307,7 +370,7 @@ static ZEND_RESULT_CODE parse_element(ArrayParserState *a, char delim) static ZEND_RESULT_CODE parse_elements(ArrayParserState *a) { - char delims[] = {'}', PHP_PQ_DELIM_OF_ARRAY(a->typ), 0}; + char delims[] = {'}', (char) PHP_PQ_DELIM_OF_ARRAY(a->typ), 0}; while (SUCCESS == parse_element(a, delims[1])) { switch (caa(a, delims, 0)) { @@ -338,7 +401,7 @@ static ZEND_RESULT_CODE parse_array(ArrayParserState *a) } list = ecalloc(1, sizeof(*list)); - ZVAL_NEW_ARR(&list->arr); + array_init(&list->arr); if (a->list) { add_next_index_zval(&a->list->arr, &list->arr); @@ -354,14 +417,18 @@ static ZEND_RESULT_CODE parse_array(ArrayParserState *a) return FAILURE; } + /* step one level back up */ if (a->list->parent) { - a->list = a->list->parent; + HashTableList *l = a->list->parent; + + efree(a->list); + a->list = l; } return SUCCESS; } -HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ TSRMLS_DC) +HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ) { HashTable *ht = NULL; ArrayParserState a = {0}; @@ -386,9 +453,13 @@ HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_ php_error_docref(NULL, E_NOTICE, "Trailing input: '%s'", a.ptr); } - do { + while (a.list) { + HashTableList *l = a.list->parent; + ht = Z_ARRVAL(a.list->arr); - } while ((a.list = a.list->parent)); + efree(a.list); + a.list = l; + } return ht; }