support PostgreSQL down to 9.0; JSON is optional
authorMichael Wallner <mike@php.net>
Thu, 16 Oct 2014 14:50:13 +0000 (16:50 +0200)
committerMichael Wallner <mike@php.net>
Thu, 16 Oct 2014 14:50:13 +0000 (16:50 +0200)
19 files changed:
config.m4
package.xml
src/php_pq_misc.c
src/php_pq_misc.h
src/php_pq_params.c
src/php_pqconn.c
src/php_pqcur.c
src/php_pqres.c
src/php_pqstm.c
tests/_setup.inc
tests/async001.phpt
tests/async002.phpt
tests/async003.phpt
tests/async004.phpt
tests/async005.phpt
tests/async006.phpt
tests/conv001.phpt
tests/notify001.phpt
tests/unbuffered001.phpt

index 0ec1dbd..ae8ae2f 100644 (file)
--- 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\
index 3531a5d..13b1437 100644 (file)
@@ -31,9 +31,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
   <email>mike@php.net</email>
   <active>yes</active>
  </lead>
- <date>2014-10-15</date>
+ <date>2014-10-16</date>
  <version>
-  <release>0.5.2dev</release>
+  <release>0.5.2</release>
   <api>0.5.0</api>
  </version>
  <stability>
@@ -42,6 +42,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
  </stability>
  <license>BSD, revised</license>
  <notes><![CDATA[
+* Fix build with PostgreSQL 9.1 and 9.0
 ]]></notes>
  <contents>
   <dir name="/">
index 7dfd2a5..2bc430c 100644 (file)
@@ -17,9 +17,6 @@
 #include <php.h>
 #include <ext/date/php_date.h>
 #include <ext/standard/php_string.h>
-#if defined(HAVE_JSON) && !defined(COMPILE_DL_JSON)
-#      include <ext/json/php_json.h>
-#endif
 
 #include <Zend/zend_interfaces.h>
 
index 5bf8160..2e116d7 100644 (file)
@@ -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
index 4a6ba68..6ac55af 100644 (file)
@@ -17,7 +17,9 @@
 #include <php.h>
 #include <ext/standard/php_string.h>
 #include <ext/standard/php_smart_str.h>
+#ifdef HAVE_JSON
 #include <ext/json/php_json.h>
+#endif
 
 #include <Zend/zend_interfaces.h>
 
@@ -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
index f30b3a8..dd08ced 100644 (file)
@@ -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;
index afaa6b3..16057e8 100644 (file)
@@ -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;
index d629d25..a9ab9c7 100644 (file)
@@ -17,7 +17,9 @@
 #include <php.h>
 
 #include <ext/spl/spl_iterators.h>
+#if HAVE_JSON
 #include <ext/json/php_json.h>
+#endif
 #include <libpq-events.h>
 
 #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;
index f3136d9..ba12037 100644 (file)
@@ -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;
index 4fb26f8..d4b5c11 100644 (file)
@@ -1,2 +1,2 @@
 <?php
-define("PQ_DSN", "");
+define("PQ_DSN", "host=localhost");
index 2327857..d1aa35b 100644 (file)
@@ -44,5 +44,5 @@ DONE
 --EXPECTREGEX--
 Test
 (WP(RP)*)+S
-3(,\d+),+4
+(2,)*3(,\d)*,4
 DONE
index 12b1be4..4cc19c8 100644 (file)
@@ -54,7 +54,7 @@ DONE
 --EXPECTREGEX--
 Test
 (WP(RP)*)+S
-3(,\d+),+4
+(2,)*3(,\d)*,4
 (WP(RP)*)+S
-3(,\d+),+4
+(2,)*3(,\d)*,4
 DONE
index 32d9dfd..9872642 100644 (file)
@@ -38,7 +38,7 @@ object(pq\Result)#%d (8) {
   ["numCols"]=>
   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"]=>
index 6fc2743..d40cda8 100644 (file)
@@ -39,7 +39,7 @@ object(pq\Result)#%d (8) {
   ["numCols"]=>
   int(2)
   ["affectedRows"]=>
-  int(1)
+  int(%d)
   ["fetchType"]=>
   int(0)
   ["autoConvert"]=>
index 102ba13..343992a 100644 (file)
@@ -48,7 +48,7 @@ object(pq\Result)#%d (8) {
   ["numCols"]=>
   int(2)
   ["affectedRows"]=>
-  int(1)
+  int(%d)
   ["fetchType"]=>
   int(0)
   ["autoConvert"]=>
index 4bcd889..775c880 100644 (file)
@@ -1,7 +1,10 @@
 --TEST--
 async unbuffered exec
 --SKIPIF--
-<?php include "_skipif.inc"; ?>
+<?php
+include "_skipif.inc";
+defined("pq\\Result::SINGLE_TUPLE") or die("skip need pq\\Result::SINGLE_TUPLE");
+?>
 --FILE--
 <?php
 echo "Test\n";
index 7e778e9..ec88151 100644 (file)
@@ -3,6 +3,7 @@ converter
 --SKIPIF--
 <?php
 include "_skipif.inc";
+_ext("json");
 ?>
 --INI--
 date.timezone=UTC
index e255353..c0b2635 100644 (file)
@@ -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
index 4bc4d85..46e4b9b 100644 (file)
@@ -1,7 +1,11 @@
 --TEST--
 unbuffered result
 --SKIPIF--
-<?php include "_skipif.inc"; ?>
+<?php 
+include "_skipif.inc";
+defined("pq\\Result::SINGLE_TUPLE") or die("skip need pq\\Result::SINGLE_TUPLE");
+
+?>
 --FILE--
 <?php
 echo "Test\n";