Hartmut Holzgraefe wrote:

i've started looking into the patch yesterday, there are still some
small issues with it though ... i'll provide you with more detailed comments later today or early tomorrow ...

open questions:

 - should the functions return an error if using the specified oid
   isn't possible or just throw a warning and return the oid that
   was actually assigned and used by the server?

changes:

 - there was a mismatch between autoconf macro names and what
   was tested against in the source

 - ZEND_ARG_INFO entries for the new parameter

 - pg_lo_create()

   - option parsing is more lightweight and only
     one #ifdef is needed

   - added a test case file

   - updated documentation

 - pg_lo_import()

   - new parameter is now placed after file name, not before,
     as we usually do with new parameters

   - only one #ifdef block needed

   - updated documentation

   - still need to add a test case, function compiles but
     i haven't tested it yet

 - possible coding style issues, still breaking in a new
   emacs installation ...

--
Hartmut Holzgraefe, MySQL Regional Support Manager EMEA

Sun Microsystems GmbH, Sonnenallee 1, 85551 Kirchheim-Heimstetten
Amtsgericht Muenchen: HRB161028
Geschaeftsfuehrer: Thomas Schroeder, Wolfgang Engels, Dr. Roland Boemer
Vorsitzender des Aufsichtsrates: Martin Haering
diff -rubBwNx CVS 5.3-clean/ext/pgsql/config.m4 5.3/ext/pgsql/config.m4
--- 5.3-clean/ext/pgsql/config.m4	2007-07-11 23:51:55.000000000 +0200
+++ 5.3/ext/pgsql/config.m4	2008-07-06 02:46:48.000000000 +0200
@@ -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
 
diff -rubBwNx CVS 5.3-clean/ext/pgsql/pgsql.c 5.3/ext/pgsql/pgsql.c
--- 5.3-clean/ext/pgsql/pgsql.c	2008-07-02 02:10:54.000000000 +0200
+++ 5.3/ext/pgsql/pgsql.c	2008-07-07 16:23:40.000000000 +0200
@@ -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
@@ -2992,37 +2994,69 @@
 }
 /* }}} */
 
-/* {{{ 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;
+  	zval *pgsql_link = NULL, *oid = NULL;
 	PGconn *pgsql;
-	Oid pgsql_oid;
+  	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 == 0) {
-		id = PGG(default_link);
-		CHECK_DEFAULT_LINK(id);
+	if ((argc == 1) && (Z_TYPE_P(pgsql_link) != IS_RESOURCE)) {
+		oid = pgsql_link;
+		pgsql_link = NULL;
 	}
 
-	if (pgsql_link == NULL && id == -1) {
+	if (pgsql_link == NULL) {
+		id = PGG(default_link);
+		CHECK_DEFAULT_LINK(id);
+		if (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_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");
@@ -3347,26 +3382,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");
@@ -3389,12 +3425,50 @@
 
 	ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
 
-	oid = lo_import(pgsql, file_in);
+	if (oid) {
+#ifndef HAVE_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 */
+				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(oid);
+
+	   PGSQL_RETURN_OID(returned_oid);
+#endif
+	}
+
+	returned_oid = lo_import(pgsql, file_in);
+
+	if (returned_oid == InvalidOid) {
+		RETURN_FALSE;
+	}
+	PGSQL_RETURN_OID(returned_oid);
 }
 /* }}} */
 
diff -rubBwNx CVS 5.3-clean/ext/pgsql/tests/27large_object_oid.phpt 5.3/ext/pgsql/tests/27large_object_oid.phpt
--- 5.3-clean/ext/pgsql/tests/27large_object_oid.phpt	1970-01-01 01:00:00.000000000 +0100
+++ 5.3/ext/pgsql/tests/27large_object_oid.phpt	2008-07-06 19:49:47.000000000 +0200
@@ -0,0 +1,42 @@
+--TEST--
+PostgreSQL large object with given oid
+--SKIPIF--
+<?php include("skipif.inc"); ?>
+--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, "22000");
+if (!$oid) echo ("pg_lo_create() error\n");
+if ($oid != 22000) 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 (23000);
+if (!$oid) echo ("pg_lo_create() error\n");
+if ($oid != 23000) 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
Index: functions/pg-lo-create.xml
===================================================================
RCS file: /repository/phpdoc/en/reference/pgsql/functions/pg-lo-create.xml,v
retrieving revision 1.10
diff -u -r1.10 pg-lo-create.xml
--- functions/pg-lo-create.xml	20 Jun 2007 22:25:13 -0000	1.10
+++ functions/pg-lo-create.xml	7 Jul 2008 14:50:32 -0000
@@ -12,6 +12,7 @@
   <methodsynopsis>
    <type>int</type><methodname>pg_lo_create</methodname>
    <methodparam choice="opt"><type>resource</type><parameter>connection</parameter></methodparam>
+   <methodparam choice="opt"><type>mixed</type><parameter>object_id</parameter></methodparam>
   </methodsynopsis>
   <para>
    <function>pg_lo_create</function> creates a large
@@ -54,10 +55,23 @@
       </para>
      </listitem>
     </varlistentry>
+    <varlistentry>
+     <term><parameter>object_id</parameter></term>
+     <listitem>
+      <para>
+       If an <parameter>object_id</parameter> is given the function
+       will try to create a large object with this id, else a free
+       object id is assigned by the server. The parameter
+       was added in &php; 5.3 and relies on functionality that first
+       appeared in PostgreSQL 8.1.
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </para>
  </refsect1>
 
+
  <refsect1 role="returnvalues">
   &reftitle.returnvalues;
   <para>
@@ -65,6 +79,30 @@
   </para>
  </refsect1>
  
+ <refsect1 role="changelog">
+  &reftitle.changelog;
+  <para>
+   <informaltable>
+    <tgroup cols="2">
+     <thead>
+      <row>
+       <entry>&Version;</entry>
+       <entry>&Description;</entry>
+      </row>
+     </thead>
+     <tbody>
+      <row>
+       <entry>5.3.0</entry>
+       <entry><para>
+        The optional <parameter>object_id</parameter> was added.
+       </para></entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </informaltable>
+  </para>
+ </refsect1>
+
  <refsect1 role="examples">
   &reftitle.examples;
   <para>
Index: functions/pg-lo-import.xml
===================================================================
RCS file: /repository/phpdoc/en/reference/pgsql/functions/pg-lo-import.xml,v
retrieving revision 1.11
diff -u -r1.11 pg-lo-import.xml
--- functions/pg-lo-import.xml	20 Jun 2007 22:25:13 -0000	1.11
+++ functions/pg-lo-import.xml	7 Jul 2008 14:50:32 -0000
@@ -59,6 +59,18 @@
       </para>
      </listitem>
     </varlistentry>
+    <varlistentry>
+     <term><parameter>object_id</parameter></term>
+     <listitem>
+      <para>
+       If an <parameter>object_id</parameter> is given the function
+       will try to create a large object with this id, else a free
+       object id is assigned by the server. The parameter
+       was added in &php; 5.3 and relies on functionality that first
+       appeared in PostgreSQL 8.1.
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </para>
  </refsect1>
@@ -84,6 +96,12 @@
      </thead>
      <tbody>
       <row>
+       <entry>5.3.0</entry>
+       <entry><para>
+        The optional <parameter>object_id</parameter> was added.
+       </para></entry>
+      </row>
+      <row>
        <entry>4.2.0</entry>
        <entry><para>
         The syntax of this function changed. It used to be:

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to