/autom4te*
/.dep.inc
run-tests.php
+php_pq_type.h
PHP_ARG_WITH(pq, [whether to enable libpq (PostgreSQL) support],
-[ --with-pq Include libpq support])
+[ --with-pq Include libpq support])
+PHP_ARG_WITH(pq-postgresql, [where to find PostgreSQL server headers],
+[ --with-pq-postgresql Define some standard type IODs from catalog/pg_type.h], [$PHP_PQ])
if test "$PHP_PQ" != "no"; then
SEARCH_PATH="/usr/local /usr /opt"
-L$PQ_DIR/$PHP_LIBDIR
])
PHP_CHECK_LIBRARY(pq, PQlibVersion, [AC_DEFINE(HAVE_PQLIBVERSION, 1, Have PQlibVersion)])
-
+
PQ_SRC="\
src/php_pq_module.c\
src/php_pq_misc.c\
PHP_NEW_EXTENSION(pq, $PQ_SRC, $ext_shared)
PHP_ADD_BUILD_DIR($ext_builddir/src)
PHP_ADD_INCLUDE($ext_srcdir/src)
- PHP_ADD_EXTENSION_DEP(pq, raphf)
+ PHP_ADD_EXTENSION_DEP(pq, raphf)
+
+ if test "$PHP_PQ_POSTGRESQL" != "no"; then
+ if test "$PHP_PQ_POSTGRESQL" != "yes"; then
+ SEARCH_PATH="$PHP_PQ_POSTGRESQL $SEARCH_PATH"
+ fi
+ for i in $SEARCH_PATH; do
+ CATALOG="$i/include/postgresql/server/catalog/pg_type.h"
+ AC_MSG_CHECKING(for $CATALOG)
+ if test -f "$CATALOG"; then
+ AC_MSG_RESULT(yep)
+ AC_PROG_AWK()
+ $AWK -f $ext_srcdir/php_pq_type.awk < "$CATALOG" > $ext_srcdir/php_pq_type.h
+ AC_DEFINE(HAVE_PHP_PQ_TYPE_H, 1, Have PostgreSQL type OID defs)
+ break
+ fi
+ AC_MSG_RESULT(nope)
+ done
+ fi
fi
</stability>
<license>BSD, revised</license>
<notes><![CDATA[
+* Fixed type handling of boolean/double input parameters.
+* Added extented type handling of result parameters if PostgreSQL server headers are present.
* Implemented get_properties() object handler.
]]></notes>
<contents>
<file role="doc" name="LICENSE" />
<file role="src" name="config.m4" />
<file role="src" name="php_pq.h" />
+ <file role="src" name="php_pq_type.awk" />
<dir name="src">
<file role="src" name="php_pq_callback.c" />
<file role="src" name="php_pq_callback.h" />
<file role="test" name="basic001.phpt" />
<file role="test" name="basic002.phpt" />
<file role="test" name="bound001.phpt" />
+ <file role="test" name="bound002.phpt" />
<file role="test" name="cancel001.phpt" />
<file role="test" name="copy001.phpt" />
<file role="test" name="encoding001.phpt" />
--- /dev/null
+#!/usr/bin/awk -f
+
+BEGIN {
+ printf "#ifndef PHP_PQ_TYPE\n"
+ printf "# define PHP_PQ_TYPE(t,o)\n"
+ printf "#endif\n"
+}
+
+END {
+ printf "#ifndef PHP_PQ_TYPE_IS_ARRAY\n"
+ printf "# define PHP_PQ_TYPE_IS_ARRAY(oid) (\\\n\t\t0 \\\n"
+ for (name in arrays) {
+ printf "\t||\t((oid) == %d) \\\n", arrays[name]
+ }
+ printf ")\n#endif\n"
+}
+
+/^DATA/ {
+ oid = $4
+ name = toupper($6)
+ if (sub("^_", "", name)) {
+ arrays[name] = oid
+ name = name "ARRAY"
+ }
+ printf "#ifndef PHP_PQ_OID_%s\n", name
+ printf "# define PHP_PQ_OID_%s %d\n", name, oid
+ printf "#endif\n"
+ printf "PHP_PQ_TYPE(\"%s\", %d)\n", name, oid
+}
#endif
#include <php.h>
-
+#include <ext/date/php_date.h>
#include <libpq/libpq-fs.h>
#include "php_pq.h"
}
*/
+zval *php_pq_date_from_string(char *datetime_str, size_t datetime_len, zval *zv TSRMLS_DC)
+{
+ php_date_obj *dobj;
+
+ if (!zv) {
+ MAKE_STD_ZVAL(zv);
+ }
+
+ php_date_instantiate(php_date_get_date_ce(), zv TSRMLS_CC);
+ dobj = zend_object_store_get_object(zv TSRMLS_CC);
+ if (!php_date_initialize(dobj, datetime_str, datetime_len, NULL, NULL, 1 TSRMLS_CC)) {
+ zval_dtor(zv);
+ ZVAL_NULL(zv);
+ }
+
+ return zv;
+}
+
/*
* Local variables:
* tab-width: 4
int php_pq_types_to_array(HashTable *ht, Oid **types TSRMLS_DC);
int php_pq_params_to_array(HashTable *ht, char ***params, HashTable *zdtor TSRMLS_DC);
+zval *php_pq_date_from_string(char *datetime_str, size_t datetime_len, zval *zv TSRMLS_DC);
+
#endif
/*
break;
}
} else {
+ zval *zv;
char *val = PQgetvalue(res, row, c);
int len = PQgetlength(res, row, c);
+ MAKE_STD_ZVAL(zv);
+
+ switch (PQftype(res, c)) {
+#ifdef HAVE_PHP_PQ_TYPE_H
+# undef PHP_PQ_TYPE
+# include "php_pq_type.h"
+ case PHP_PQ_OID_BOOL:
+ ZVAL_BOOL(zv, *val == 't');
+ break;
+#if SIZEOF_LONG >= 8
+ case PHP_PQ_OID_INT8:
+ case PHP_PQ_OID_TID:
+#endif
+ case PHP_PQ_OID_INT4:
+ case PHP_PQ_OID_INT2:
+ case PHP_PQ_OID_XID:
+ case PHP_PQ_OID_OID:
+ ZVAL_LONG(zv, zend_atol(val, len));
+ break;
+
+ case PHP_PQ_OID_FLOAT4:
+ case PHP_PQ_OID_FLOAT8:
+ ZVAL_DOUBLE(zv, zend_strtod(val, NULL));
+ break;
+
+ case PHP_PQ_OID_ABSTIME:
+ case PHP_PQ_OID_DATE:
+ case PHP_PQ_OID_TIMESTAMP:
+ case PHP_PQ_OID_TIMESTAMPTZ:
+ php_pq_date_from_string(val, len, zv TSRMLS_CC);
+ break;
+
+
+#else
+ case 18: /* BOOL */
+ ZVAL_BOOL(zv, *val == 't');
+ break;
+#endif
+ default:
+ ZVAL_STRINGL(zv, val, len, 1);
+ break;
+ }
+
switch (fetch_type) {
case PHP_PQRES_FETCH_OBJECT:
- add_property_stringl(data, PQfname(res, c), val, len, 1);
+ add_property_zval(data, PQfname(res, c), zv);
+ zval_ptr_dtor(&zv);
break;
case PHP_PQRES_FETCH_ASSOC:
- add_assoc_stringl(data, PQfname(res, c), val, len, 1);
+ add_assoc_zval(data, PQfname(res, c), zv);
break;
case PHP_PQRES_FETCH_ARRAY:
- add_index_stringl(data, c, val, len ,1);
+ add_index_zval(data, c, zv);
break;
}
}
"from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
"where typisdefined " \
"and typrelid=0"
-#define PHP_PQ_OID_TEXT 25
+#ifndef PHP_PQ_OID_TEXT
+# define PHP_PQ_OID_TEXT 25
+#endif
ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, namespaces, 1)
ph.read = php_pqtypes_object_read_connection;
zend_hash_add(&php_pqtypes_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL);
+#ifdef HAVE_PHP_PQ_TYPE_H
+# undef PHP_PQ_TYPE
+# define PHP_PQ_TYPE(name, oid) zend_declare_class_constant_long(php_pqtypes_class_entry, ZEND_STRL(name), oid TSRMLS_CC);
+# include "php_pq_type.h"
+ zend_declare_class_constant_bool(php_pqtypes_class_entry, ZEND_STRL("DEFINED"), 1 TSRMLS_CC);
+#else
+ zend_declare_class_constant_bool(php_pqtypes_class_entry, ZEND_STRL("DEFINED"), 0 TSRMLS_CC);
+#endif
+
return SUCCESS;
}
--TEST--
fetch bound
--SKIPIF--
-<?php include "_skipif.inc"; ?>
+<?php
+include "_skipif.inc";
+if (pq\Types::DEFINED) {
+ die("skip pq\Types::DEFINED == true");
+}
+?>
--FILE--
<?php
echo "Test\n";
--- /dev/null
+--TEST--
+fetch bound
+--SKIPIF--
+<?php
+include "_skipif.inc";
+if (!pq\Types::DEFINED) {
+ die("skip pq\Types::DEFINED == false");
+}
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+include "_setup.inc";
+
+$c = new pq\Connection(PQ_DSN);
+$r = $c->exec("select 1*a,2*a,3*a from generate_series(2,3) a");
+$r->bind(0, $a);
+$r->bind(1, $b);
+$r->bind(2, $c);
+while ($s = $r->fetchBound()) {
+ var_dump($s,$a,$b,$c);
+}
+?>
+DONE
+--EXPECT--
+Test
+array(3) {
+ [0]=>
+ &int(2)
+ [1]=>
+ &int(4)
+ [2]=>
+ &int(6)
+}
+int(2)
+int(4)
+int(6)
+array(3) {
+ [0]=>
+ &int(3)
+ [1]=>
+ &int(6)
+ [2]=>
+ &int(9)
+}
+int(3)
+int(6)
+int(9)
+DONE