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