aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1998-01-11 21:14:56 +0000
committerMarc G. Fournier <scrappy@hub.org>1998-01-11 21:14:56 +0000
commitba977c086c01726affcc96219a79584a11ccc78e (patch)
tree209fc13fa5b540fdaf17711a26338ad6a35e6367
parent4bad5be7bc7fa1ea973e0b83046b82f9fd5984c5 (diff)
downloadpostgresql-ba977c086c01726affcc96219a79584a11ccc78e.tar.gz
postgresql-ba977c086c01726affcc96219a79584a11ccc78e.zip
Peter's Mega-Patch for JDBC...
see README_6.3 for list of changes
-rw-r--r--src/interfaces/jdbc/Makefile112
-rw-r--r--src/interfaces/jdbc/README22
-rw-r--r--src/interfaces/jdbc/README_6.378
-rw-r--r--src/interfaces/jdbc/postgresql/CallableStatement.java234
-rw-r--r--src/interfaces/jdbc/postgresql/Connection.java244
-rw-r--r--src/interfaces/jdbc/postgresql/DatabaseMetaData.java452
-rw-r--r--src/interfaces/jdbc/postgresql/Driver.java40
-rw-r--r--src/interfaces/jdbc/postgresql/Field.java122
-rw-r--r--src/interfaces/jdbc/postgresql/PG_Stream.java36
-rw-r--r--src/interfaces/jdbc/postgresql/PreparedStatement.java125
-rw-r--r--src/interfaces/jdbc/postgresql/ResultSet.java94
-rw-r--r--src/interfaces/jdbc/postgresql/ResultSetMetaData.java3
-rw-r--r--src/interfaces/jdbc/postgresql/Statement.java20
13 files changed, 1276 insertions, 306 deletions
diff --git a/src/interfaces/jdbc/Makefile b/src/interfaces/jdbc/Makefile
index 469b552a699..928aafae5ef 100644
--- a/src/interfaces/jdbc/Makefile
+++ b/src/interfaces/jdbc/Makefile
@@ -4,7 +4,7 @@
# Makefile for Java JDBC interface
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.2 1997/09/29 20:11:42 scrappy Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.3 1998/01/11 21:14:29 scrappy Exp $
#
#-------------------------------------------------------------------------
@@ -22,41 +22,70 @@ RM = rm -f
$(JAVAC) $<
.SUFFIXES: .class .java
-.PHONY: all clean doc
+.PHONY: all clean doc examples
all: postgresql.jar
+ @echo ------------------------------------------------------------
+ @echo The JDBC driver has now been built. To make it available to
+ @echo other applications, copy the postgresql.jar file to a public
+ @echo "place (under unix this could be /usr/local/lib) and add it"
+ @echo to the class path.
+ @echo
+ @echo Then either add -Djdbc.drivers=postgresql.Driver to the
+ @echo commandline when running your application, or edit the
+ @echo "properties file (~/.hotjava/properties under unix), and"
+ @echo add a line containing jdbc.drivers=postgresql.Driver
+ @echo
+ @echo More details are in the README file.
+ @echo ------------------------------------------------------------
+ @echo To build the examples, type:
+ @echo " make examples"
+ @echo ------------------------------------------------------------
+ @echo
+# This rule builds the javadoc documentation
doc:
- $(JAVADOC) -public postgresql
+ export CLASSPATH=.;\
+ $(JAVADOC) -public \
+ postgresql \
+ postgresql.fastpath \
+ postgresql.largeobject
+# These classes form the driver. These, and only these are placed into
+# the jar file.
OBJS= postgresql/CallableStatement.class \
postgresql/Connection.class \
postgresql/DatabaseMetaData.class \
postgresql/Driver.class \
postgresql/Field.class \
- postgresql/PG_Object.class \
postgresql/PG_Stream.class \
- postgresql/PGbox.class \
- postgresql/PGcircle.class \
- postgresql/PGlobj.class \
- postgresql/PGlseg.class \
- postgresql/PGpath.class \
- postgresql/PGpoint.class \
- postgresql/PGpolygon.class \
- postgresql/PGtokenizer.class \
postgresql/PreparedStatement.class \
postgresql/ResultSet.class \
postgresql/ResultSetMetaData.class \
- postgresql/Statement.class
+ postgresql/Statement.class \
+ postgresql/fastpath/Fastpath.class \
+ postgresql/fastpath/FastpathArg.class \
+ postgresql/geometric/PGbox.class \
+ postgresql/geometric/PGcircle.class \
+ postgresql/geometric/PGlseg.class \
+ postgresql/geometric/PGpath.class \
+ postgresql/geometric/PGpoint.class \
+ postgresql/geometric/PGpolygon.class \
+ postgresql/largeobject/LargeObject.class \
+ postgresql/largeobject/LargeObjectManager.class \
+ postgresql/util/PGobject.class \
+ postgresql/util/PGtokenizer.class
postgresql.jar: $(OBJS)
- $(JAR) -c0vf $@ $^
+ $(JAR) -c0vf $@ $$($(FIND) postgresql -name "*.class" -print)
# This rule removes any temporary and compiled files from the source tree.
clean:
$(FIND) . -name "*~" -exec $(RM) {} \;
$(FIND) . -name "*.class" -exec $(RM) {} \;
+ $(FIND) . -name "*.html" -exec $(RM) {} \;
$(RM) postgresql.jar
+ -$(RM) -rf Package-postgresql *output
#######################################################################
# This helps make workout what classes are from what source files
@@ -69,21 +98,56 @@ postgresql/Connection.class: postgresql/Connection.java
postgresql/DatabaseMetaData.class: postgresql/DatabaseMetaData.java
postgresql/Driver.class: postgresql/Driver.java
postgresql/Field.class: postgresql/Field.java
-postgresql/PG_Object.class: postgresql/PG_Object.java
postgresql/PG_Stream.class: postgresql/PG_Stream.java
-postgresql/PGbox.class: postgresql/PGbox.java
-postgresql/PGcircle.class: postgresql/PGcircle.java
-postgresql/PGlobj.class: postgresql/PGlobj.java
-postgresql/PGlseg.class: postgresql/PGlseg.java
-postgresql/PGpath.class: postgresql/PGpath.java
-postgresql/PGpoint.class: postgresql/PGpoint.java
-postgresql/PGpolygon.class: postgresql/PGpolygon.java
-postgresql/PGtokenizer.class: postgresql/PGtokenizer.java
postgresql/PreparedStatement.class: postgresql/PreparedStatement.java
postgresql/ResultSet.class: postgresql/ResultSet.java
postgresql/ResultSetMetaData.class: postgresql/ResultSetMetaData.java
postgresql/Statement.class: postgresql/Statement.java
+postgresql/fastpath/Fastpath.class: postgresql/fastpath/Fastpath.java
+postgresql/fastpath/FastpathArg.class: postgresql/fastpath/FastpathArg.java
+postgresql/geometric/PGbox.class: postgresql/geometric/PGbox.java
+postgresql/geometric/PGcircle.class: postgresql/geometric/PGcircle.java
+postgresql/geometric/PGlseg.class: postgresql/geometric/PGlseg.java
+postgresql/geometric/PGpath.class: postgresql/geometric/PGpath.java
+postgresql/geometric/PGpoint.class: postgresql/geometric/PGpoint.java
+postgresql/geometric/PGpolygon.class: postgresql/geometric/PGpolygon.java
+postgresql/largeobject/LargeObject.class: postgresql/largeobject/LargeObject.java
+postgresql/largeobject/LargeObjectManager.class: postgresql/largeobject/LargeObjectManager.java
+postgresql/util/PGobject.class: postgresql/util/PGobject.java
+postgresql/util/PGtokenizer.class: postgresql/util/PGtokenizer.java
+#######################################################################
+# These classes are in the example directory, and form the examples
+EX= example/basic.class \
+ example/blobtest.class \
+ example/datestyle.class \
+ example/psql.class \
+ example/ImageViewer.class
+# This rule builds the examples
+examples: postgresql.jar $(EX)
+ @echo ------------------------------------------------------------
+ @echo The examples have been built.
+ @echo
+ @echo For instructions on how to use them, simply run them. For example:
+ @echo
+ @echo " java example.blobtest"
+ @echo
+ @echo This would display instructions on how to run the example.
+ @echo ------------------------------------------------------------
+ @echo Available examples:
+ @echo
+ @echo " example.basic Basic JDBC useage"
+ @echo " example.blobtest Binary Large Object tests"
+ @echo " example.datestyle Shows how datestyles are handled"
+ @echo " example.ImageViewer Example application storing images"
+ @echo " example.psql Simple java implementation of psql"
+ @echo ------------------------------------------------------------
+ @echo
-
+example/basic.class: example/basic.java
+example/blobtest.class: example/blobtest.java
+example/datestyle.class: example/datestyle.java
+example/psql.class: example/psql.java
+example/ImageViewer.class: example/ImageViewer.java
+#######################################################################
diff --git a/src/interfaces/jdbc/README b/src/interfaces/jdbc/README
index cd43a5af2f3..035ad008bf3 100644
--- a/src/interfaces/jdbc/README
+++ b/src/interfaces/jdbc/README
@@ -10,6 +10,14 @@ or the JDBC mailing list:
http://www.blackdown.org
+For problems with this driver, then refer to the postgres-interfaces email
+list:
+
+ http://www.postgresql.org
+
+By the time V6.3 is released, full documentation will be on the web, and in
+the distribution.
+
---------------------------------------------------------------------------
COMPILING
@@ -115,15 +123,21 @@ them to the URL. eg:
By default, the driver doesn't use password authentication. You can enable
this by adding the argument auth. ie:
- jdbc:postgresql:database?user=me&password=mypass&auth=y
+ jdbc:postgresql:database?user=me&password=mypass&auth=password
or if passing the user & password directly via DriverManager.getConnection():
- jdbc:postgresql:database?auth=y
+ jdbc:postgresql:database?auth=password
-PS: Password authentication is enabled if the value of auth starts with 'y'.
+PS: Password authentication is enabled if the value of auth starts with 'p'.
It is case insensitive.
+As of postgresql 6.3, Ident (RFC 1413) authentication is also supported.
+Simply use auth=ident in the url.
+
+Also, as of 6.3, a system property of postgresql.auth is supported. This
+defines the default authentication to use. The auth property overides this.
+
---------------------------------------------------------------------------
That's the basics related to this driver. You'll need to read the JDBC Docs
@@ -180,7 +194,7 @@ syntax for writing these to the database.
---------------------------------------------------------------------------
-Peter T Mount, October 28 1997
+Peter T Mount, January 11 1998
home email: pmount@maidast.demon.co.uk http://www.demon.co.uk/finder
work email: peter@maidstone.gov.uk http://www.maidstone.gov.uk
diff --git a/src/interfaces/jdbc/README_6.3 b/src/interfaces/jdbc/README_6.3
new file mode 100644
index 00000000000..797d3ff99b7
--- /dev/null
+++ b/src/interfaces/jdbc/README_6.3
@@ -0,0 +1,78 @@
+Ok, here's the JDBC patch.
+
+The jdbc6.3.tar.gz file that I've uploaded ftp.postgresql.org contains the
+following files:
+
+README_6.3 This message
+blob.patch The patch to src/backend/tcop/fastpath.c fixing large objects
+jdbc.tar The entire jdbc driver
+
+I've put the entire driver here, rather than a patch, because its become
+too complicated to do one this time. Files have been moved, two files
+removed because they were obsolete, and there are a lot of new files.
+
+Heres what the patch does:
+
+* Memory overflow problem in the backend causing large objects to fail in
+ both libpq & jdbc (causing the backend to crash with a Segmentation
+ Violation)
+* Problem with equals() method on the geometric support classes if the
+ class being checked wasn't the same class
+* Fixed output of PGpath and PGpolygon support classes (missing , separator)
+* Optimised the geometric support classes
+* HTMLised the inline documentation, so the output of javadoc is easier
+ to read (mainly paragraphs)
+* Removed obsolete class PGlobj (it never worked, and has been replaced
+ to read (mainly paragraphs)
+* Removed obsolete class PGlobj (it never worked, and has been replaced
+ by the postgresql.largeobject package)
+* Removed obsolete example JDBC_Test.java (replaced by new examples)
+* Added < and > to nesting in PGtokenizer.
+* Added fastpath support as a new package
+* Added large object support as a new package
+* Added ability of user code to handle custom storage types.
+* Added new example testing the importing and exporting of a large object
+* Added example application showing how to store and display images stored
+ as large objects
+* Added example implementing part of psql client. This shows how to find out
+ what tables/columns are in a database (not yet complete)
+* ResultSet.getBytes() now returns large object if field is an oid
+* ResultSet.getString() now doesn't call getBytes() as this now would
+ cause an infinite loop because of large object support in getBytes()
+* PreparedStatement.setBytes() now create a large object, and store its
+ oid into the column
+* Reworked date style handling to make it easier to support new styles
+* Added german and ISO styles, now all styles supported by postgresql
+ are now supported by the driver
+* Fixed DatabaseMetaData.getTables()
+* DatabaseMetaData.getTableTypes() returns our supported types.
+* Fixed DatabaseMetaData.getColumns()
+
+These three are required for Borland's JBuilder to work. For now they
+return an empty result, as I'm not sure yet on how to get the
+required results.
+* DatabaseMetaData.getBestRowIdentifier()
+* DatabaseMetaData.getProcedureColumns()
+* DatabaseMetaData.getIndexInfo()
+
+Finally, one change that is incompatible with earlier versions of the
+driver. This change only affects any client code that uses the geometric
+classes (eg: PGpoint) or the getObject()/setObject() methods.
+
+Because of a problem with javac, if user code includes the line:
+
+import postgresql.*;
+
+then javac will fail, saying that interfaces cannot be instanciated.
+
+To fix this, I've moved these classes into a new sub package,
+postgresql.geometric and the PG_Object (renamed PGobject), and PGtokenizer
+to postgresql.util.So the above line would become:
+
+import postgresql.geometric.*;
+
+Anyhow, I'm going to start writing some proper documentation for the
+driver. For now, there is some available temporarily at:
+
+ http://www.demon.co.uk/finder/postgres/jdbc/packages.html
+
diff --git a/src/interfaces/jdbc/postgresql/CallableStatement.java b/src/interfaces/jdbc/postgresql/CallableStatement.java
index ede69bbb121..7f56a42b2a5 100644
--- a/src/interfaces/jdbc/postgresql/CallableStatement.java
+++ b/src/interfaces/jdbc/postgresql/CallableStatement.java
@@ -4,46 +4,114 @@ import java.sql.*;
import java.math.*;
/**
- * JDBC Interface to Postgres95 functions
+ * CallableStatement is used to execute SQL stored procedures.
+ *
+ * <p>JDBC provides a stored procedure SQL escape that allows stored
+ * procedures to be called in a standard way for all RDBMS's. This escape
+ * syntax has one form that includes a result parameter and one that does
+ * not. If used, the result parameter must be registered as an OUT
+ * parameter. The other parameters may be used for input, output or both.
+ * Parameters are refered to sequentially, by number. The first parameter
+ * is 1.
+ *
+ * {?= call <procedure-name>[<arg1>,<arg2>, ...]}
+ * {call <procedure-name>[<arg1>,<arg2>, ...]}
+ *
+ *
+ * <p>IN parameter values are set using the set methods inherited from
+ * PreparedStatement. The type of all OUT parameters must be registered
+ * prior to executing the stored procedure; their values are retrieved
+ * after execution via the get methods provided here.
+ *
+ * <p>A Callable statement may return a ResultSet or multiple ResultSets.
+ * Multiple ResultSets are handled using operations inherited from
+ * Statement.
+ *
+ * <p>For maximum portability, a call's ResultSets and update counts should
+ * be processed prior to getting the values of output parameters.
+ *
+ * @see Connection#prepareCall
+ * @see ResultSet
*/
-// Copy methods from the Result set object here.
-
public class CallableStatement extends PreparedStatement implements java.sql.CallableStatement
{
+ /**
+ * @exception SQLException on failure
+ */
CallableStatement(Connection c,String q) throws SQLException
{
super(c,q);
}
- // Before executing a stored procedure call you must explicitly
- // call registerOutParameter to register the java.sql.Type of each
- // out parameter.
+ /**
+ * Before executing a stored procedure call you must explicitly
+ * call registerOutParameter to register the java.sql.Type of each
+ * out parameter.
+ *
+ * <p>Note: When reading the value of an out parameter, you must use
+ * the getXXX method whose Java type XXX corresponds to the
+ * parameter's registered SQL type.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @param sqlType SQL type code defined by java.sql.Types; for
+ * parameters of type Numeric or Decimal use the version of
+ * registerOutParameter that accepts a scale value
+ * @exception SQLException if a database-access error occurs.
+ */
public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
}
- // You must also specify the scale for numeric/decimal types:
+ /**
+ * You must also specify the scale for numeric/decimal types:
+ *
+ * <p>Note: When reading the value of an out parameter, you must use
+ * the getXXX method whose Java type XXX corresponds to the
+ * parameter's registered SQL type.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @param sqlType use either java.sql.Type.NUMERIC or java.sql.Type.DECIMAL
+ * @param scale a value greater than or equal to zero representing the
+ * desired number of digits to the right of the decimal point
+ * @exception SQLException if a database-access error occurs.
+ */
public void registerOutParameter(int parameterIndex, int sqlType,
int scale) throws SQLException
{
}
- public boolean isNull(int parameterIndex) throws SQLException {
- return true;
- }
+ // Old api?
+ //public boolean isNull(int parameterIndex) throws SQLException {
+ //return true;
+ //}
- // New API (JPM)
+ /**
+ * An OUT parameter may have the value of SQL NULL; wasNull
+ * reports whether the last value read has this special value.
+ *
+ * <p>Note: You must first call getXXX on a parameter to read its
+ * value and then call wasNull() to see if the value was SQL NULL.
+ * @return true if the last parameter read was SQL NULL
+ * @exception SQLException if a database-access error occurs.
+ */
public boolean wasNull() throws SQLException {
// check to see if the last access threw an exception
return false; // fake it for now
}
- // Methods for retrieving OUT parameters from this statement.
- public String getChar(int parameterIndex) throws SQLException {
- return null;
- }
+ // Old api?
+ //public String getChar(int parameterIndex) throws SQLException {
+ //return null;
+ //}
- // New API (JPM)
+ /**
+ * Get the value of a CHAR, VARCHAR, or LONGVARCHAR parameter as a
+ * Java String.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is null
+ * @exception SQLException if a database-access error occurs.
+ */
public String getString(int parameterIndex) throws SQLException {
return null;
}
@@ -51,64 +119,148 @@ public class CallableStatement extends PreparedStatement implements java.sql.Cal
// return null;
//}
- public String getLongVarChar(int parameterIndex) throws SQLException {
- return null;
- }
+ //public String getLongVarChar(int parameterIndex) throws SQLException {
+ //return null;
+ //}
- // New API (JPM) (getBit)
+ /**
+ * Get the value of a BIT parameter as a Java boolean.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is false
+ * @exception SQLException if a database-access error occurs.
+ */
public boolean getBoolean(int parameterIndex) throws SQLException {
return false;
}
- // New API (JPM) (getTinyInt)
+ /**
+ * Get the value of a TINYINT parameter as a Java byte.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is 0
+ * @exception SQLException if a database-access error occurs.
+ */
public byte getByte(int parameterIndex) throws SQLException {
return 0;
}
- // New API (JPM) (getSmallInt)
+ /**
+ * Get the value of a SMALLINT parameter as a Java short.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is 0
+ * @exception SQLException if a database-access error occurs.
+ */
public short getShort(int parameterIndex) throws SQLException {
return 0;
}
- // New API (JPM) (getInteger)
- public int getInt(int parameterIndex) throws SQLException {
+ /**
+ * Get the value of an INTEGER parameter as a Java int.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is 0
+ * @exception SQLException if a database-access error occurs.
+ */
+public int getInt(int parameterIndex) throws SQLException {
return 0;
}
- // New API (JPM) (getBigInt)
+ /**
+ * Get the value of a BIGINT parameter as a Java long.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is 0
+ * @exception SQLException if a database-access error occurs.
+ */
public long getLong(int parameterIndex) throws SQLException {
return 0;
}
+ /**
+ * Get the value of a FLOAT parameter as a Java float.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is 0
+ * @exception SQLException if a database-access error occurs.
+ */
public float getFloat(int parameterIndex) throws SQLException {
return (float) 0.0;
}
+ /**
+ * Get the value of a DOUBLE parameter as a Java double.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is 0
+ * @exception SQLException if a database-access error occurs.
+ */
public double getDouble(int parameterIndex) throws SQLException {
return 0.0;
}
+ /**
+ * Get the value of a NUMERIC parameter as a java.math.BigDecimal
+ * object.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @param scale a value greater than or equal to zero representing the
+ * desired number of digits to the right of the decimal point
+ * @return the parameter value; if the value is SQL NULL, the result is null
+ * @exception SQLException if a database-access error occurs.
+ */
public BigDecimal getBigDecimal(int parameterIndex, int scale)
throws SQLException {
return null;
}
- // New API (JPM) (getBinary)
+ /**
+ * Get the value of a SQL BINARY or VARBINARY parameter as a Java
+ * byte[]
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is null
+ * @exception SQLException if a database-access error occurs.
+ */
public byte[] getBytes(int parameterIndex) throws SQLException {
return null;
}
// New API (JPM) (getLongVarBinary)
- public byte[] getBinaryStream(int parameterIndex) throws SQLException {
- return null;
- }
+ //public byte[] getBinaryStream(int parameterIndex) throws SQLException {
+ //return null;
+ //}
+ /**
+ * Get the value of a SQL DATE parameter as a java.sql.Date object
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is null
+ * @exception SQLException if a database-access error occurs.
+ */
public java.sql.Date getDate(int parameterIndex) throws SQLException {
return null;
}
+
+ /**
+ * Get the value of a SQL TIME parameter as a java.sql.Time object.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is null
+ * @exception SQLException if a database-access error occurs.
+ */
public java.sql.Time getTime(int parameterIndex) throws SQLException {
return null;
}
+
+ /**
+ * Get the value of a SQL TIMESTAMP parameter as a java.sql.Timestamp object.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return the parameter value; if the value is SQL NULL, the result is null
+ * @exception SQLException if a database-access error occurs.
+ */
public java.sql.Timestamp getTimestamp(int parameterIndex)
throws SQLException {
return null;
@@ -119,12 +271,30 @@ public class CallableStatement extends PreparedStatement implements java.sql.Cal
// You can obtain a ParameterMetaData object to get information
// about the parameters to this CallableStatement.
- public DatabaseMetaData getMetaData() {
- return null;
- }
+ //public DatabaseMetaData getMetaData() {
+ //return null;
+ //}
// getObject returns a Java object for the parameter.
// See the JDBC spec's "Dynamic Programming" chapter for details.
+ /**
+ * Get the value of a parameter as a Java object.
+ *
+ * <p>This method returns a Java object whose type coresponds to the
+ * SQL type that was registered for this parameter using
+ * registerOutParameter.
+ *
+ * <P>Note that this method may be used to read datatabase-specific,
+ * abstract data types. This is done by specifying a targetSqlType
+ * of java.sql.types.OTHER, which allows the driver to return a
+ * database-specific Java type.
+ *
+ * <p>See the JDBC spec's "Dynamic Programming" chapter for details.
+ *
+ * @param parameterIndex the first parameter is 1, the second is 2,...
+ * @return A java.lang.Object holding the OUT parameter value.
+ * @exception SQLException if a database-access error occurs.
+ */
public Object getObject(int parameterIndex)
throws SQLException {
return null;
diff --git a/src/interfaces/jdbc/postgresql/Connection.java b/src/interfaces/jdbc/postgresql/Connection.java
index 09344e1fe08..1c13b520d5b 100644
--- a/src/interfaces/jdbc/postgresql/Connection.java
+++ b/src/interfaces/jdbc/postgresql/Connection.java
@@ -5,22 +5,21 @@ import java.lang.*;
import java.net.*;
import java.util.*;
import java.sql.*;
-import postgresql.*;
+import postgresql.fastpath.*;
+import postgresql.largeobject.*;
+import postgresql.util.*;
/**
- * @version 1.0 15-APR-1997
- * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
- *
* A Connection represents a session with a specific database. Within the
* context of a Connection, SQL statements are executed and results are
* returned.
*
- * A Connection's database is able to provide information describing
+ * <P>A Connection's database is able to provide information describing
* its tables, its supported SQL grammar, its stored procedures, the
* capabilities of this connection, etc. This information is obtained
* with the getMetaData method.
*
- * <B>Note:</B> By default, the Connection automatically commits changes
+ * <p><B>Note:</B> By default, the Connection automatically commits changes
* after executing each statement. If auto-commit has been disabled, an
* explicit commit must be done or database changes will not be saved.
*
@@ -28,8 +27,12 @@ import postgresql.*;
*/
public class Connection implements java.sql.Connection
{
+ // This is the network stream associated with this connection
protected PG_Stream pg_stream;
+ // This is set by postgresql.Statement.setMaxRows()
+ protected int maxrows = 0; // maximum no. of rows; 0 = unlimited
+
private String PG_HOST;
private int PG_PORT;
private String PG_USER;
@@ -59,7 +62,39 @@ public class Connection implements java.sql.Connection
private String cursor = null; // The positioned update cursor name
// This is false for US, true for European date formats
- protected boolean europeanDates = false;
+ //protected boolean europeanDates = false;
+
+ /**
+ * This is the current date style of the backend
+ */
+ protected int currentDateStyle;
+
+ /**
+ * This defines the formats for dates, according to the various date styles.
+ *
+ * <p>There are two strings for each entry. The first is the string to search
+ * for in the datestyle message, and the second the format to use.
+ *
+ * <p>To add a new date style, work out the format. Then with psql running
+ * in the date style you wish to add, type: show datestyle;
+ *
+ * <p>eg:
+ * <br><pre>
+ * => show datestyle;
+ * NOTICE: Datestyle is SQL with European conventions
+ * ^^^^^^^^^^^^^^^^^
+ * </pre>The marked part of the string is the first string below. The second
+ * is your format. If a style (like ISO) ignores the US/European variants,
+ * then you can ignore the "with" part of the string.
+ */
+ protected static final String dateStyles[] = {
+ "Postgres with European", "dd-MM-yyyy",
+ "Postgres with US", "MM-dd-yyyy",
+ "ISO", "yyyy-MM-dd",
+ "SQL with European", "dd/MM/yyyy",
+ "SQL with US", "MM/dd/yyyy",
+ "German", "dd.MM.yyyy"
+ };
// Now handle notices as warnings, so things like "show" now work
protected SQLWarning firstWarning = null;
@@ -67,6 +102,13 @@ public class Connection implements java.sql.Connection
/**
* Connect to a PostgreSQL database back end.
*
+ * <p><b>Important Notice</b>
+ *
+ * <br>Although this will connect to the database, user code should open
+ * the connection via the DriverManager.getConnection() methods only.
+ *
+ * <br>This should only be called from the postgresql.Driver class.
+ *
* @param host the hostname of the database back end
* @param port the port number of the postmaster process
* @param info a Properties[] thing of the user and password
@@ -108,6 +150,7 @@ public class Connection implements java.sql.Connection
STARTUP_CODE=STARTUP_USER;
}
+ // Now make the initial connection
try
{
pg_stream = new PG_Stream(host, port);
@@ -148,6 +191,9 @@ public class Connection implements java.sql.Connection
clearWarnings();
ExecSQL("show datestyle");
+ // Initialise object handling
+ initObjectTypes();
+
// Mark the connection as ok, and cleanup
clearWarnings();
PG_STATUS = CONNECTION_OK;
@@ -468,10 +514,15 @@ public class Connection implements java.sql.Connection
// **********************************************************
/**
- * This adds a warning to the warning chain
+ * This adds a warning to the warning chain.
+ * @param msg message to add
*/
public void addWarning(String msg)
{
+ //PrintStream log = DriverManager.getLogStream();
+ //if(log!=null)
+ DriverManager.println(msg);
+
// Add the warning to the chain
if(firstWarning!=null)
firstWarning.setNextWarning(new SQLWarning(msg));
@@ -481,16 +532,25 @@ public class Connection implements java.sql.Connection
// Now check for some specific messages
// This is generated by the SQL "show datestyle"
- if(msg.startsWith("NOTICE:DateStyle")) {
- if(msg.indexOf("with US")==-1)
- europeanDates=true;
- else
- europeanDates=false;
- System.err.println("europeanDates="+europeanDates);
+ if(msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) {
+ // 13 is the length off "DateStyle is "
+ msg = msg.substring(msg.indexOf("DateStyle is ")+13);
+
+ for(int i=0;i<dateStyles.length;i+=2)
+ if(msg.startsWith(dateStyles[i]))
+ currentDateStyle=i+1; // this is the index of the format
}
}
/**
+ * @return the date format for the current date style of the backend
+ */
+ public String getDateStyle()
+ {
+ return dateStyles[currentDateStyle];
+ }
+
+ /**
* Send a query to the backend. Returns one of the ResultSet
* objects.
*
@@ -525,6 +585,8 @@ public class Connection implements java.sql.Connection
while (!hfr || fqp > 0)
{
+ Object tup=null; // holds rows as they are recieved
+
int c = pg_stream.ReceiveChar();
switch (c)
@@ -536,7 +598,10 @@ public class Connection implements java.sql.Connection
case 'B': // Binary Data Transfer
if (fields == null)
throw new SQLException("Tuple received before MetaData");
- tuples.addElement(pg_stream.ReceiveTuple(fields.length, true));
+ tup = pg_stream.ReceiveTuple(fields.length, true);
+ // This implements Statement.setMaxRows()
+ if(maxrows==0 || tuples.size()<maxrows)
+ tuples.addElement(tup);
break;
case 'C': // Command Status
recv_status = pg_stream.ReceiveString(8192);
@@ -558,7 +623,10 @@ public class Connection implements java.sql.Connection
case 'D': // Text Data Transfer
if (fields == null)
throw new SQLException("Tuple received before MetaData");
- tuples.addElement(pg_stream.ReceiveTuple(fields.length, false));
+ tup = pg_stream.ReceiveTuple(fields.length, false);
+ // This implements Statement.setMaxRows()
+ if(maxrows==0 || tuples.size()<maxrows)
+ tuples.addElement(tup);
break;
case 'E': // Error Message
msg = pg_stream.ReceiveString(4096);
@@ -576,10 +644,7 @@ public class Connection implements java.sql.Connection
hfr = true;
break;
case 'N': // Error Notification
- msg = pg_stream.ReceiveString(4096);
- PrintStream log = DriverManager.getLogStream();
- if(log!=null) log.println(msg);
- addWarning(msg);
+ addWarning(pg_stream.ReceiveString(4096));
break;
case 'P': // Portal Name
String pname = pg_stream.ReceiveString(8192);
@@ -675,14 +740,143 @@ public class Connection implements java.sql.Connection
}
/**
- * This method is not part of the Connection interface. Its is an extension
- * that allows access to the PostgreSQL Large Object API
+ * This returns the Fastpath API for the current connection.
+ *
+ * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
+ * functions on the postgresql backend itself.
+ *
+ * <p>It is primarily used by the LargeObject API
+ *
+ * <p>The best way to use this is as follows:
+ *
+ * <p><pre>
+ * import postgresql.fastpath.*;
+ * ...
+ * Fastpath fp = ((postgresql.Connection)myconn).getFastpathAPI();
+ * </pre>
+ *
+ * <p>where myconn is an open Connection to postgresql.
+ *
+ * @return Fastpath object allowing access to functions on the postgresql
+ * backend.
+ * @exception SQLException by Fastpath when initialising for first time
+ */
+ public Fastpath getFastpathAPI() throws SQLException
+ {
+ if(fastpath==null)
+ fastpath = new Fastpath(this,pg_stream);
+ return fastpath;
+ }
+
+ // This holds a reference to the Fastpath API if already open
+ private Fastpath fastpath = null;
+
+ /**
+ * This returns the LargeObject API for the current connection.
+ *
+ * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
+ * functions on the postgresql backend itself.
+ *
+ * <p>The best way to use this is as follows:
+ *
+ * <p><pre>
+ * import postgresql.largeobject.*;
+ * ...
+ * LargeObjectManager lo = ((postgresql.Connection)myconn).getLargeObjectAPI();
+ * </pre>
+ *
+ * <p>where myconn is an open Connection to postgresql.
+ *
+ * @return LargeObject object that implements the API
+ * @exception SQLException by LargeObject when initialising for first time
+ */
+ public LargeObjectManager getLargeObjectAPI() throws SQLException
+ {
+ if(largeobject==null)
+ largeobject = new LargeObjectManager(this);
+ return largeobject;
+ }
+
+ // This holds a reference to the LargeObject API if already open
+ private LargeObjectManager largeobject = null;
+
+ /**
+ * This method is used internally to return an object based around
+ * postgresql's more unique data types.
+ *
+ * <p>It uses an internal Hashtable to get the handling class. If the
+ * type is not supported, then an instance of postgresql.util.PGobject
+ * is returned.
*
- * @return PGlobj class that implements the API
+ * You can use the getValue() or setValue() methods to handle the returned
+ * object. Custom objects can have their own methods.
+ *
+ * @return PGobject for this type, and set to value
+ * @exception SQLException if value is not correct for this type
*/
- public PGlobj getLargeObjectAPI() throws SQLException
+ protected PGobject getObject(String type,String value) throws SQLException
+ {
+ PGobject obj = null;
+ try {
+ String name = (String)objectTypes.get(type);
+ obj = (PGobject)(Class.forName(name==null?"postgresql.util.PGobject":name).newInstance());
+ } catch(Exception ex) {
+ throw new SQLException("Failed to create object for "+type+": "+ex);
+ }
+ if(obj!=null) {
+ obj.setType(type);
+ obj.setValue(value);
+ }
+ return obj;
+ }
+
+ /**
+ * This allows client code to add a handler for one of postgresql's
+ * more unique data types.
+ *
+ * <p><b>NOTE:</b> This is not part of JDBC, but an extension.
+ *
+ * <p>The best way to use this is as follows:
+ *
+ * <p><pre>
+ * ...
+ * ((postgresql.Connection)myconn).addDataType("mytype","my.class.name");
+ * ...
+ * </pre>
+ *
+ * <p>where myconn is an open Connection to postgresql.
+ *
+ * <p>The handling class must extend postgresql.util.PGobject
+ *
+ * @see postgresql.util.PGobject
+ */
+ public void addDataType(String type,String name)
+ {
+ objectTypes.put(type,name);
+ }
+
+ // This holds the available types
+ private Hashtable objectTypes = new Hashtable();
+
+ // This array contains the types that are supported as standard.
+ //
+ // The first entry is the types name on the database, the second
+ // the full class name of the handling class.
+ //
+ private static final String defaultObjectTypes[][] = {
+ {"box", "postgresql.geometric.PGbox"},
+ {"circle", "postgresql.geometric.PGcircle"},
+ {"lseg", "postgresql.geometric.PGlseg"},
+ {"path", "postgresql.geometric.PGpath"},
+ {"point", "postgresql.geometric.PGpoint"},
+ {"polygon", "postgresql.geometric.PGpolygon"}
+ };
+
+ // This initialises the objectTypes hashtable
+ private void initObjectTypes()
{
- return new PGlobj(this);
+ for(int i=0;i<defaultObjectTypes.length;i++)
+ objectTypes.put(defaultObjectTypes[i][0],defaultObjectTypes[i][1]);
}
}
diff --git a/src/interfaces/jdbc/postgresql/DatabaseMetaData.java b/src/interfaces/jdbc/postgresql/DatabaseMetaData.java
index b5e8a985fb2..4e3894f66b6 100644
--- a/src/interfaces/jdbc/postgresql/DatabaseMetaData.java
+++ b/src/interfaces/jdbc/postgresql/DatabaseMetaData.java
@@ -4,17 +4,14 @@ import java.sql.*;
import java.util.*;
/**
- * @version 1.0 15-APR-1997
- * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
- *
* This class provides information about the database as a whole.
*
- * Many of the methods here return lists of information in ResultSets. You
+ * <p>Many of the methods here return lists of information in ResultSets. You
* can use the normal ResultSet methods such as getString and getInt to
* retrieve the data from these ResultSets. If a given form of metadata is
* not available, these methods should throw a SQLException.
*
- * Some of these methods take arguments that are String patterns. These
+ * <p>Some of these methods take arguments that are String patterns. These
* arguments all have names such as fooPattern. Within a pattern String,
* "%" means match any substring of 0 or more characters, and "_" means
* match any one character. Only metadata entries matching the search
@@ -22,7 +19,7 @@ import java.util.*;
* ref, it means that argument's criteria should be dropped from the
* search.
*
- * A SQLException will be throws if a driver does not support a meta
+ * <p>A SQLException will be throws if a driver does not support a meta
* data method. In the case of methods that return a ResultSet, either
* a ResultSet (which may be empty) is returned or a SQLException is
* thrown.
@@ -33,6 +30,12 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
Connection connection; // The connection association
+ // These define various OID's. Hopefully they will stay constant.
+ static final int iVarcharOid = 1043; // OID for varchar
+ static final int iBoolOid = 16; // OID for bool
+ static final int iInt2Oid = 21; // OID for int2
+ static final int iInt4Oid = 23; // OID for int4
+
public DatabaseMetaData(Connection conn)
{
this.connection = conn;
@@ -152,19 +155,21 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
}
/**
- * What is the version of this database product. Note that
- * PostgreSQL 6.1 has a system catalog called pg_version -
+ * What is the version of this database product.
+ *
+ * <p>Note that PostgreSQL 6.3 has a system catalog called pg_version -
* however, select * from pg_version on any database retrieves
- * no rows. For now, we will return the version 6.1 (in the
- * hopes that we change this driver as often as we change the
- * database)
+ * no rows.
+ *
+ * <p>For now, we will return the version 6.3 (in the hope that we change
+ * this driver as often as we change the database)
*
* @return the database version
* @exception SQLException if a database access error occurs
*/
public String getDatabaseProductVersion() throws SQLException
{
- return ("6.2");
+ return ("6.3");
}
/**
@@ -240,7 +245,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* as case sensitive and as a result store them in mixed case?
* A JDBC-Compliant driver will always return false.
*
- * Predicament - what do they mean by "SQL identifiers" - if it
+ * <p>Predicament - what do they mean by "SQL identifiers" - if it
* means the names of the tables and columns, then the answers
* given below are correct - otherwise I don't know.
*
@@ -290,7 +295,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* case sensitive and as a result store them in mixed case? A
* JDBC compliant driver will always return true.
*
- * Predicament - what do they mean by "SQL identifiers" - if it
+ * <p>Predicament - what do they mean by "SQL identifiers" - if it
* means the names of the tables and columns, then the answers
* given below are correct - otherwise I don't know.
*
@@ -340,7 +345,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* a space if identifier quoting isn't supported. A JDBC Compliant
* driver will always use a double quote character.
*
- * If an SQL identifier is a table name, column name, etc. then
+ * <p>If an SQL identifier is a table name, column name, etc. then
* we do not support it.
*
* @return the quoting string
@@ -355,10 +360,12 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* Get a comma separated list of all a database's SQL keywords that
* are NOT also SQL92 keywords.
*
- * Within PostgreSQL, the keywords are found in
+ * <p>Within PostgreSQL, the keywords are found in
* src/backend/parser/keywords.c
- * For SQL Keywords, I took the list provided at
- * http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt
+ *
+ * <p>For SQL Keywords, I took the list provided at
+ * <a href="http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt">
+ * http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt</a>
* which is for SQL3, not SQL-92, but it is close enough for
* this purpose.
*
@@ -410,7 +417,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* Get all the "extra" characters that can bew used in unquoted
* identifier names (those beyond a-zA-Z0-9 and _)
*
- * From the file src/backend/parser/scan.l, an identifier is
+ * <p>From the file src/backend/parser/scan.l, an identifier is
* {letter}{letter_or_digit} which makes it just those listed
* above.
*
@@ -449,14 +456,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
/**
* Is column aliasing supported?
*
- * If so, the SQL AS clause can be used to provide names for
+ * <p>If so, the SQL AS clause can be used to provide names for
* computed columns or to provide alias names for columns as
* required. A JDBC Compliant driver always returns true.
*
- * e.g.
+ * <p>e.g.
*
+ * <br><pre>
* select count(C) as C_COUNT from T group by C;
*
+ * </pre><br>
* should return a column named as C_COUNT instead of count(C)
*
* @return true if so
@@ -506,7 +515,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
/**
* Are expressions in "ORCER BY" lists supported?
*
- * e.g. select * from t order by a + b;
+ * <br>e.g. select * from t order by a + b;
*
* @return true if so
* @exception SQLException if a database access error occurs
@@ -607,7 +616,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* Can columns be defined as non-nullable. A JDBC Compliant driver
* always returns true.
*
- * This changed from false to true in v6.2 of the driver, as this
+ * <p>This changed from false to true in v6.2 of the driver, as this
* support was added to the backend.
*
* @return true if so
@@ -622,9 +631,9 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* Does this driver support the minimum ODBC SQL grammar. This
* grammar is defined at:
*
- * http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm
+ * <p><a href="http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm">http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm</a>
*
- * In Appendix C. From this description, we seem to support the
+ * <p>In Appendix C. From this description, we seem to support the
* ODBC minimal (Level 0) grammar.
*
* @return true if so
@@ -1142,7 +1151,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* What is the maximum number of columns in a table? From the
* create_table(l) manual page...
*
- * "The new class is created as a heap with no initial data. A
+ * <p>"The new class is created as a heap with no initial data. A
* class can have no more than 1600 attributes (realistically,
* this is limited by the fact that tuple sizes must be less than
* 8192 bytes)..."
@@ -1393,6 +1402,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* Does a data definition statement within a transaction force
* the transaction to commit? I think this means something like:
*
+ * <p><pre>
* CREATE TABLE T (A INT);
* INSERT INTO T (A) VALUES (2);
* BEGIN;
@@ -1400,6 +1410,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* CREATE TABLE X (A INT);
* SELECT A FROM T INTO X;
* COMMIT;
+ * </pre><p>
*
* does the CREATE TABLE call cause a commit? The answer is no.
*
@@ -1412,7 +1423,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
}
/**
- * Is a data definition statement within a transaction ignored?
+ * Is a data definition statement within a transaction ignored?
* It seems to be (from experiment in previous method)
*
* @return true if so
@@ -1426,22 +1437,26 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
/**
* Get a description of stored procedures available in a catalog
*
- * Only procedure descriptions matching the schema and procedure
+ * <p>Only procedure descriptions matching the schema and procedure
* name criteria are returned. They are ordered by PROCEDURE_SCHEM
* and PROCEDURE_NAME
*
- * Each procedure description has the following columns:
- * PROCEDURE_CAT String => procedure catalog (may be null)
- * PROCEDURE_SCHEM String => procedure schema (may be null)
- * PROCEDURE_NAME String => procedure name
- * Field 4 reserved (make it null)
- * Field 5 reserved (make it null)
- * Field 6 reserved (make it null)
- * REMARKS String => explanatory comment on the procedure
- * PROCEDURE_TYPE short => kind of procedure
- * * procedureResultUnknown - May return a result
- * * procedureNoResult - Does not return a result
- * * procedureReturnsResult - Returns a result
+ * <p>Each procedure description has the following columns:
+ * <ol>
+ * <li><b>PROCEDURE_CAT</b> String => procedure catalog (may be null)
+ * <li><b>PROCEDURE_SCHEM</b> String => procedure schema (may be null)
+ * <li><b>PROCEDURE_NAME</b> String => procedure name
+ * <li><b>Field 4</b> reserved (make it null)
+ * <li><b>Field 5</b> reserved (make it null)
+ * <li><b>Field 6</b> reserved (make it null)
+ * <li><b>REMARKS</b> String => explanatory comment on the procedure
+ * <li><b>PROCEDURE_TYPE</b> short => kind of procedure
+ * <ul>
+ * <li> procedureResultUnknown - May return a result
+ * <li> procedureNoResult - Does not return a result
+ * <li> procedureReturnsResult - Returns a result
+ * </ul>
+ * </ol>
*
* @param catalog - a catalog name; "" retrieves those without a
* catalog; null means drop catalog name from criteria
@@ -1451,8 +1466,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* @return ResultSet - each row is a procedure description
* @exception SQLException if a database access error occurs
*/
- static final int iVarcharOid = 1043; // This is the OID for a varchar()
- static final int iInt2Oid = 21; // This is the OID for an int2
public java.sql.ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException
{
// the field descriptors for the new ResultSet
@@ -1497,17 +1510,183 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
return new ResultSet(connection, f, v, "OK", 1);
}
+ /**
+ * Get a description of a catalog's stored procedure parameters
+ * and result columns.
+ *
+ * <p>Only descriptions matching the schema, procedure and parameter
+ * name criteria are returned. They are ordered by PROCEDURE_SCHEM
+ * and PROCEDURE_NAME. Within this, the return value, if any, is
+ * first. Next are the parameter descriptions in call order. The
+ * column descriptions follow in column number order.
+ *
+ * <p>Each row in the ResultSet is a parameter description or column
+ * description with the following fields:
+ * <ol>
+ * <li><b>PROCEDURE_CAT</b> String => procedure catalog (may be null)
+ * <li><b>PROCEDURE_SCHE</b>M String => procedure schema (may be null)
+ * <li><b>PROCEDURE_NAME</b> String => procedure name
+ * <li><b>COLUMN_NAME</b> String => column/parameter name
+ * <li><b>COLUMN_TYPE</b> Short => kind of column/parameter:
+ * <ul><li>procedureColumnUnknown - nobody knows
+ * <li>procedureColumnIn - IN parameter
+ * <li>procedureColumnInOut - INOUT parameter
+ * <li>procedureColumnOut - OUT parameter
+ * <li>procedureColumnReturn - procedure return value
+ * <li>procedureColumnResult - result column in ResultSet
+ * </ul>
+ * <li><b>DATA_TYPE</b> short => SQL type from java.sql.Types
+ * <li><b>TYPE_NAME</b> String => SQL type name
+ * <li><b>PRECISION</b> int => precision
+ * <li><b>LENGTH</b> int => length in bytes of data
+ * <li><b>SCALE</b> short => scale
+ * <li><b>RADIX</b> short => radix
+ * <li><b>NULLABLE</b> short => can it contain NULL?
+ * <ul><li>procedureNoNulls - does not allow NULL values
+ * <li>procedureNullable - allows NULL values
+ * <li>procedureNullableUnknown - nullability unknown
+ * <li><b>REMARKS</b> String => comment describing parameter/column
+ * </ol>
+ * @param catalog This is ignored in postgresql, advise this is set to null
+ * @param schemaPattern This is ignored in postgresql, advise this is set to null
+ * @param procedureNamePattern a procedure name pattern
+ * @param columnNamePattern a column name pattern
+ * @return each row is a stored procedure parameter or column description
+ * @exception SQLException if a database-access error occurs
+ * @see #getSearchStringEscape
+ */
+ // Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException
{
- // XXX-Not Implemented
- return null;
+ // for now, this returns an empty result set.
+ Field f[] = new Field[13];
+ ResultSet r; // ResultSet for the SQL query that we need to do
+ Vector v = new Vector(); // The new ResultSet tuple stuff
+
+ f[0] = new Field(connection, new String("PROCEDURE_CAT"), iVarcharOid, 32);
+ f[1] = new Field(connection, new String("PROCEDURE_SCHEM"), iVarcharOid, 32);
+ f[2] = new Field(connection, new String("PROCEDURE_NAME"), iVarcharOid, 32);
+ f[3] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32);
+ f[4] = new Field(connection, new String("COLUMN_TYPE"), iInt2Oid, 2);
+ f[5] = new Field(connection, new String("DATA_TYPE"), iInt2Oid, 2);
+ f[6] = new Field(connection, new String("TYPE_NAME"), iVarcharOid, 32);
+ f[7] = new Field(connection, new String("PRECISION"), iInt4Oid, 4);
+ f[8] = new Field(connection, new String("LENGTH"), iInt4Oid, 4);
+ f[9] = new Field(connection, new String("SCALE"), iInt2Oid, 2);
+ f[10] = new Field(connection, new String("RADIX"), iInt2Oid, 2);
+ f[11] = new Field(connection, new String("NULLABLE"), iInt2Oid, 2);
+ f[12] = new Field(connection, new String("REMARKS"), iVarcharOid, 32);
+
+ return new ResultSet(connection, f, v, "OK", 1);
}
+ /**
+ * Get a description of tables available in a catalog.
+ *
+ * <p>Only table descriptions matching the catalog, schema, table
+ * name and type criteria are returned. They are ordered by
+ * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
+ *
+ * <p>Each table description has the following columns:
+ *
+ * <ol>
+ * <li><b>TABLE_CAT</b> String => table catalog (may be null)
+ * <li><b>TABLE_SCHEM</b> String => table schema (may be null)
+ * <li><b>TABLE_NAME</b> String => table name
+ * <li><b>TABLE_TYPE</b> String => table type. Typical types are "TABLE",
+ * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL
+ * TEMPORARY", "ALIAS", "SYNONYM".
+ * <li><b>REMARKS</b> String => explanatory comment on the table
+ * </ol>
+ *
+ * <p>The valid values for the types parameter are:
+ * "TABLE", "INDEX", "LARGE OBJECT", "SEQUENCE", "SYSTEM TABLE" and
+ * "SYSTEM INDEX"
+ *
+ * @param catalog a catalog name; For postgresql, this is ignored, and
+ * should be set to null
+ * @param schemaPattern a schema name pattern; For postgresql, this is ignored, and
+ * should be set to null
+ * @param tableNamePattern a table name pattern. For all tables this should be "%"
+ * @param types a list of table types to include; null returns
+ * all types
+ * @return each row is a table description
+ * @exception SQLException if a database-access error occurs.
+ */
public java.sql.ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String types[]) throws SQLException
{
- return connection.createStatement().executeQuery("SELECT '' as TABLE_CAT,'' AS TABLE_SCHEM,relname AS TABLE_NAME,'TABLE' AS TABLE_TYPE,'' AS REMARKS FROM pg_class WHERE relkind = 'r' and relname !~ '^pg_' and relname !~ '^Inv' and relname ~ '"+tableNamePattern+"' ORDER BY TABLE_NAME");
+ // the field descriptors for the new ResultSet
+ Field f[] = new Field[5];
+ ResultSet r; // ResultSet for the SQL query that we need to do
+ Vector v = new Vector(); // The new ResultSet tuple stuff
+
+ f[0] = new Field(connection, new String("TABLE_CAT"), iVarcharOid, 32);
+ f[1] = new Field(connection, new String("TABLE_SCHEM"), iVarcharOid, 32);
+ f[2] = new Field(connection, new String("TABLE_NAME"), iVarcharOid, 32);
+ f[3] = new Field(connection, new String("TABLE_TYPE"), iVarcharOid, 32);
+ f[4] = new Field(connection, new String("REMARKS"), iVarcharOid, 32);
+
+ // Now form the query
+ StringBuffer sql = new StringBuffer("select relname,oid from pg_class where ");
+ boolean notFirst=false;
+ for(int i=0;i<types.length;i++) {
+ if(notFirst)
+ sql.append(" or ");
+ for(int j=0;j<getTableTypes.length;j++)
+ if(getTableTypes[j][0].equals(types[i])) {
+ sql.append(getTableTypes[j][1]);
+ notFirst=true;
+ }
+ }
+
+ // Now run the query
+ r = connection.ExecSQL(sql.toString());
+
+ if (r.getColumnCount() != 2)
+ throw new SQLException("Unexpected return from query for table list");
+
+ while (r.next())
+ {
+ byte[][] tuple = new byte[5][0];
+
+ String name = r.getString(1);
+ String remarks = new String("no remarks");
+
+ // Fetch the description for the table (if any)
+ ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(2));
+ if(dr.getTupleCount()==1) {
+ dr.next();
+ remarks=dr.getString(1);
+ }
+ dr.close();
+
+ tuple[0] = null; // Catalog name
+ tuple[1] = null; // Schema name
+ tuple[2] = name.getBytes(); // Table name
+ tuple[3] = null; // Table type
+ tuple[4] = remarks.getBytes(); // Remarks
+ v.addElement(tuple);
+ }
+ r.close();
+ return new ResultSet(connection, f, v, "OK", 1);
}
+ // This array contains the valid values for the types argument
+ // in getTables().
+ //
+ // Each supported type consists of it's name, and the sql where
+ // clause to retrieve that value.
+ //
+ // IMPORTANT: the query must be enclosed in ( )
+ private static final String getTableTypes[][] = {
+ {"TABLE", "(relkind='r' and relname !~ '^pg_' and relname !~ '^xinv')"},
+ {"INDEX", "(relkind='i' and relname !~ '^pg_' and relname !~ '^xinx')"},
+ {"LARGE OBJECT", "(relkind='r' and relname ~ '^xinv')"},
+ {"SEQUENCE", "(relkind='S' and relname !~ '^pg_')"},
+ {"SYSTEM TABLE", "(relkind='r' and relname ~ '^pg_')"},
+ {"SYSTEM INDEX", "(relkind='i' and relname ~ '^pg_')"}
+ };
+
/**
* Get the schema names available in this database. The results
* are ordered by schema name.
@@ -1522,8 +1701,15 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public java.sql.ResultSet getSchemas() throws SQLException
{
- // XXX-Not Implemented
- return null;
+ // We don't use schemas, so we simply return a single schema name "".
+ //
+ Field f[] = new Field[1];
+ Vector v = new Vector();
+ byte[][] tuple = new byte[1][0];
+ f[0] = new Field(connection,new String("TABLE_SCHEM"),iVarcharOid,32);
+ tuple[0] = "".getBytes();
+ v.addElement(tuple);
+ return new ResultSet(connection,f,v,"OK",1);
}
/**
@@ -1538,10 +1724,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* @return ResultSet each row has a single String column that is a
* catalog name
*/
- // We don't use catalog names, so this returns a single catalog
public java.sql.ResultSet getCatalogs() throws SQLException
{
- return connection.createStatement().executeQuery("SELECT '' as TABLE_CAT");
+ // We don't use catalogs, so we simply return a single catalog name "".
+ Field f[] = new Field[1];
+ Vector v = new Vector();
+ byte[][] tuple = new byte[1][0];
+ f[0] = new Field(connection,new String("TABLE_CAT"),iVarcharOid,32);
+ tuple[0] = "".getBytes();
+ v.addElement(tuple);
+ return new ResultSet(connection,f,v,"OK",1);
}
/**
@@ -1560,8 +1752,15 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public java.sql.ResultSet getTableTypes() throws SQLException
{
- // XXX-Not Implemented
- return null;
+ Field f[] = new Field[1];
+ Vector v = new Vector();
+ byte[][] tuple = new byte[1][0];
+ f[0] = new Field(connection,new String("TABLE_TYPE"),iVarcharOid,32);
+ for(int i=0;i<getTableTypes.length;i++) {
+ tuple[0] = getTableTypes[i][0].getBytes();
+ v.addElement(tuple);
+ }
+ return new ResultSet(connection,f,v,"OK",1);
}
/**
@@ -1614,10 +1813,87 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public java.sql.ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException
{
- // XXX-Not Implemented
- // PM: this will be implemented, as soon as I sort out how to convert the
- // code from the other driver (private note: look at getProcedures() )
- return null;
+ // the field descriptors for the new ResultSet
+ Field f[] = new Field[18];
+ ResultSet r; // ResultSet for the SQL query that we need to do
+ Vector v = new Vector(); // The new ResultSet tuple stuff
+
+ f[0] = new Field(connection, new String("TABLE_CAT"), iVarcharOid, 32);
+ f[1] = new Field(connection, new String("TABLE_SCHEM"), iVarcharOid, 32);
+ f[2] = new Field(connection, new String("TABLE_NAME"), iVarcharOid, 32);
+ f[3] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32);
+ f[4] = new Field(connection, new String("DATA_TYPE"), iInt2Oid, 2);
+ f[5] = new Field(connection, new String("TYPE_NAME"), iVarcharOid, 32);
+ f[6] = new Field(connection, new String("COLUMN_SIZE"), iInt4Oid, 4);
+ f[7] = new Field(connection, new String("BUFFER_LENGTH"), iVarcharOid, 32);
+ f[8] = new Field(connection, new String("DECIMAL_DIGITS"), iInt4Oid, 4);
+ f[9] = new Field(connection, new String("NUM_PREC_RADIX"), iInt4Oid, 4);
+ f[10] = new Field(connection, new String("NULLABLE"), iInt4Oid, 4);
+ f[11] = new Field(connection, new String("REMARKS"), iVarcharOid, 32);
+ f[12] = new Field(connection, new String("COLUMN_DEF"), iVarcharOid, 32);
+ f[13] = new Field(connection, new String("SQL_DATA_TYPE"), iInt4Oid, 4);
+ f[14] = new Field(connection, new String("SQL_DATETIME_SUB"), iInt4Oid, 4);
+ f[15] = new Field(connection, new String("CHAR_OCTET_LENGTH"), iVarcharOid, 32);
+ f[16] = new Field(connection, new String("ORDINAL_POSITION"), iInt4Oid,4);
+ f[17] = new Field(connection, new String("IS_NULLABLE"), iVarcharOid, 32);
+
+ // Now form the query
+ r = connection.ExecSQL("select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen from pg_class c, pg_attribute a where a.attrelid=c.oid and c.relname like '"+tableNamePattern+"' and a.attname like '"+columnNamePattern+"' and a.attnum>0 order by c.relname,a.attnum");
+
+ while(r.next()) {
+ byte[][] tuple = new byte[18][0];
+
+ String name = r.getString(1);
+ String remarks = new String("no remarks");
+
+ // Fetch the description for the table (if any)
+ ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(1));
+ if(dr.getTupleCount()==1) {
+ dr.next();
+ remarks=dr.getString(1);
+ }
+ dr.close();
+
+ tuple[0] = "".getBytes(); // Catalog name
+ tuple[1] = "".getBytes(); // Schema name
+ tuple[2] = r.getString(2).getBytes(); // Table name
+ tuple[3] = r.getString(3).getBytes(); // Column name
+
+ dr = connection.ExecSQL("select typname from pg_type where oid = "+r.getString(4));
+ dr.next();
+ String typname=dr.getString(1);
+ dr.close();
+ tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes(); // Data type
+ tuple[5] = typname.getBytes(); // Type name
+
+ tuple[6] = r.getString(7).getBytes(); // Column size
+
+ tuple[7] = null; // Buffer length
+
+ tuple[8] = "0".getBytes(); // Decimal Digits - how to get this?
+ tuple[9] = "10".getBytes(); // Num Prec Radix - assume decimal
+
+ // tuple[10] is below
+
+ tuple[11] = remarks.getBytes(); // Remarks
+
+ tuple[12] = null; // column default
+
+ tuple[13] = null; // sql data type (unused)
+ tuple[14] = null; // sql datetime sub (unused)
+
+ tuple[15] = tuple[6]; // char octet length
+
+ tuple[16] = r.getString(5).getBytes(); // ordinal position
+
+ String nullFlag = r.getString(6);
+ tuple[10] = Integer.toString(nullFlag.equals("f")?java.sql.DatabaseMetaData.columnNullable:java.sql.DatabaseMetaData.columnNoNulls).getBytes(); // Nullable
+ tuple[17] = (nullFlag.equals("f")?"YES":"NO").getBytes(); // is nullable
+
+ v.addElement(tuple);
+ }
+ r.close();
+ return new ResultSet(connection, f, v, "OK", 1);
}
/**
@@ -1649,8 +1925,30 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public java.sql.ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException
{
- // XXX-Not Implemented
+ // XXX-Not Implemented as grant is broken
return null;
+ //Field f[] = new Field[8];
+ //Vector v = new Vector();
+ //
+ //f[0] = new Field(connection,new String("TABLE_CAT"),iVarcharOid,32);
+ //f[1] = new Field(connection,new String("TABLE_SCHEM"),iVarcharOid,32);
+ //f[2] = new Field(connection,new String("TABLE_NAME"),iVarcharOid,32);
+ //f[3] = new Field(connection,new String("COLUMN_NAME"),iVarcharOid,32);
+ //f[4] = new Field(connection,new String("GRANTOR"),iVarcharOid,32);
+ //f[5] = new Field(connection,new String("GRANTEE"),iVarcharOid,32);
+ //f[6] = new Field(connection,new String("PRIVILEGE"),iVarcharOid,32);
+ //f[7] = new Field(connection,new String("IS_GRANTABLE"),iVarcharOid,32);
+ //
+ //// This is taken direct from the psql source
+ //ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner ORDER BY relname");
+ //while(r.next()) {
+ //byte[][] tuple = new byte[8][0];
+ //tuple[0] = tuple[1]= "default".getBytes();
+ //
+ //v.addElement(tuple);
+ //}
+ //
+ //return new ResultSet(connection,f,v,"OK",1);
}
/**
@@ -1722,10 +2020,24 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* @param nullable include columns that are nullable?
* @return ResultSet each row is a column description
*/
+ // Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException
{
- // XXX-Not Implemented
- return null;
+ // for now, this returns an empty result set.
+ Field f[] = new Field[8];
+ ResultSet r; // ResultSet for the SQL query that we need to do
+ Vector v = new Vector(); // The new ResultSet tuple stuff
+
+ f[0] = new Field(connection, new String("SCOPE"), iInt2Oid, 2);
+ f[1] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32);
+ f[2] = new Field(connection, new String("DATA_TYPE"), iInt2Oid, 2);
+ f[3] = new Field(connection, new String("TYPE_NAME"), iVarcharOid, 32);
+ f[4] = new Field(connection, new String("COLUMN_SIZE"), iInt4Oid, 4);
+ f[5] = new Field(connection, new String("BUFFER_LENGTH"), iInt4Oid, 4);
+ f[6] = new Field(connection, new String("DECIMAL_DIGITS"), iInt2Oid, 2);
+ f[7] = new Field(connection, new String("PSEUDO_COLUMN"), iInt2Oid, 2);
+
+ return new ResultSet(connection, f, v, "OK", 1);
}
/**
@@ -2078,9 +2390,29 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* accurate
* @return ResultSet each row is an index column description
*/
+ // Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException
{
- // XXX-Not Implemented
- return null;
+ // for now, this returns an empty result set.
+ Field f[] = new Field[13];
+ ResultSet r; // ResultSet for the SQL query that we need to do
+ Vector v = new Vector(); // The new ResultSet tuple stuff
+
+ f[0] = new Field(connection, new String("TABLE_CAT"), iVarcharOid, 32);
+ f[1] = new Field(connection, new String("TABLE_SCHEM"), iVarcharOid, 32);
+ f[2] = new Field(connection, new String("TABLE_NAME"), iVarcharOid, 32);
+ f[3] = new Field(connection, new String("NON_UNIQUE"), iBoolOid, 1);
+ f[4] = new Field(connection, new String("INDEX_QUALIFIER"), iVarcharOid, 32);
+ f[5] = new Field(connection, new String("INDEX_NAME"), iVarcharOid, 32);
+ f[6] = new Field(connection, new String("TYPE"), iInt2Oid, 2);
+ f[7] = new Field(connection, new String("ORDINAL_POSITION"), iInt2Oid, 2);
+ f[8] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32);
+ f[9] = new Field(connection, new String("ASC_OR_DESC"), iVarcharOid, 32);
+ f[10] = new Field(connection, new String("CARDINALITY"), iInt4Oid, 4);
+ f[11] = new Field(connection, new String("PAGES"), iInt4Oid, 4);
+ f[12] = new Field(connection, new String("FILTER_CONDITION"), iVarcharOid, 32);
+
+ return new ResultSet(connection, f, v, "OK", 1);
}
}
+
diff --git a/src/interfaces/jdbc/postgresql/Driver.java b/src/interfaces/jdbc/postgresql/Driver.java
index 7b711455ad3..4b1772c88ef 100644
--- a/src/interfaces/jdbc/postgresql/Driver.java
+++ b/src/interfaces/jdbc/postgresql/Driver.java
@@ -7,17 +7,17 @@ import java.util.*;
* The Java SQL framework allows for multiple database drivers. Each
* driver should supply a class that implements the Driver interface
*
- * The DriverManager will try to load as many drivers as it can find and then
- * for any given connection request, it will ask each driver in turn to try
- * to connect to the target URL.
+ * <p>The DriverManager will try to load as many drivers as it can find and
+ * then for any given connection request, it will ask each driver in turn
+ * to try to connect to the target URL.
*
- * It is strongly recommended that each Driver class should be small and
+ * <p>It is strongly recommended that each Driver class should be small and
* standalone so that the Driver class can be loaded and queried without
* bringing in vast quantities of supporting code.
*
- * When a Driver class is loaded, it should create an instance of itself and
- * register it with the DriverManager. This means that a user can load and
- * register a driver by doing Class.forName("foo.bah.Driver")
+ * <p>When a Driver class is loaded, it should create an instance of itself
+ * and register it with the DriverManager. This means that a user can load
+ * and register a driver by doing Class.forName("foo.bah.Driver")
*
* @see postgresql.Connection
* @see java.sql.Driver
@@ -58,18 +58,18 @@ public class Driver implements java.sql.Driver
* when the JDBC driverManager is asked to connect to a given URL,
* it passes the URL to each loaded driver in turn.
*
- * The driver should raise an SQLException if it is the right driver
+ * <p>The driver should raise an SQLException if it is the right driver
* to connect to the given URL, but has trouble connecting to the
* database.
*
- * The java.util.Properties argument can be used to pass arbitrary
+ * <p>The java.util.Properties argument can be used to pass arbitrary
* string tag/value pairs as connection arguments. Normally, at least
* "user" and "password" properties should be included in the
* properties.
*
- * Our protocol takes the form:
+ * Our protocol takes the forms:
* <PRE>
- * jdbc:postgresql://host:port/database
+ * jdbc:postgresql://host:port/database?param1=val1&...
* </PRE>
*
* @param url the URL of the database to connect to
@@ -110,7 +110,8 @@ public class Driver implements java.sql.Driver
* The getPropertyInfo method is intended to allow a generic GUI
* tool to discover what properties it should prompt a human for
* in order to get enough information to connect to a database.
- * Note that depending on the values the human has supplied so
+ *
+ * <p>Note that depending on the values the human has supplied so
* far, additional values may become necessary, so it may be necessary
* to iterate through several calls to getPropertyInfo
*
@@ -169,6 +170,9 @@ public class Driver implements java.sql.Driver
* tests, otherwise it is required to return false. JDBC compliance
* requires full support for the JDBC API and full support for SQL 92
* Entry Level.
+ *
+ * <p>For PostgreSQL, this is not yet possible, as we are not SQL92
+ * compliant (yet).
*/
public boolean jdbcCompliant()
{
@@ -185,7 +189,7 @@ public class Driver implements java.sql.Driver
* @param url JDBC URL to parse
* @param defaults Default properties
* @return Properties with elements added from the url
- * @throws SQLException
+ * @exception SQLException
*/
Properties parseURL(String url,Properties defaults) throws SQLException
{
@@ -280,7 +284,7 @@ public class Driver implements java.sql.Driver
}
/**
- * Returns the hostname portion of the URL
+ * @return the hostname portion of the URL
*/
public String host()
{
@@ -288,8 +292,7 @@ public class Driver implements java.sql.Driver
}
/**
- * Returns the port number portion of the URL
- * or -1 if no port was specified
+ * @return the port number portion of the URL or -1 if no port was specified
*/
public int port()
{
@@ -297,7 +300,7 @@ public class Driver implements java.sql.Driver
}
/**
- * Returns the database name of the URL
+ * @return the database name of the URL
*/
public String database()
{
@@ -305,7 +308,8 @@ public class Driver implements java.sql.Driver
}
/**
- * Returns any property
+ * @return the value of any property specified in the URL or properties
+ * passed to connect(), or null if not found.
*/
public String property(String name)
{
diff --git a/src/interfaces/jdbc/postgresql/Field.java b/src/interfaces/jdbc/postgresql/Field.java
index a4cc3c76e76..78553dd32eb 100644
--- a/src/interfaces/jdbc/postgresql/Field.java
+++ b/src/interfaces/jdbc/postgresql/Field.java
@@ -6,10 +6,8 @@ import java.util.*;
import postgresql.*;
/**
- * postgresql.Field is a class used to describe fields in a PostgreSQL ResultSet
- *
- * @version 1.0 15-APR-1997
- * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
+ * postgresql.Field is a class used to describe fields in a PostgreSQL
+ * ResultSet
*/
public class Field
{
@@ -22,7 +20,7 @@ public class Field
String type_name = null;// The sql type name
/**
- * Construct a field based on the information fed to it.
+ * Construct a field based on the information fed to it.
*
* @param conn the connection this field came from
* @param name the name of the field
@@ -38,6 +36,14 @@ public class Field
}
/**
+ * @return the oid of this Field's data type
+ */
+ public int getOID()
+ {
+ return oid;
+ }
+
+ /**
* the ResultSet and ResultMetaData both need to handle the SQL
* type, which is gained from another query. Note that we cannot
* use getObject() in this, since getObject uses getSQLType().
@@ -47,48 +53,78 @@ public class Field
*/
public int getSQLType() throws SQLException
{
- if (sql_type == -1)
- {
- ResultSet result = (postgresql.ResultSet)conn.ExecSQL("select typname from pg_type where oid = " + oid);
- if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
- throw new SQLException("Unexpected return from query for type");
- result.next();
- type_name = result.getString(1);
- if (type_name.equals("int2"))
- sql_type = Types.SMALLINT;
- else if (type_name.equals("int4"))
- sql_type = Types.INTEGER;
- else if (type_name.equals("int8"))
- sql_type = Types.BIGINT;
- else if (type_name.equals("cash"))
- sql_type = Types.DECIMAL;
- else if (type_name.equals("money"))
- sql_type = Types.DECIMAL;
- else if (type_name.equals("float4"))
- sql_type = Types.REAL;
- else if (type_name.equals("float8"))
- sql_type = Types.DOUBLE;
- else if (type_name.equals("bpchar"))
- sql_type = Types.CHAR;
- else if (type_name.equals("varchar"))
- sql_type = Types.VARCHAR;
- else if (type_name.equals("bool"))
- sql_type = Types.BIT;
- else if (type_name.equals("date"))
- sql_type = Types.DATE;
- else if (type_name.equals("time"))
- sql_type = Types.TIME;
- else if (type_name.equals("abstime"))
- sql_type = Types.TIMESTAMP;
- else if (type_name.equals("timestamp"))
- sql_type = Types.TIMESTAMP;
- else
- sql_type = Types.OTHER;
- }
+ if(sql_type == -1) {
+ ResultSet result = (postgresql.ResultSet)conn.ExecSQL("select typname from pg_type where oid = " + oid);
+ if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+ throw new SQLException("Unexpected return from query for type");
+ result.next();
+ sql_type = getSQLType(result.getString(1));
+ result.close();
+ }
+ return sql_type;
+ }
+
+ /**
+ * This returns the SQL type. It is called by the Field and DatabaseMetaData classes
+ * @param type_name PostgreSQL type name
+ * @return java.sql.Types value for oid
+ */
+ public static int getSQLType(String type_name)
+ {
+ int sql_type = Types.OTHER; // default value
+ for(int i=0;i<types.length;i++)
+ if(type_name.equals(types[i]))
+ sql_type=typei[i];
return sql_type;
}
/**
+ * This table holds the postgresql names for the types supported.
+ * Any types that map to Types.OTHER (eg POINT) don't go into this table.
+ * They default automatically to Types.OTHER
+ *
+ * Note: This must be in the same order as below.
+ *
+ * Tip: keep these grouped together by the Types. value
+ */
+ private static final String types[] = {
+ "int2",
+ "int4","oid",
+ "int8",
+ "cash","money",
+ "float4",
+ "float8",
+ "bpchar","char","char2","char4","char8","char16",
+ "varchar","text","name","filename",
+ "bool",
+ "date",
+ "time",
+ "abstime","timestamp"
+ };
+
+ /**
+ * This table holds the JDBC type for each entry above.
+ *
+ * Note: This must be in the same order as above
+ *
+ * Tip: keep these grouped together by the Types. value
+ */
+ private static final int typei[] = {
+ Types.SMALLINT,
+ Types.INTEGER,Types.INTEGER,
+ Types.BIGINT,
+ Types.DECIMAL,Types.DECIMAL,
+ Types.REAL,
+ Types.DOUBLE,
+ Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
+ Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
+ Types.BIT,
+ Types.DATE,
+ Types.TIME,
+ Types.TIMESTAMP,Types.TIMESTAMP
+ };
+
+ /**
* We also need to get the type name as returned by the back end.
* This is held in type_name AFTER a call to getSQLType. Since
* we get this information within getSQLType (if it isn't already
diff --git a/src/interfaces/jdbc/postgresql/PG_Stream.java b/src/interfaces/jdbc/postgresql/PG_Stream.java
index 59804c6dc6b..8c5f5215614 100644
--- a/src/interfaces/jdbc/postgresql/PG_Stream.java
+++ b/src/interfaces/jdbc/postgresql/PG_Stream.java
@@ -71,6 +71,28 @@ public class PG_Stream
}
/**
+ * Sends an integer to the back end in reverse order.
+ *
+ * This is required when the backend uses the routines in the
+ * src/backend/libpq/pqcomprim.c module.
+ *
+ * @param val the integer to be sent
+ * @param siz the length of the integer in bytes (size of structure)
+ * @exception IOException if an I/O error occurs
+ */
+ public void SendIntegerReverse(int val, int siz) throws IOException
+ {
+ byte[] buf = new byte[siz];
+ int p=0;
+ while (siz-- > 0)
+ {
+ buf[p++] = (byte)(val & 0xff);
+ val >>= 8;
+ }
+ Send(buf);
+ }
+
+ /**
* Send an array of bytes to the backend
*
* @param buf The array of bytes to be sent
@@ -296,6 +318,20 @@ public class PG_Stream
}
/**
+ * This flushes any pending output to the backend. It is used primarily
+ * by the Fastpath code.
+ * @exception SQLException if an I/O error occurs
+ */
+ public void flush() throws SQLException
+ {
+ try {
+ pg_output.flush();
+ } catch (IOException e) {
+ throw new SQLException("Error flushing output: " + e.toString());
+ }
+ }
+
+ /**
* Closes the connection
*
* @exception IOException if a IO Error occurs
diff --git a/src/interfaces/jdbc/postgresql/PreparedStatement.java b/src/interfaces/jdbc/postgresql/PreparedStatement.java
index 479f86eee92..659375064d3 100644
--- a/src/interfaces/jdbc/postgresql/PreparedStatement.java
+++ b/src/interfaces/jdbc/postgresql/PreparedStatement.java
@@ -5,21 +5,20 @@ import java.math.*;
import java.sql.*;
import java.text.*;
import java.util.*;
+import postgresql.largeobject.*;
+import postgresql.util.*;
/**
- * @version 6.3 15-APR-1997
- * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A><A HREF="mailto:petermount@earthling.net">Peter Mount</A>
- *
* A SQL Statement is pre-compiled and stored in a PreparedStatement object.
* This object can then be used to efficiently execute this statement multiple
* times.
*
- * <B>Note:</B> The setXXX methods for setting IN parameter values must
+ * <p><B>Note:</B> The setXXX methods for setting IN parameter values must
* specify types that are compatible with the defined SQL type of the input
* parameter. For instance, if the IN parameter has SQL type Integer, then
* setInt should be used.
*
- * If arbitrary parameter type conversions are required, then the setObject
+ * <p>If arbitrary parameter type conversions are required, then the setObject
* method should be used with a target SQL type.
*
* @see ResultSet
@@ -33,10 +32,10 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
Connection connection;
/**
- * Constructor for the PreparedStatement class. Split the SQL statement
- * into segments - separated by the arguments. When we rebuild the
- * thing with the arguments, we can substitute the args and join the
- * whole thing together.
+ * Constructor for the PreparedStatement class.
+ * Split the SQL statement into segments - separated by the arguments.
+ * When we rebuild the thing with the arguments, we can substitute the
+ * args and join the whole thing together.
*
* @param conn the instanatiating connection
* @param sql the SQL statement with ? for IN markers
@@ -125,7 +124,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
/**
* Set a parameter to SQL NULL
*
- * <B>Note:</B> You must specify the parameters SQL type (although
+ * <p><B>Note:</B> You must specify the parameters SQL type (although
* PostgreSQL ignores it)
*
* @param parameterIndex the first parameter is 1, etc...
@@ -254,35 +253,49 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
*/
public void setString(int parameterIndex, String x) throws SQLException
{
- StringBuffer b = new StringBuffer();
- int i;
-
- b.append('\'');
- for (i = 0 ; i < x.length() ; ++i)
- {
- char c = x.charAt(i);
- if (c == '\\' || c == '\'')
- b.append((char)'\\');
- b.append(c);
- }
- b.append('\'');
- set(parameterIndex, b.toString());
+ // if the passed string is null, then set this column to null
+ if(x==null)
+ set(parameterIndex,"null");
+ else {
+ StringBuffer b = new StringBuffer();
+ int i;
+
+ b.append('\'');
+ for (i = 0 ; i < x.length() ; ++i)
+ {
+ char c = x.charAt(i);
+ if (c == '\\' || c == '\'')
+ b.append((char)'\\');
+ b.append(c);
+ }
+ b.append('\'');
+ set(parameterIndex, b.toString());
+ }
}
- /**
- * Set a parameter to a Java array of bytes. The driver converts this
- * to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
- * size relative to the driver's limits on VARBINARYs) when it sends
- * it to the database.
- *
- * @param parameterIndex the first parameter is 1...
- * @param x the parameter value
- * @exception SQLException if a database access error occurs
- */
- public void setBytes(int parameterIndex, byte x[]) throws SQLException
- {
- throw new SQLException("Binary Data not supported");
- }
+ /**
+ * Set a parameter to a Java array of bytes. The driver converts this
+ * to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
+ * size relative to the driver's limits on VARBINARYs) when it sends
+ * it to the database.
+ *
+ * <p>Implementation note:
+ * <br>With postgresql, this creates a large object, and stores the
+ * objects oid in this column.
+ *
+ * @param parameterIndex the first parameter is 1...
+ * @param x the parameter value
+ * @exception SQLException if a database access error occurs
+ */
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException
+ {
+ LargeObjectManager lom = connection.getLargeObjectAPI();
+ int oid = lom.create();
+ LargeObject lob = lom.open(oid);
+ lob.write(x);
+ lob.close();
+ setInt(parameterIndex,oid);
+ }
/**
* Set a parameter to a java.sql.Date value. The driver converts this
@@ -294,16 +307,30 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
*/
public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
{
- SimpleDateFormat df = new SimpleDateFormat(connection.europeanDates?"''dd-MM-yyyy''":"''MM-dd-yyyy''");
-
- set(parameterIndex, df.format(x));
+ SimpleDateFormat df = new SimpleDateFormat("''"+connection.getDateStyle()+"''");
+
+ // Ideally the following should work:
+ //
+ // set(parameterIndex, df.format(x));
+ //
+ // however, SimpleDateFormat seems to format a date to the previous
+ // day. So a fix (for now) is to add a day before formatting.
+ // This needs more people to confirm this is really happening, or
+ // possibly for us to implement our own formatting code.
+ //
+ // I've tested this with the Linux jdk1.1.3 and the Win95 JRE1.1.5
+ //
+ set(parameterIndex, df.format(new java.util.Date(x.getTime()+DAY)));
}
+
+ // This equates to 1 day
+ private static final int DAY = 86400000;
/**
* Set a parameter to a java.sql.Time value. The driver converts
* this to a SQL TIME value when it sends it to the database.
*
- * @param parameterIndex the first parameter is 1...
+ * @param parameterIndex the first parameter is 1...));
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
@@ -332,7 +359,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
* end-of-file. The JDBC driver will do any necessary conversion from
* ASCII to the database char format.
*
- * <B>Note:</B> This stream object can either be a standard Java
+ * <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
@@ -353,7 +380,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
* end-of-file. The JDBC driver will do any necessary conversion from
* UNICODE to the database char format.
*
- * <B>Note:</B> This stream object can either be a standard Java
+ * <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
@@ -372,7 +399,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file.
*
- * <B>Note:</B> This stream object can either be a standard Java
+ * <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
@@ -406,10 +433,10 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
* Set the value of a parameter using an object; use the java.lang
* equivalent objects for integral values.
*
- * The given Java object will be converted to the targetSqlType before
+ * <P>The given Java object will be converted to the targetSqlType before
* being sent to the database.
*
- * note that this method may be used to pass database-specific
+ * <P>note that this method may be used to pass database-specific
* abstract data types. This is done by using a Driver-specific
* Java type and using a targetSqlType of java.sql.Types.OTHER
*
@@ -450,7 +477,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
case Types.TIMESTAMP:
setTimestamp(parameterIndex, (Timestamp)x);
case Types.OTHER:
- setString(parameterIndex, ((PG_Object)x).value);
+ setString(parameterIndex, ((PGobject)x).getValue());
default:
throw new SQLException("Unknown Types value");
}
@@ -485,8 +512,8 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
setTimestamp(parameterIndex, (Timestamp)x);
else if (x instanceof Boolean)
setBoolean(parameterIndex, ((Boolean)x).booleanValue());
- else if (x instanceof PG_Object)
- setString(parameterIndex, ((PG_Object)x).value);
+ else if (x instanceof PGobject)
+ setString(parameterIndex, ((PGobject)x).getValue());
else
throw new SQLException("Unknown object type");
}
diff --git a/src/interfaces/jdbc/postgresql/ResultSet.java b/src/interfaces/jdbc/postgresql/ResultSet.java
index 017b0ad2927..f8eea22595e 100644
--- a/src/interfaces/jdbc/postgresql/ResultSet.java
+++ b/src/interfaces/jdbc/postgresql/ResultSet.java
@@ -6,31 +6,32 @@ import java.math.*;
import java.text.*;
import java.util.*;
import java.sql.*;
-import postgresql.*;
+import postgresql.largeobject.*;
+import postgresql.util.*;
/**
* A ResultSet provides access to a table of data generated by executing a
* Statement. The table rows are retrieved in sequence. Within a row its
* column values can be accessed in any order.
*
- * A ResultSet maintains a cursor pointing to its current row of data.
+ * <P>A ResultSet maintains a cursor pointing to its current row of data.
* Initially the cursor is positioned before the first row. The 'next'
* method moves the cursor to the next row.
*
- * The getXXX methods retrieve column values for the current row. You can
+ * <P>The getXXX methods retrieve column values for the current row. You can
* retrieve values either using the index number of the column, or by using
* the name of the column. In general using the column index will be more
* efficient. Columns are numbered from 1.
*
- * For maximum portability, ResultSet columns within each row should be read
+ * <P>For maximum portability, ResultSet columns within each row should be read
* in left-to-right order and each column should be read only once.
*
- * For the getXXX methods, the JDBC driver attempts to convert the underlying
- * data to the specified Java type and returns a suitable Java value. See the
- * JDBC specification for allowable mappings from SQL types to Java types with
- * the ResultSet getXXX methods.
+ *<P> For the getXXX methods, the JDBC driver attempts to convert the
+ * underlying data to the specified Java type and returns a suitable Java
+ * value. See the JDBC specification for allowable mappings from SQL types
+ * to Java types with the ResultSet getXXX methods.
*
- * Column names used as input to getXXX methods are case insenstive. When
+ * <P>Column names used as input to getXXX methods are case insenstive. When
* performing a getXXX using a column name, if several columns have the same
* name, then the value of the first matching column will be returned. The
* column name option is designed to be used when column names are used in the
@@ -39,11 +40,11 @@ import postgresql.*;
* the programmer to guarentee that they actually refer to the intended
* columns.
*
- * A ResultSet is automatically closed by the Statement that generated it
+ * <P>A ResultSet is automatically closed by the Statement that generated it
* when that Statement is closed, re-executed, or is used to retrieve the
* next result from a sequence of multiple results.
*
- * The number, types and properties of a ResultSet's columns are provided by
+ * <P>The number, types and properties of a ResultSet's columns are provided by
* the ResultSetMetaData object returned by the getMetaData method.
*
* @see ResultSetMetaData
@@ -92,7 +93,7 @@ public class ResultSet implements java.sql.ResultSet
* the first call to next makes the first row the current row;
* the second call makes the second row the current row, etc.
*
- * If an input stream from the previous row is open, it is
+ * <p>If an input stream from the previous row is open, it is
* implicitly closed. The ResultSet's warning chain is cleared
* when a new row is read
*
@@ -114,7 +115,7 @@ public class ResultSet implements java.sql.ResultSet
* when it is automatically closed. The close method provides this
* immediate release.
*
- * <B>Note:</B> A ResultSet is automatically closed by the Statement
+ * <p><B>Note:</B> A ResultSet is automatically closed by the Statement
* the Statement that generated it when that Statement is closed,
* re-executed, or is used to retrieve the next result from a sequence
* of multiple results. A ResultSet is also automatically closed
@@ -150,11 +151,17 @@ public class ResultSet implements java.sql.ResultSet
*/
public String getString(int columnIndex) throws SQLException
{
- byte[] bytes = getBytes(columnIndex);
-
- if (bytes == null)
+ //byte[] bytes = getBytes(columnIndex);
+ //
+ //if (bytes == null)
+ //return null;
+ //return new String(bytes);
+ if (columnIndex < 1 || columnIndex > fields.length)
+ throw new SQLException("Column Index out of range");
+ wasNullFlag = (this_row[columnIndex - 1] == null);
+ if(wasNullFlag)
return null;
- return new String(bytes);
+ return new String(this_row[columnIndex - 1]);
}
/**
@@ -347,8 +354,14 @@ public class ResultSet implements java.sql.ResultSet
}
/**
- * Get the value of a column in the current row as a Java byte array
- * The bytes represent the raw values returned by the driver.
+ * Get the value of a column in the current row as a Java byte array.
+ *
+ * <p>In normal use, the bytes represent the raw values returned by the
+ * backend. However, if the column is an OID, then it is assumed to
+ * refer to a Large Object, and that object is returned as a byte array.
+ *
+ * <p><b>Be warned</b> If the large object is huge, then you may run out
+ * of memory.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return the column value; if the value is SQL NULL, the result
@@ -360,6 +373,17 @@ public class ResultSet implements java.sql.ResultSet
if (columnIndex < 1 || columnIndex > fields.length)
throw new SQLException("Column Index out of range");
wasNullFlag = (this_row[columnIndex - 1] == null);
+
+ // Handle OID's as BLOBS
+ if(!wasNullFlag)
+ if( fields[columnIndex - 1].getOID() == 26) {
+ LargeObjectManager lom = connection.getLargeObjectAPI();
+ LargeObject lob = lom.open(getInt(columnIndex));
+ byte buf[] = lob.read(lob.size());
+ lob.close();
+ return buf;
+ }
+
return this_row[columnIndex - 1];
}
@@ -374,7 +398,7 @@ public class ResultSet implements java.sql.ResultSet
public java.sql.Date getDate(int columnIndex) throws SQLException
{
String s = getString(columnIndex);
- SimpleDateFormat df = new SimpleDateFormat(connection.europeanDates?"dd-MM-yyyy":"MM-dd-yyyy");
+ SimpleDateFormat df = new SimpleDateFormat(connection.getDateStyle());
try {
return new java.sql.Date(df.parse(s).getTime());
} catch (ParseException e) {
@@ -449,13 +473,13 @@ public class ResultSet implements java.sql.ResultSet
* The JDBC driver will do any necessary conversion from the
* database format into ASCII.
*
- * <B>Note:</B> All the data in the returned stream must be read
+ * <p><B>Note:</B> All the data in the returned stream must be read
* prior to getting the value of any other column. The next call
* to a get method implicitly closes the stream. Also, a stream
* may return 0 for available() whether there is data available
* or not.
*
- * We implement an ASCII stream as a Binary stream - we should really
+ *<p> We implement an ASCII stream as a Binary stream - we should really
* do the data conversion, but I cannot be bothered to implement this
* right now.
*
@@ -494,8 +518,8 @@ public class ResultSet implements java.sql.ResultSet
*
* @param columnIndex the first column is 1, the second is 2...
* @return a Java InputStream that delivers the database column value
- * as a stream of two byte Unicode characters. If the value is
- * SQL NULL, then the result is null
+ * as a stream of bytes. If the value is SQL NULL, then the result
+ * is null
* @exception SQLException if a database access error occurs
* @see getAsciiStream
* @see getUnicodeStream
@@ -603,10 +627,10 @@ public class ResultSet implements java.sql.ResultSet
* returned. Subsequent ResultSet warnings will be chained
* to this SQLWarning.
*
- * The warning chain is automatically cleared each time a new
+ * <p>The warning chain is automatically cleared each time a new
* row is read.
*
- * <B>Note:</B> This warning chain only covers warnings caused by
+ * <p><B>Note:</B> This warning chain only covers warnings caused by
* ResultSet methods. Any warnings caused by statement methods
* (such as reading OUT parameters) will be chained on the
* Statement object.
@@ -633,16 +657,16 @@ public class ResultSet implements java.sql.ResultSet
/**
* Get the name of the SQL cursor used by this ResultSet
*
- * In SQL, a result table is retrieved though a cursor that is
+ * <p>In SQL, a result table is retrieved though a cursor that is
* named. The current row of a result can be updated or deleted
* using a positioned update/delete statement that references
* the cursor name.
*
- * JDBC supports this SQL feature by providing the name of the
+ * <p>JDBC supports this SQL feature by providing the name of the
* SQL cursor used by a ResultSet. The current row of a ResulSet
* is also the current row of this SQL cursor.
*
- * <B>Note:</B> If positioned update is not supported, a SQLException
+ * <p><B>Note:</B> If positioned update is not supported, a SQLException
* is thrown.
*
* @return the ResultSet's SQL cursor name.
@@ -668,12 +692,12 @@ public class ResultSet implements java.sql.ResultSet
/**
* Get the value of a column in the current row as a Java object
*
- * This method will return the value of the given column as a
+ * <p>This method will return the value of the given column as a
* Java object. The type of the Java object will be the default
* Java Object type corresponding to the column's SQL type, following
* the mapping specified in the JDBC specification.
*
- * This method may also be used to read database specific abstract
+ * <p>This method may also be used to read database specific abstract
* data types.
*
* @param columnIndex the first column is 1, the second is 2...
@@ -714,19 +738,19 @@ public class ResultSet implements java.sql.ResultSet
case Types.TIMESTAMP:
return getTimestamp(columnIndex);
default:
- return new PG_Object(field.getTypeName(), getString(columnIndex));
+ return connection.getObject(field.getTypeName(), getString(columnIndex));
}
}
/**
* Get the value of a column in the current row as a Java object
*
- * This method will return the value of the given column as a
+ *<p> This method will return the value of the given column as a
* Java object. The type of the Java object will be the default
* Java Object type corresponding to the column's SQL type, following
* the mapping specified in the JDBC specification.
*
- * This method may also be used to read database specific abstract
+ * <p>This method may also be used to read database specific abstract
* data types.
*
* @param columnName is the SQL name of the column
@@ -816,8 +840,6 @@ public class ResultSet implements java.sql.ResultSet
* particular, we need to know the number of rows and the
* number of columns. Rows are also known as Tuples
*
- * getTupleCount returns the number of rows
- *
* @return the number of rows
*/
public int getTupleCount()
diff --git a/src/interfaces/jdbc/postgresql/ResultSetMetaData.java b/src/interfaces/jdbc/postgresql/ResultSetMetaData.java
index 7d2c1ceaf33..c4e54dbefaa 100644
--- a/src/interfaces/jdbc/postgresql/ResultSetMetaData.java
+++ b/src/interfaces/jdbc/postgresql/ResultSetMetaData.java
@@ -6,9 +6,6 @@ import java.util.*;
import postgresql.*;
/**
- * @version 1.0 15-APR-1997
- * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
- *
* A ResultSetMetaData object can be used to find out about the types and
* properties of the columns in a ResultSet
*
diff --git a/src/interfaces/jdbc/postgresql/Statement.java b/src/interfaces/jdbc/postgresql/Statement.java
index 464a263621f..177b8189f6c 100644
--- a/src/interfaces/jdbc/postgresql/Statement.java
+++ b/src/interfaces/jdbc/postgresql/Statement.java
@@ -3,13 +3,10 @@ package postgresql;
import java.sql.*;
/**
- * @version 1.0 15-APR-1997
- * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
- *
* A Statement object is used for executing a static SQL statement and
* obtaining the results produced by it.
*
- * Only one ResultSet per Statement can be open at any point in time.
+ * <p>Only one ResultSet per Statement can be open at any point in time.
* Therefore, if the reading of one ResultSet is interleaved with the
* reading of another, each must have been generated by different
* Statements. All statement execute methods implicitly close a
@@ -23,7 +20,6 @@ public class Statement implements java.sql.Statement
Connection connection; // The connection who created us
ResultSet result = null; // The current results
SQLWarning warnings = null; // The warnings chain.
- int maxrows = 0; // maximum no. of rows; 0 = unlimited
int timeout = 0; // The timeout for a query (not used)
boolean escapeProcessing = true;// escape processing flag
@@ -78,7 +74,7 @@ public class Statement implements java.sql.Statement
* for this to happen when it is automatically closed. The
* close method provides this immediate release.
*
- * <B>Note:</B> A Statement is automatically closed when it is
+ * <p><B>Note:</B> A Statement is automatically closed when it is
* garbage collected. When a Statement is closed, its current
* ResultSet, if one exists, is also closed.
*
@@ -126,7 +122,7 @@ public class Statement implements java.sql.Statement
*/
public int getMaxRows() throws SQLException
{
- return maxrows;
+ return connection.maxrows;
}
/**
@@ -138,7 +134,7 @@ public class Statement implements java.sql.Statement
*/
public void setMaxRows(int max) throws SQLException
{
- maxrows = max;
+ connection.maxrows = max;
}
/**
@@ -197,10 +193,10 @@ public class Statement implements java.sql.Statement
* chain. Subsequent Statement warnings will be chained to this
* SQLWarning.
*
- * The Warning chain is automatically cleared each time a statement
+ * <p>The Warning chain is automatically cleared each time a statement
* is (re)executed.
*
- * <B>Note:</B> If you are processing a ResultSet then any warnings
+ * <p><B>Note:</B> If you are processing a ResultSet then any warnings
* associated with ResultSet reads will be chained on the ResultSet
* object.
*
@@ -231,12 +227,12 @@ public class Statement implements java.sql.Statement
* doesn't support positioned update/delete, this method is a
* no-op.
*
- * <B>Note:</B> By definition, positioned update/delete execution
+ * <p><B>Note:</B> By definition, positioned update/delete execution
* must be done by a different Statement than the one which
* generated the ResultSet being used for positioning. Also, cursor
* names must be unique within a Connection.
*
- * We throw an additional constriction. There can only be one
+ * <p>We throw an additional constriction. There can only be one
* cursor active at any one time.
*
* @param name the new cursor name