From c62ffa9e8cf262c412efeb84c2523d1c78897282 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 16 Oct 2014 16:50:13 +0200 Subject: [PATCH] support PostgreSQL down to 9.0; JSON is optional --- config.m4 | 49 ++++++++++++++++++++++++++++++++-------- package.xml | 5 ++-- src/php_pq_misc.c | 3 --- src/php_pq_misc.h | 1 + src/php_pq_params.c | 6 +++-- src/php_pqconn.c | 8 +++++++ src/php_pqcur.c | 2 ++ src/php_pqres.c | 12 +++++++++- src/php_pqstm.c | 2 ++ tests/_setup.inc | 2 +- tests/async001.phpt | 2 +- tests/async002.phpt | 4 ++-- tests/async003.phpt | 4 ++-- tests/async004.phpt | 2 +- tests/async005.phpt | 2 +- tests/async006.phpt | 5 +++- tests/conv001.phpt | 1 + tests/notify001.phpt | 12 ++++------ tests/unbuffered001.phpt | 6 ++++- 19 files changed, 92 insertions(+), 36 deletions(-) diff --git a/config.m4 b/config.m4 index 0ec1dbd..ae8ae2f 100644 --- a/config.m4 +++ b/config.m4 @@ -20,18 +20,47 @@ if test "$PHP_PQ" != "no"; then AC_MSG_ERROR(could not find include/libpq-events.h) fi PHP_ADD_INCLUDE($PQ_DIR/include) + + ifdef([AC_PROG_EGREP], [ + AC_PROG_EGREP + ], [ + AC_CHECK_PROG(EGREP, egrep, egrep) + ]) + + for PQ_DEF in PGRES_SINGLE_TUPLE PGRES_COPY_BOTH; do + AC_MSG_CHECKING(for $PQ_DEF) + if $EGREP -q $PQ_DEF $PQ_DIR/include/libpq-fe.h; then + AC_DEFINE([$PQ_DEF], [1], [Have $PQ_DEF]) + AC_MSG_RESULT(yep) + else + AC_MSG_RESULT(nope) + fi + done - PQ_SYM=PQregisterEventProc - PHP_CHECK_LIBRARY(pq, $PQ_SYM, [ - PHP_ADD_LIBRARY_WITH_PATH(pq, $PQ_DIR/$PHP_LIBDIR, PQ_SHARED_LIBADD) - PHP_SUBST(PQ_SHARED_LIBADD) - ],[ - AC_MSG_ERROR(could not find $PQ_SYM in -lpq) - ],[ - -L$PQ_DIR/$PHP_LIBDIR + + AC_DEFUN([PQ_CHECK_FUNC], [ + FAIL_HARD=$2 + + PHP_CHECK_LIBRARY(pq, $1, [ + AC_DEFINE([HAVE_]translit($1,a-z,A-Z), 1, Have $1) + ], [ + if test -n "$FAIL_HARD"; then + if "$FAIL_HARD"; then + AC_MSG_ERROR(could not find $PQ_SYM in -lpq) + fi + fi + ], [ + -L$PQ_DIR/$PHP_LIBDIR + ]) ]) - PHP_CHECK_LIBRARY(pq, PQlibVersion, [AC_DEFINE(HAVE_PQLIBVERSION, 1, Have PQlibVersion)]) - PHP_CHECK_LIBRARY(pq, PQconninfo, [AC_DEFINE(HAVE_PQCONNINFO, 1, Have PQconninfo)]) + + PQ_CHECK_FUNC(PQregisterEventProc, true) + PHP_ADD_LIBRARY_WITH_PATH(pq, $PQ_DIR/$PHP_LIBDIR, PQ_SHARED_LIBADD) + PHP_SUBST(PQ_SHARED_LIBADD) + + PQ_CHECK_FUNC(PQlibVersion) + PQ_CHECK_FUNC(PQconninfo) + PQ_CHECK_FUNC(PQsetSingleRowMode) PQ_SRC="\ src/php_pq_module.c\ diff --git a/package.xml b/package.xml index 3531a5d..13b1437 100644 --- a/package.xml +++ b/package.xml @@ -31,9 +31,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> mike@php.net yes - 2014-10-15 + 2014-10-16 - 0.5.2dev + 0.5.2 0.5.0 @@ -42,6 +42,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> BSD, revised diff --git a/src/php_pq_misc.c b/src/php_pq_misc.c index 7dfd2a5..2bc430c 100644 --- a/src/php_pq_misc.c +++ b/src/php_pq_misc.c @@ -17,9 +17,6 @@ #include #include #include -#if defined(HAVE_JSON) && !defined(COMPILE_DL_JSON) -# include -#endif #include diff --git a/src/php_pq_misc.h b/src/php_pq_misc.h index 5bf8160..2e116d7 100644 --- a/src/php_pq_misc.h +++ b/src/php_pq_misc.h @@ -47,6 +47,7 @@ zend_class_entry *php_pqconv_class_entry; HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ TSRMLS_DC); + PHP_MINIT_FUNCTION(pq_misc); #endif diff --git a/src/php_pq_params.c b/src/php_pq_params.c index 4a6ba68..6ac55af 100644 --- a/src/php_pq_params.c +++ b/src/php_pq_params.c @@ -17,7 +17,9 @@ #include #include #include +#ifdef HAVE_JSON #include +#endif #include @@ -86,7 +88,7 @@ static zval *object_param_to_string(php_pq_params_t *p, zval *zobj, Oid type TSR smart_str str = {0}; switch (type) { -#ifdef PHP_PQ_OID_JSON +#if HAVE_JSON && defined(PHP_PQ_OID_JSON) # ifdef PHP_PQ_OID_JSONB case PHP_PQ_OID_JSONB: # endif @@ -225,7 +227,7 @@ static zval *array_param_to_string(php_pq_params_t *p, zval *zarr, Oid type TSRM struct apply_to_param_from_array_arg arg = {NULL}; switch (type) { -#ifdef PHP_PQ_OID_JSON +#if HAVE_JSON && defined(PHP_PQ_OID_JSON) # ifdef PHP_PQ_OID_JSONB case PHP_PQ_OID_JSONB: # endif diff --git a/src/php_pqconn.c b/src/php_pqconn.c index f30b3a8..dd08ced 100644 --- a/src/php_pqconn.c +++ b/src/php_pqconn.c @@ -1133,8 +1133,10 @@ static PHP_METHOD(pqconn, execAsync) { throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); } else if (!PQsendQuery(obj->intern->conn, query_str)) { throw_exce(EX_IO TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); +#if HAVE_PQSETSINGLEROWMODE } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) { throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn)); +#endif } else { php_pq_callback_recurse(&obj->intern->onevent, &resolver TSRMLS_CC); obj->intern->poller = PQconsumeInput; @@ -1222,8 +1224,10 @@ static PHP_METHOD(pqconn, execParamsAsync) { if (!rc) { throw_exce(EX_IO TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); +#if HAVE_PQSETSINGLEROWMODE } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) { throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn)); +#endif } else { php_pq_callback_recurse(&obj->intern->onevent, &resolver TSRMLS_CC); obj->intern->poller = PQconsumeInput; @@ -1310,9 +1314,11 @@ STATUS php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj, const ch if (!PQsendPrepare(obj->intern->conn, name, query, params->type.count, params->type.oids)) { rv = FAILURE; throw_exce(EX_IO TSRMLS_CC, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn)); +#if HAVE_PQSETSINGLEROWMODE } 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)); +#endif } else { rv = SUCCESS; obj->intern->poller = PQconsumeInput; @@ -1440,9 +1446,11 @@ STATUS php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const ch if (!PQsendQuery(obj->intern->conn, decl)) { rv = FAILURE; throw_exce(EX_IO TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn)); +#if HAVE_PQSETSINGLEROWMODE } 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)); +#endif } else { rv = SUCCESS; obj->intern->poller = PQconsumeInput; diff --git a/src/php_pqcur.c b/src/php_pqcur.c index afaa6b3..16057e8 100644 --- a/src/php_pqcur.c +++ b/src/php_pqcur.c @@ -79,8 +79,10 @@ static void cur_fetch_or_move(INTERNAL_FUNCTION_PARAMETERS, const char *action, if (!rc) { throw_exce(EX_IO TSRMLS_CC, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); +#if HAVE_PQSETSINGLEROWMODE } 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)); +#endif } else { php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); obj->intern->conn->intern->poller = PQconsumeInput; diff --git a/src/php_pqres.c b/src/php_pqres.c index d629d25..a9ab9c7 100644 --- a/src/php_pqres.c +++ b/src/php_pqres.c @@ -17,7 +17,9 @@ #include #include +#if HAVE_JSON #include +#endif #include #include "php_pq.h" @@ -79,7 +81,9 @@ static STATUS php_pqres_iterator_valid(zend_object_iterator *i TSRMLS_DC) switch (PQresultStatus(obj->intern->res)) { case PGRES_TUPLES_OK: +#if HAVE_PGRES_SINGLE_TUPLE case PGRES_SINGLE_TUPLE: +#endif if (PQntuples(obj->intern->res) <= iter->index) { return FAILURE; } @@ -171,7 +175,7 @@ zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRM php_pqdt_from_string(val, len, "Y-m-d H:i:s.uO", zv TSRMLS_CC); break; -#ifdef PHP_PQ_OID_JSON +#if HAVE_JSON && defined(PHP_PQ_OID_JSON) # ifdef PHP_PQ_OID_JSONB case PHP_PQ_OID_JSONB: # endif @@ -1203,8 +1207,12 @@ PHP_MINIT_FUNCTION(pqres) zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC); +#ifdef HAVE_PGRES_COPY_BOTH zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC); +#endif +#if HAVE_PGRES_SINGLE_TUPLE zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC); +#endif zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC); @@ -1216,7 +1224,9 @@ PHP_MINIT_FUNCTION(pqres) zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY TSRMLS_CC); zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME TSRMLS_CC); +#if HAVE_JSON zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON TSRMLS_CC); +#endif zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL TSRMLS_CC); return SUCCESS; diff --git a/src/php_pqstm.c b/src/php_pqstm.c index f3136d9..ba12037 100644 --- a/src/php_pqstm.c +++ b/src/php_pqstm.c @@ -250,8 +250,10 @@ static PHP_METHOD(pqstm, execAsync) { if (!rc) { throw_exce(EX_IO TSRMLS_CC, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); +#if HAVE_PQSETSINGLEROWMODE } 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)); +#endif } else { php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); obj->intern->conn->intern->poller = PQconsumeInput; diff --git a/tests/_setup.inc b/tests/_setup.inc index 4fb26f8..d4b5c11 100644 --- a/tests/_setup.inc +++ b/tests/_setup.inc @@ -1,2 +1,2 @@ int(1) ["affectedRows"]=> - int(1) + int(%d) ["fetchType"]=> int(0) ["autoConvert"]=> @@ -56,7 +56,7 @@ object(pq\Result)#%d (8) { ["numCols"]=> int(3) ["affectedRows"]=> - int(1) + int(%d) ["fetchType"]=> int(0) ["autoConvert"]=> diff --git a/tests/async004.phpt b/tests/async004.phpt index 6fc2743..d40cda8 100644 --- a/tests/async004.phpt +++ b/tests/async004.phpt @@ -39,7 +39,7 @@ object(pq\Result)#%d (8) { ["numCols"]=> int(2) ["affectedRows"]=> - int(1) + int(%d) ["fetchType"]=> int(0) ["autoConvert"]=> diff --git a/tests/async005.phpt b/tests/async005.phpt index 102ba13..343992a 100644 --- a/tests/async005.phpt +++ b/tests/async005.phpt @@ -48,7 +48,7 @@ object(pq\Result)#%d (8) { ["numCols"]=> int(2) ["affectedRows"]=> - int(1) + int(%d) ["fetchType"]=> int(0) ["autoConvert"]=> diff --git a/tests/async006.phpt b/tests/async006.phpt index 4bcd889..775c880 100644 --- a/tests/async006.phpt +++ b/tests/async006.phpt @@ -1,7 +1,10 @@ --TEST-- async unbuffered exec --SKIPIF-- - + --FILE-- --INI-- date.timezone=UTC diff --git a/tests/notify001.phpt b/tests/notify001.phpt index e255353..c0b2635 100644 --- a/tests/notify001.phpt +++ b/tests/notify001.phpt @@ -22,19 +22,19 @@ $producer->notify("test", "this is an async test"); $r = array($consumer->socket); $w = null; $e = null; -var_dump(stream_select($r, $w, $e, NULL)); +stream_select($r, $w, $e, NULL); $consumer->poll(); $producer->notify("other", "this should not show up"); -var_dump(stream_select($r, $w, $e, 0)); +stream_select($r, $w, $e, 0,1000); $consumer->poll(); $producer->notify("test", "just to be sure"); $r = array($consumer->socket); $w = null; $e = null; -var_dump(stream_select($r, $w, $e, 0)); +stream_select($r, $w, $e, 0,1000); $consumer->poll(); $consumer->unlisten("test"); @@ -43,7 +43,7 @@ $producer->notify("test", "this shouldn't show up either"); $r = array($consumer->socket); $w = null; $e = null; -var_dump(stream_select($r, $w, $e, 0)); +stream_select($r, $w, $e, 0,1000); $consumer->poll(); ?> @@ -51,10 +51,6 @@ DONE --EXPECTF-- Test test(%d): this is a test -int(1) test(%d): this is an async test -int(0) -int(1) test(%d): just to be sure -int(0) DONE diff --git a/tests/unbuffered001.phpt b/tests/unbuffered001.phpt index 4bc4d85..46e4b9b 100644 --- a/tests/unbuffered001.phpt +++ b/tests/unbuffered001.phpt @@ -1,7 +1,11 @@ --TEST-- unbuffered result --SKIPIF-- - + --FILE--