hholzgra Wed Jul 23 09:27:01 2008 UTC
Modified files:
/php-src/ext/pgsql config.m4 pgsql.c
/php-src/ext/pgsql/tests 27large_object_oid.phpt
28large_object_import_oid.phpt
Log:
MFB + Unicode:
added support for object ids in pg_lo_create() and pg_lo_import()
where available (based on code provided by Tatsuo Ishii)
http://cvs.php.net/viewvc.cgi/php-src/ext/pgsql/config.m4?r1=1.52&r2=1.53&diff_format=u
Index: php-src/ext/pgsql/config.m4
diff -u php-src/ext/pgsql/config.m4:1.52 php-src/ext/pgsql/config.m4:1.53
--- php-src/ext/pgsql/config.m4:1.52 Wed Jul 11 21:51:10 2007
+++ php-src/ext/pgsql/config.m4 Wed Jul 23 09:27:01 2008
@@ -1,5 +1,5 @@
dnl
-dnl $Id: config.m4,v 1.52 2007/07/11 21:51:10 jani Exp $
+dnl $Id: config.m4,v 1.53 2008/07/23 09:27:01 hholzgra Exp $
dnl
PHP_ARG_WITH(pgsql,for PostgreSQL support,
@@ -92,6 +92,8 @@
AC_CHECK_LIB(pq, PQescapeStringConn,
AC_DEFINE(HAVE_PQESCAPE_CONN,1,[PostgreSQL 8.1.4 or later]))
AC_CHECK_LIB(pq, PQescapeByteaConn,
AC_DEFINE(HAVE_PQESCAPE_BYTEA_CONN,1,[PostgreSQL 8.1.4 or later]))
AC_CHECK_LIB(pq,
pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether
libpq is compiled with --enable-multibyte]))
+ AC_CHECK_LIB(pq, lo_create, AC_DEFINE(HAVE_PG_LO_CREATE,1,[PostgreSQL 8.1 or
later]))
+ AC_CHECK_LIB(pq, lo_import_with_oid,
AC_DEFINE(HAVE_PG_LO_IMPORT_WITH_OID,1,[PostgreSQL 8.4 or later]))
LIBS=$old_LIBS
LDFLAGS=$old_LDFLAGS
http://cvs.php.net/viewvc.cgi/php-src/ext/pgsql/pgsql.c?r1=1.381&r2=1.382&diff_format=u
Index: php-src/ext/pgsql/pgsql.c
diff -u php-src/ext/pgsql/pgsql.c:1.381 php-src/ext/pgsql/pgsql.c:1.382
--- php-src/ext/pgsql/pgsql.c:1.381 Wed Jul 2 00:13:26 2008
+++ php-src/ext/pgsql/pgsql.c Wed Jul 23 09:27:01 2008
@@ -20,7 +20,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pgsql.c,v 1.381 2008/07/02 00:13:26 felipe Exp $ */
+/* $Id: pgsql.c,v 1.382 2008/07/23 09:27:01 hholzgra Exp $ */
#include <stdlib.h>
@@ -350,6 +350,7 @@
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_create, 0, 0, 0)
ZEND_ARG_INFO(0, connection)
+ ZEND_ARG_INFO(0, large_object_id)
ZEND_END_ARG_INFO()
static
@@ -392,6 +393,7 @@
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_import, 0, 0, 0)
ZEND_ARG_INFO(0, connection)
ZEND_ARG_INFO(0, filename)
+ ZEND_ARG_INFO(0, large_object_oid)
ZEND_END_ARG_INFO()
static
@@ -2978,42 +2980,86 @@
}
/* }}} */
-/* {{{ proto int pg_lo_create([resource connection])
+/* {{{ proto mixed pg_lo_create([resource connection],[mixed large_object_oid])
Create a large object */
PHP_FUNCTION(pg_lo_create)
{
- zval *pgsql_link = NULL;
- PGconn *pgsql;
- Oid pgsql_oid;
- int id = -1, argc = ZEND_NUM_ARGS();
+ zval *pgsql_link = NULL, *oid = NULL;
+ PGconn *pgsql;
+ Oid pgsql_oid, wanted_oid = InvalidOid;
+ int id = -1, argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) ==
FAILURE) {
+ if (zend_parse_parameters(argc TSRMLS_CC, "|zz", &pgsql_link, &oid) ==
FAILURE) {
return;
}
+
+ if ((argc == 1) && (Z_TYPE_P(pgsql_link) != IS_RESOURCE)) {
+ oid = pgsql_link;
+ pgsql_link = NULL;
+ }
- if (argc == 0) {
+ if (pgsql_link == NULL) {
id = PGG(default_link);
CHECK_DEFAULT_LINK(id);
+ if (id == -1) {
+ RETURN_FALSE;
+ }
}
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
-
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL
link", le_link, le_plink);
- /* NOTE: Archive modes not supported until I get some more data. Don't
think anybody's
- using it anyway. I believe it's also somehow related to the 'time
travel' feature of
- PostgreSQL, that's on the list of features to be removed... Create
modes not supported.
- What's the use of an object that can be only written to, but not
read from, and vice
- versa? Beats me... And the access type (r/w) must be specified again
when opening
- the object, probably (?) overrides this. (Jouni)
- */
+ if (oid) {
+#ifndef HAVE_PG_LO_CREATE
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OID value passing
not supported");
+#else
+ switch (Z_TYPE_P(oid)) {
+ case IS_STRING:
+ {
+ char *end_ptr;
+ wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid),
&end_ptr, 10);
+ if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) !=
end_ptr) {
+ /* wrong integer format */
+ php_error_docref(NULL TSRMLS_CC,
E_NOTICE, "invalid OID value passed");
+ RETURN_FALSE;
+ }
+ }
+ break;
+ case IS_UNICODE:
+ {
+ UChar *end_ptr;
+ wanted_oid =
(Oid)zend_u_strtoul(Z_USTRVAL_P(oid), &end_ptr, 10);
+ if ((Z_USTRVAL_P(oid)+Z_USTRLEN_P(oid)) !=
end_ptr) {
+ /* wrong integer format */
+ php_error_docref(NULL TSRMLS_CC,
E_NOTICE, "invalid OID value passed");
+ RETURN_FALSE;
+ }
+ }
+ break;
+ case IS_LONG:
+ if (Z_LVAL_P(oid) < (long)InvalidOid) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE,
"invalid OID value passed");
+ RETURN_FALSE;
+ }
+ wanted_oid = (Oid)Z_LVAL_P(oid);
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID
value passed");
+ RETURN_FALSE;
+ }
+ if ((pgsql_oid = lo_create(pgsql, wanted_oid)) == InvalidOid) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to
create PostgreSQL large object");
+ RETURN_FALSE;
+ }
+
+ PGSQL_RETURN_OID(pgsql_oid);
+#endif
+ }
if ((pgsql_oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == InvalidOid) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create
PostgreSQL large object");
RETURN_FALSE;
}
+
PGSQL_RETURN_OID(pgsql_oid);
}
/* }}} */
@@ -3332,26 +3378,27 @@
}
/* }}} */
-/* {{{ proto int pg_lo_import([resource connection, ] string filename)
+/* {{{ proto int pg_lo_import([resource connection, ] string filename [, mixed
oid])
Import large object direct from filesystem */
PHP_FUNCTION(pg_lo_import)
{
- zval *pgsql_link = NULL;
+ zval *pgsql_link = NULL, *oid = NULL;
char *file_in;
int id = -1, name_len;
int argc = ZEND_NUM_ARGS();
PGconn *pgsql;
- Oid oid;
+ Oid wanted_oid, returned_oid;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rs",
&pgsql_link, &file_in, &name_len) == SUCCESS) {
+ "rs|z",
&pgsql_link, &file_in, &name_len, &oid) == SUCCESS) {
;
}
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc
TSRMLS_CC,
- "s",
&file_in, &name_len) == SUCCESS) {
+
"s|z", &file_in, &name_len, &oid) == SUCCESS) {
id = PGG(default_link);
CHECK_DEFAULT_LINK(id);
}
+ // old calling convention, deprecated since PHP 4.2
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc
TSRMLS_CC,
"sr",
&file_in, &name_len, &pgsql_link ) == SUCCESS) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Old API is used");
@@ -3370,12 +3417,61 @@
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL
link", le_link, le_plink);
- oid = lo_import(pgsql, file_in);
+ if (oid) {
+#ifndef HAVE_PG_LO_IMPORT_WITH_OID
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OID value passing
not supported");
+#else
+ switch (Z_TYPE_P(oid)) {
+ case IS_STRING:
+ {
+ char *end_ptr;
+ wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid),
&end_ptr, 10);
+ if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) !=
end_ptr) {
+ /* wrong integer format, trailing
non-numeric characters */
+ php_error_docref(NULL TSRMLS_CC,
E_NOTICE, "invalid OID value passed");
+ RETURN_FALSE;
+ }
+ }
+ break;
+ case IS_UNICODE:
+ {
+ UChar *end_ptr;
+ wanted_oid =
(Oid)zend_u_strtoul(Z_USTRVAL_P(oid), &end_ptr, 10);
+ if ((Z_USTRVAL_P(oid)+Z_USTRLEN_P(oid)) !=
end_ptr) {
+ /* wrong integer format, trailing
non-numeric characters */
+ php_error_docref(NULL TSRMLS_CC,
E_NOTICE, "invalid OID value passed");
+ RETURN_FALSE;
+ }
+ }
+ break;
+ case IS_LONG:
+ if (Z_LVAL_P(oid) < (long)InvalidOid) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE,
"invalid OID value passed");
+ RETURN_FALSE;
+ }
+ wanted_oid = (Oid)Z_LVAL_P(oid);
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID
value passed");
+ RETURN_FALSE;
+ }
+
+ returned_oid = lo_import_with_oid(pgsql, file_in, wanted_oid);
- if (oid == InvalidOid) {
+ if (returned_oid == InvalidOid) {
+ RETURN_FALSE;
+ }
+
+ PGSQL_RETURN_OID(returned_oid);
+#endif
+ }
+
+ returned_oid = lo_import(pgsql, file_in);
+
+ if (returned_oid == InvalidOid) {
RETURN_FALSE;
}
- PGSQL_RETURN_OID(oid);
+ PGSQL_RETURN_OID(returned_oid);
}
/* }}} */
http://cvs.php.net/viewvc.cgi/php-src/ext/pgsql/tests/27large_object_oid.phpt?r1=1.1&r2=1.2&diff_format=u
Index: php-src/ext/pgsql/tests/27large_object_oid.phpt
diff -u /dev/null php-src/ext/pgsql/tests/27large_object_oid.phpt:1.2
--- /dev/null Wed Jul 23 09:27:01 2008
+++ php-src/ext/pgsql/tests/27large_object_oid.phpt Wed Jul 23 09:27:01 2008
@@ -0,0 +1,47 @@
+--TEST--
+PostgreSQL create large object with given oid
+--SKIPIF--
+<?php
+include("skipif.inc");
+$v = pg_version($conn);
+if (version_compare("8.3", $v["client"]) > 0) die("skip - requires pg client
>= 8.3\n");
+if (version_compare("8.3", $v["server"]) > 0) die("skip - requires pg server
>= 8.3\n");
+?>
+--FILE--
+<?php
+
+include('config.inc');
+
+$db = pg_connect($conn_str);
+
+echo "create LO from int\n";
+pg_exec ($db, "begin");
+$oid = pg_lo_create ($db, 21000);
+if (!$oid) echo ("pg_lo_create() error\n");
+if ($oid != 21000) echo ("pg_lo_create() wrong id\n");
+pg_lo_unlink ($db, $oid);
+pg_exec ($db, "commit");
+
+echo "create LO from string\n";
+pg_exec ($db, "begin");
+$oid = pg_lo_create ($db, "21001");
+if (!$oid) echo ("pg_lo_create() error\n");
+if ($oid != 21001) echo ("pg_lo_create() wrong id\n");
+pg_lo_unlink ($db, $oid);
+pg_exec ($db, "commit");
+
+echo "create LO using default connection\n";
+pg_exec ("begin");
+$oid = pg_lo_create (21002);
+if (!$oid) echo ("pg_lo_create() error\n");
+if ($oid != 21002) echo ("pg_lo_create() wrong id\n");
+pg_lo_unlink ($oid);
+pg_exec ("commit");
+
+echo "OK";
+?>
+--EXPECT--
+create LO from int
+create LO from string
+create LO using default connection
+OK
http://cvs.php.net/viewvc.cgi/php-src/ext/pgsql/tests/28large_object_import_oid.phpt?r1=1.1&r2=1.2&diff_format=u
Index: php-src/ext/pgsql/tests/28large_object_import_oid.phpt
diff -u /dev/null php-src/ext/pgsql/tests/28large_object_import_oid.phpt:1.2
--- /dev/null Wed Jul 23 09:27:01 2008
+++ php-src/ext/pgsql/tests/28large_object_import_oid.phpt Wed Jul 23
09:27:01 2008
@@ -0,0 +1,48 @@
+--TEST--
+PostgreSQL import large object with given oid
+--SKIPIF--
+<?php
+include("skipif.inc");
+$v = pg_version($conn);
+if (version_compare("8.4devel", $v["client"]) > 0) die("skip - requires pg
client >= 8.4\n");
+if (version_compare("8.4devel", $v["server"]) > 0) die("skip - requires pg
server >= 8.4\n");
+?>
+--FILE--
+<?php
+
+include('config.inc');
+
+$db = pg_connect($conn_str);
+
+echo "import LO from int\n";
+pg_exec($db, 'begin');
+$oid = pg_lo_import($db, __FILE__, 21003);
+if (!$oid) echo ("pg_lo_import() error\n");
+if ($oid != 21003) echo ("pg_lo_import() wrong id\n");
+pg_lo_unlink ($db, $oid);
+pg_exec($db, 'commit');
+
+echo "import LO from string\n";
+pg_exec($db, 'begin');
+$oid = pg_lo_import($db, __FILE__, "21004");
+if (!$oid) echo ("pg_lo_import() error\n");
+if ($oid != 21004) echo ("pg_lo_import() wrong id\n");
+pg_lo_unlink ($db, $oid);
+pg_exec($db, 'commit');
+
+echo "import LO using default connection\n";
+pg_exec('begin');
+$oid = pg_lo_import($db, __FILE__, 21005);
+if (!$oid) echo ("pg_lo_import() error\n");
+if ($oid != 21005) echo ("pg_lo_import() wrong id\n");
+pg_lo_unlink ($oid);
+pg_exec('commit');
+
+
+echo "OK";
+?>
+--EXPECT--
+import LO from int
+import LO from string
+import LO using default connection
+OK
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php