mirror of
https://github.com/php/php-src.git
synced 2024-12-19 15:00:15 +08:00
MFB + Unicode:
added support for object ids in pg_lo_create() and pg_lo_import() where available (based on code provided by Tatsuo Ishii)
This commit is contained in:
parent
0225470dc5
commit
d11e0df7ad
@ -92,6 +92,8 @@ if test "$PHP_PGSQL" != "no"; then
|
||||
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
|
||||
|
||||
|
@ -350,6 +350,7 @@ ZEND_END_ARG_INFO()
|
||||
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 @@ static
|
||||
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 @@ PHP_FUNCTION(pg_untrace)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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 @@ PHP_FUNCTION(pg_lo_read_all)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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 @@ PHP_FUNCTION(pg_lo_import)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (oid == InvalidOid) {
|
||||
returned_oid = lo_import_with_oid(pgsql, file_in, wanted_oid);
|
||||
|
||||
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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
47
ext/pgsql/tests/27large_object_oid.phpt
Normal file
47
ext/pgsql/tests/27large_object_oid.phpt
Normal file
@ -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
|
48
ext/pgsql/tests/28large_object_import_oid.phpt
Normal file
48
ext/pgsql/tests/28large_object_import_oid.phpt
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user