aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/jdbc/Makefile4
-rw-r--r--src/interfaces/jdbc/build.xml43
-rw-r--r--src/interfaces/jdbc/example/ImageViewer.java4
-rw-r--r--src/interfaces/jdbc/example/basic.java5
-rw-r--r--src/interfaces/jdbc/example/blobtest.java2
-rw-r--r--src/interfaces/jdbc/example/threadsafe.java2
-rw-r--r--src/interfaces/jdbc/org/postgresql/Driver.java.in2
-rw-r--r--src/interfaces/jdbc/org/postgresql/Field.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/PGConnection.java72
-rw-r--r--src/interfaces/jdbc/org/postgresql/PGStatement.java21
-rw-r--r--src/interfaces/jdbc/org/postgresql/ResultSet.java264
-rw-r--r--src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java10
-rw-r--r--src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java (renamed from src/interfaces/jdbc/org/postgresql/Connection.java)251
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java957
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java (renamed from src/interfaces/jdbc/org/postgresql/Statement.java)218
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java2
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java214
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java36
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java47
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java32
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java19
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java1026
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java144
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java203
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java752
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java142
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Array.java56
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java2
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java332
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java32
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java62
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java32
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java21
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java1802
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java381
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/UpdateableResultSet.java12
-rw-r--r--src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java32
-rw-r--r--src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java238
-rw-r--r--src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java3
-rw-r--r--src/interfaces/jdbc/org/postgresql/util/Serialize.java24
48 files changed, 3033 insertions, 4522 deletions
diff --git a/src/interfaces/jdbc/Makefile b/src/interfaces/jdbc/Makefile
index 3b88af4d3c7..fc881a34ba2 100644
--- a/src/interfaces/jdbc/Makefile
+++ b/src/interfaces/jdbc/Makefile
@@ -4,7 +4,7 @@
#
# Copyright (c) 2001, PostgreSQL Global Development Group
#
-# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.34 2002/03/05 17:55:23 momjian Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.35 2002/07/23 03:59:54 barry Exp $
#
#-------------------------------------------------------------------------
@@ -38,5 +38,5 @@ uninstall:
clean distclean maintainer-clean:
$(ANT) -buildfile $(srcdir)/build.xml clean
-check:
+check: all
$(ANT) -buildfile $(srcdir)/build.xml test
diff --git a/src/interfaces/jdbc/build.xml b/src/interfaces/jdbc/build.xml
index c8b541d6a66..278053eeace 100644
--- a/src/interfaces/jdbc/build.xml
+++ b/src/interfaces/jdbc/build.xml
@@ -6,7 +6,7 @@
This file now requires Ant 1.4.1. 2002-04-18
- $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.24 2002/06/27 04:38:01 barry Exp $
+ $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.25 2002/07/23 03:59:54 barry Exp $
-->
@@ -29,7 +29,7 @@
in the CLASSPATH (ie JDK1.2 or later), and then enterprise if the
javax.sql.DataSource class is present.
- Important: This must have the following order: jdbc1, jdbc2, enterprise
+ Important: This must have the following order: jdbc1, jdbc2, jdbc3
-->
<target name="check_versions">
<condition property="jdbc1">
@@ -39,22 +39,12 @@
<or>
<equals arg1="${ant.java.version}" arg2="1.2"/>
<equals arg1="${ant.java.version}" arg2="1.3"/>
- <equals arg1="${ant.java.version}" arg2="1.4"/>
</or>
</condition>
<condition property="jdbc3">
<equals arg1="${ant.java.version}" arg2="1.4"/>
</condition>
- <condition property="datasource">
- <and>
- <or>
- <equals arg1="${ant.java.version}" arg2="1.2"/>
- <equals arg1="${ant.java.version}" arg2="1.3"/>
- <equals arg1="${ant.java.version}" arg2="1.4"/>
- </or>
- <available classname="javax.sql.DataSource"/>
- </and>
- </condition>
+ <available property="datasource" classname="javax.sql.DataSource"/>
<available property="junit" classname="junit.framework.Test" />
</target>
@@ -97,16 +87,17 @@
<exclude name="${package}/jdbc1/**" unless="jdbc1"/>
<exclude name="${package}/jdbc2/**" unless="jdbc2"/>
+ <exclude name="${package}/jdbc3/**" unless="jdbc3"/>
- <exclude name="${package}/largeobject/PGblob.java" unless="jdbc2" />
- <exclude name="${package}/largeobject/PGclob.java" unless="jdbc2" />
+ <exclude name="${package}/largeobject/PGblob.java" if="jdbc1" />
+ <exclude name="${package}/largeobject/PGclob.java" if="jdbc1" />
<exclude name="${package}/PostgresqlDataSource.java" unless="datasource" />
<exclude name="${package}/xa/**" unless="datasource" />
<exclude name="${package}/test/**" unless="junit" />
- <exclude name="${package}/test/jdbc2/**" unless="jdbc2" />
- <exclude name="${package}/test/JDBC2Tests.java" unless="jdbc2" />
+ <exclude name="${package}/test/jdbc2/**" if="jdbc1" />
+ <exclude name="${package}/test/JDBC2Tests.java" if="jdbc1" />
</javac>
</target>
@@ -121,10 +112,10 @@
<equals arg1="${jdbc1}" arg2="true"/>
</condition>
<condition property="edition" value="JDBC2">
- <or>
<equals arg1="${jdbc2}" arg2="true"/>
- <equals arg1="${jdbc3}" arg2="true"/> <!-- fake it for now -->
- </or>
+ </condition>
+ <condition property="edition" value="JDBC3">
+ <equals arg1="${jdbc3}" arg2="true"/>
</condition>
<condition property="edition" value="JDBC2 Enterprise">
<and>
@@ -134,8 +125,8 @@
</condition>
<!-- determine the connection class -->
- <property name="connectclass" value="org.postgresql.jdbc1.Connection" />
- <available property="connectclass" value="org.postgresql.jdbc2.Connection" classname="java.lang.ThreadLocal" />
+ <property name="connectclass" value="org.postgresql.jdbc1.Jdbc1Connection" />
+ <available property="connectclass" value="org.postgresql.jdbc2.Jdbc2Connection" classname="java.lang.ThreadLocal" />
<!-- Some defaults -->
<filter token="MAJORVERSION" value="${major}" />
@@ -173,13 +164,13 @@
<javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}">
<include name="example/**" />
<exclude name="example/corba/**"/>
- <exclude name="example/blobtest.java" unless="jdk1.2+"/>
+ <exclude name="example/blobtest.java" if="jdbc1"/>
</javac>
</target>
<!-- Builds the corba example -->
- <target name="corba" if="jdk1.2+">
+ <target name="corba" if="jdbc2">
<exec dir="${srcdir}/example/corba" executable="idl2java">
<arg value="stock.idl" />
</exec>
@@ -230,8 +221,8 @@
<target name="test" depends="jar" if="junit">
<javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}">
- <include name="${package}/test/jdbc2/**" if="jdk1.2+" />
- <include name="${package}/test/java2ee/**" if="jdk1.2e+" />
+ <include name="${package}/test/jdbc2/**" if="jdbc2" />
+ <include name="${package}/test/jdbc2/**" if="jdbc3" />
</javac>
<java fork="yes" classname="junit.${junit.ui}.TestRunner" taskname="junit" failonerror="true">
diff --git a/src/interfaces/jdbc/example/ImageViewer.java b/src/interfaces/jdbc/example/ImageViewer.java
index f61a8870e7b..0401780b5ca 100644
--- a/src/interfaces/jdbc/example/ImageViewer.java
+++ b/src/interfaces/jdbc/example/ImageViewer.java
@@ -205,7 +205,7 @@ public class ImageViewer implements ItemListener
stat = db.createStatement();
// Also, get the LargeObjectManager for this connection
- lom = ((org.postgresql.Connection)db).getLargeObjectAPI();
+ lom = ((org.postgresql.PGConnection)db).getLargeObjectAPI();
// Now refresh the image selection list
refreshList();
@@ -299,7 +299,7 @@ public class ImageViewer implements ItemListener
try
{
// fetch the large object manager
- LargeObjectManager lom = ((org.postgresql.Connection)db).getLargeObjectAPI();
+ LargeObjectManager lom = ((org.postgresql.PGConnection)db).getLargeObjectAPI();
db.setAutoCommit(false);
diff --git a/src/interfaces/jdbc/example/basic.java b/src/interfaces/jdbc/example/basic.java
index 9a4469d83a0..5f07a56c3f5 100644
--- a/src/interfaces/jdbc/example/basic.java
+++ b/src/interfaces/jdbc/example/basic.java
@@ -6,7 +6,7 @@ import java.text.*;
/*
*
- * $Id: basic.java,v 1.11 2001/11/25 23:26:56 barry Exp $
+ * $Id: basic.java,v 1.12 2002/07/23 03:59:54 barry Exp $
*
* This example tests the basic components of the JDBC driver, and shows
* how even the simplest of queries can be implemented.
@@ -87,9 +87,8 @@ public class basic
st.executeUpdate("insert into basic values (3,1)");
// This shows how to get the oid of a just inserted row
- // updated for 7.1
st.executeUpdate("insert into basic values (4,1)");
- long insertedOID = ((org.postgresql.Statement)st).getLastOID();
+ long insertedOID = ((org.postgresql.PGStatement)st).getLastOID();
System.out.println("Inserted row with oid " + insertedOID);
// Now change the value of b from 1 to 8
diff --git a/src/interfaces/jdbc/example/blobtest.java b/src/interfaces/jdbc/example/blobtest.java
index 271026250dd..d517d267b75 100644
--- a/src/interfaces/jdbc/example/blobtest.java
+++ b/src/interfaces/jdbc/example/blobtest.java
@@ -76,7 +76,7 @@ public class blobtest
// objects, however the unique methods available to postgresql makes
// things a little easier.
System.out.println("Gaining access to large object api");
- lobj = ((org.postgresql.Connection)db).getLargeObjectAPI();
+ lobj = ((org.postgresql.PGConnection)db).getLargeObjectAPI();
int oid = ownapi_test1();
ownapi_test2(oid);
diff --git a/src/interfaces/jdbc/example/threadsafe.java b/src/interfaces/jdbc/example/threadsafe.java
index cca7be75bee..c35570a4c2a 100644
--- a/src/interfaces/jdbc/example/threadsafe.java
+++ b/src/interfaces/jdbc/example/threadsafe.java
@@ -301,7 +301,7 @@ public class threadsafe
//st = c.createStatement();
// create a blob
- lom = ((org.postgresql.Connection)c).getLargeObjectAPI();
+ lom = ((org.postgresql.PGConnection)c).getLargeObjectAPI();
oid = lom.create();
System.out.println("Thread 3 has created a blob of oid " + oid);
}
diff --git a/src/interfaces/jdbc/org/postgresql/Driver.java.in b/src/interfaces/jdbc/org/postgresql/Driver.java.in
index c53747902ff..ecb22c7a0da 100644
--- a/src/interfaces/jdbc/org/postgresql/Driver.java.in
+++ b/src/interfaces/jdbc/org/postgresql/Driver.java.in
@@ -116,7 +116,7 @@ public class Driver implements java.sql.Driver
{
if (Driver.logDebug) Driver.debug("connect " + url);
- org.postgresql.Connection con = (org.postgresql.Connection)(Class.forName("@JDBCCONNECTCLASS@").newInstance());
+ @JDBCCONNECTCLASS@ con = (@JDBCCONNECTCLASS@)(Class.forName("@JDBCCONNECTCLASS@").newInstance());
con.openConnection (host(), port(), props, database(), url, this);
return (java.sql.Connection)con;
}
diff --git a/src/interfaces/jdbc/org/postgresql/Field.java b/src/interfaces/jdbc/org/postgresql/Field.java
index 8ab28057ef2..1dbaa72c097 100644
--- a/src/interfaces/jdbc/org/postgresql/Field.java
+++ b/src/interfaces/jdbc/org/postgresql/Field.java
@@ -17,7 +17,7 @@ public class Field
private int mod; // type modifier of this field
private String name; // Name of this field
- private Connection conn; // Connection Instantation
+ private org.postgresql.PGConnection conn; // Connection Instantation
/*
@@ -28,7 +28,7 @@ public class Field
* @param oid the OID of the field
* @param len the length of the field
*/
- public Field(Connection conn, String name, int oid, int length, int mod)
+ public Field(org.postgresql.PGConnection conn, String name, int oid, int length, int mod)
{
this.conn = conn;
this.name = name;
@@ -45,7 +45,7 @@ public class Field
* @param oid the OID of the field
* @param len the length of the field
*/
- public Field(Connection conn, String name, int oid, int length)
+ public Field(org.postgresql.PGConnection conn, String name, int oid, int length)
{
this(conn, name, oid, length, 0);
}
diff --git a/src/interfaces/jdbc/org/postgresql/PGConnection.java b/src/interfaces/jdbc/org/postgresql/PGConnection.java
new file mode 100644
index 00000000000..c05f31222c5
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/PGConnection.java
@@ -0,0 +1,72 @@
+package org.postgresql;
+
+import java.sql.*;
+import java.util.Properties;
+import java.util.Vector;
+import org.postgresql.core.Encoding;
+import org.postgresql.fastpath.Fastpath;
+import org.postgresql.largeobject.LargeObjectManager;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGConnection.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This interface defines PostgreSQL extentions to the java.sql.Connection interface.
+ * Any java.sql.Connection object returned by the driver will also implement this
+ * interface
+ */
+public interface PGConnection
+{
+ /*
+ * Get the character encoding to use for this connection.
+ */
+ public Encoding getEncoding() throws SQLException;
+
+ /*
+ * This method returns the java.sql.Types type for a postgres datatype name
+ */
+ public int getSQLType(String pgTypeName) throws SQLException;
+
+ /*
+ * This returns the java.sql.Types type for a postgres datatype OID
+ */
+ public int getSQLType(int oid) throws SQLException;
+
+ /*
+ * This returns the postgres datatype name from the
+ * postgres datatype OID
+ */
+ public String getPGType(int oid) throws SQLException;
+
+ /*
+ * This returns the postgres datatype OID from the
+ * postgres datatype name
+ */
+ public int getPGType(String typeName) throws SQLException;
+
+ /*
+ * This returns the LargeObject API for the current connection.
+ */
+ public LargeObjectManager getLargeObjectAPI() throws SQLException;
+
+ /*
+ * This returns the Fastpath API for the current connection.
+ */
+ public Fastpath getFastpathAPI() throws SQLException;
+
+ /*
+ * This method is used internally to return an object based around
+ * org.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 org.postgresql.util.PGobject
+ * is returned.
+ *
+ * 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
+ * @see org.postgresql.util.Serialize
+ */
+ public Object getObject(String type, String value) throws SQLException;
+
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/PGStatement.java b/src/interfaces/jdbc/org/postgresql/PGStatement.java
new file mode 100644
index 00000000000..1295afbe5aa
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/PGStatement.java
@@ -0,0 +1,21 @@
+package org.postgresql;
+
+
+import java.sql.*;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGStatement.java,v 1.3 2002/07/23 03:59:55 barry Exp $
+ * This interface defines PostgreSQL extentions to the java.sql.Statement interface.
+ * Any java.sql.Statement object returned by the driver will also implement this
+ * interface
+ */
+public interface PGStatement
+{
+
+ /*
+ * Returns the Last inserted/updated oid.
+ * @return OID of last insert
+ * @since 7.3
+ */
+ public long getLastOID() throws SQLException;
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/ResultSet.java b/src/interfaces/jdbc/org/postgresql/ResultSet.java
deleted file mode 100644
index 6e533eed010..00000000000
--- a/src/interfaces/jdbc/org/postgresql/ResultSet.java
+++ /dev/null
@@ -1,264 +0,0 @@
-package org.postgresql;
-
-import java.lang.*;
-import java.io.*;
-import java.math.*;
-import java.text.*;
-import java.util.*;
-import java.sql.*;
-import org.postgresql.largeobject.*;
-import org.postgresql.util.*;
-
-/*
- * This class implements the common internal methods used by both JDBC 1 and
- * JDBC 2 specifications.
- */
-public abstract class ResultSet
-{
- protected Vector rows; // The results
- protected Field fields[]; // The field descriptions
- protected String status; // Status of the result
- protected boolean binaryCursor = false; // is the data binary or Strings
- protected int updateCount; // How many rows did we get back?
- protected long insertOID; // The oid of an inserted row
- protected int current_row; // Our pointer to where we are at
- protected byte[][] this_row; // the current row result
- protected Connection connection; // the connection which we returned from
- protected SQLWarning warnings = null; // The warning chain
- protected boolean wasNullFlag = false; // the flag for wasNull()
-
- // We can chain multiple resultSets together - this points to
- // next resultSet in the chain.
- protected ResultSet next = null;
-
- /*
- * Create a new ResultSet - Note that we create ResultSets to
- * represent the results of everything.
- *
- * @param fields an array of Field objects (basically, the
- * ResultSet MetaData)
- * @param tuples Vector of the actual data
- * @param status the status string returned from the back end
- * @param updateCount the number of rows affected by the operation
- * @param cursor the positioned update/delete cursor name
- */
- public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
- {
- this.connection = conn;
- this.fields = fields;
- this.rows = tuples;
- this.status = status;
- this.updateCount = updateCount;
- this.insertOID = insertOID;
- this.this_row = null;
- this.current_row = -1;
- this.binaryCursor = binaryCursor;
- }
-
-
- /*
- * Create a new ResultSet - Note that we create ResultSets to
- * represent the results of everything.
- *
- * @param fields an array of Field objects (basically, the
- * ResultSet MetaData)
- * @param tuples Vector of the actual data
- * @param status the status string returned from the back end
- * @param updateCount the number of rows affected by the operation
- * @param cursor the positioned update/delete cursor name
- */
- public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
- {
- this(conn, fields, tuples, status, updateCount, 0, false);
- }
-
- /*
- * We at times need to know if the resultSet we are working
- * with is the result of an UPDATE, DELETE or INSERT (in which
- * case, we only have a row count), or of a SELECT operation
- * (in which case, we have multiple fields) - this routine
- * tells us.
- *
- * @return true if we have tuples available
- */
- public boolean reallyResultSet()
- {
- return (fields != null);
- }
-
- /*
- * Since ResultSets can be chained, we need some method of
- * finding the next one in the chain. The method getNext()
- * returns the next one in the chain.
- *
- * @return the next ResultSet, or null if there are none
- */
- public java.sql.ResultSet getNext()
- {
- return (java.sql.ResultSet)next;
- }
-
- /*
- * This following method allows us to add a ResultSet object
- * to the end of the current chain.
- *
- * @param r the resultset to add to the end of the chain.
- */
- public void append(ResultSet r)
- {
- if (next == null)
- next = r;
- else
- next.append(r);
- }
-
- /*
- * If we are just a place holder for results, we still need
- * to get an updateCount. This method returns it.
- *
- * @return the updateCount
- */
- public int getResultCount()
- {
- return updateCount;
- }
-
- /*
- * We also need to provide a couple of auxiliary functions for
- * the implementation of the ResultMetaData functions. In
- * particular, we need to know the number of rows and the
- * number of columns. Rows are also known as Tuples
- *
- * @return the number of rows
- */
- public int getTupleCount()
- {
- return rows.size();
- }
-
- /*
- * getColumnCount returns the number of columns
- *
- * @return the number of columns
- */
- public int getColumnCount()
- {
- return fields.length;
- }
-
- /*
- * Returns the status message from the backend.<p>
- * It is used internally by the driver.
- *
- * @return the status string from the backend
- */
- public String getStatusString()
- {
- return status;
- }
-
- /*
- * returns the OID of a field.<p>
- * It is used internally by the driver.
- *
- * @param field field id
- * @return the oid of that field's type
- */
- public int getColumnOID(int field)
- {
- return fields[field -1].getOID();
- }
-
- /*
- * returns the OID of the last inserted row. Deprecated in 7.2 because
- * range for OID values is greater than java signed int.
- * @deprecated Replaced by getLastOID() in 7.2
- */
- public int getInsertedOID()
- {
- return (int) getLastOID();
- }
-
-
- /*
- * returns the OID of the last inserted row
- * @since 7.2
- */
- public long getLastOID()
- {
- return insertOID;
- }
-
- /*
- * This is part of the JDBC API, but is required by org.postgresql.Field
- */
- public abstract void close() throws SQLException;
- public abstract boolean next() throws SQLException;
- public abstract String getString(int i) throws SQLException;
-
- /*
- * This is used to fix get*() methods on Money fields. It should only be
- * used by those methods!
- *
- * It converts ($##.##) to -##.## and $##.## to ##.##
- */
- public String getFixedString(int col) throws SQLException
- {
- String s = getString(col);
-
- // Handle SQL Null
- wasNullFlag = (this_row[col - 1] == null);
- if (wasNullFlag)
- return null;
-
- // Handle Money
- if (s.charAt(0) == '(')
- {
- s = "-" + org.postgresql.util.PGtokenizer.removePara(s).substring(1);
- }
- if (s.charAt(0) == '$')
- {
- s = s.substring(1);
- }
-
- return s;
- }
-
- /**
- * The first warning reported by calls on this ResultSet is
- * returned. Subsequent ResultSet warnings will be chained
- * to this SQLWarning.
- *
- * <p>The warning chain is automatically cleared each time a new
- * row is read.
- *
- * <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.
- *
- * @return the first SQLWarning or null;
- * @exception SQLException if a database access error occurs.
- */
- public SQLWarning getWarnings() throws SQLException
- {
- return warnings;
- }
-
- /**
- * Add a warning chain to the current warning chain
- * @param warnings warnings to add
- */
- public void addWarnings(SQLWarning warnings) {
- if ( this.warnings != null )
- this.warnings.setNextWarning(warnings);
- else
- this.warnings = warnings;
- }
- protected void checkResultSet( int column ) throws SQLException
- {
- if ( this_row == null ) throw new PSQLException("postgresql.res.nextrequired");
- if ( column < 1 || column > fields.length ) throw new PSQLException("postgresql.res.colrange" );
- }
-}
-
diff --git a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
index bfa6af35723..40c6a31d7f8 100644
--- a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
+++ b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
@@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException;
* <p>The lifetime of a QueryExecutor object is from sending the query
* until the response has been received from the backend.
*
- * $Id: QueryExecutor.java,v 1.12 2002/03/26 05:52:49 barry Exp $
+ * $Id: QueryExecutor.java,v 1.13 2002/07/23 03:59:55 barry Exp $
*/
public class QueryExecutor
@@ -22,18 +22,18 @@ public class QueryExecutor
private final String sql;
private final java.sql.Statement statement;
private final PG_Stream pg_stream;
- private final org.postgresql.Connection connection;
+ private final org.postgresql.jdbc1.AbstractJdbc1Connection connection;
public QueryExecutor(String sql,
java.sql.Statement statement,
PG_Stream pg_stream,
- org.postgresql.Connection connection)
+ java.sql.Connection connection)
throws SQLException
{
this.sql = sql;
this.statement = statement;
this.pg_stream = pg_stream;
- this.connection = connection;
+ this.connection = (org.postgresql.jdbc1.AbstractJdbc1Connection)connection;
if (statement != null)
maxRows = statement.getMaxRows();
@@ -122,7 +122,7 @@ public class QueryExecutor
if ( errorMessage != null )
throw new SQLException( errorMessage.toString() );
- return connection.getResultSet(connection, statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
+ return connection.getResultSet(statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
}
}
diff --git a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
index 20f5a6f3e26..d166b10f83b 100644
--- a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
+++ b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
@@ -28,7 +28,7 @@ public class Fastpath
// to a connection).
protected Hashtable func = new Hashtable();
- protected org.postgresql.Connection conn; // our connection
+ protected org.postgresql.PGConnection conn; // our connection
protected org.postgresql.PG_Stream stream; // the network stream
/*
@@ -41,7 +41,7 @@ public class Fastpath
* @param conn org.postgresql.Connection to attach to
* @param stream The network stream to the backend
*/
- public Fastpath(org.postgresql.Connection conn, org.postgresql.PG_Stream stream)
+ public Fastpath(org.postgresql.PGConnection conn, org.postgresql.PG_Stream stream)
{
this.conn = conn;
this.stream = stream;
@@ -113,7 +113,7 @@ public class Fastpath
//------------------------------
// Notice from backend
case 'N':
- conn.addWarning(stream.ReceiveString(conn.getEncoding()));
+ ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).addWarning(stream.ReceiveString(conn.getEncoding()));
break;
case 'V':
diff --git a/src/interfaces/jdbc/org/postgresql/Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java
index 7951ddd1ecb..98aa33e5c91 100644
--- a/src/interfaces/jdbc/org/postgresql/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java
@@ -1,34 +1,38 @@
-package org.postgresql;
+package org.postgresql.jdbc1;
-import java.io.*;
-import java.net.*;
+
+import java.io.IOException;
+import java.net.ConnectException;
import java.sql.*;
import java.util.*;
import org.postgresql.Driver;
-import org.postgresql.Field;
-import org.postgresql.fastpath.*;
-import org.postgresql.largeobject.*;
-import org.postgresql.util.*;
+import org.postgresql.PG_Stream;
import org.postgresql.core.*;
+import org.postgresql.fastpath.Fastpath;
+import org.postgresql.largeobject.LargeObjectManager;
+import org.postgresql.util.*;
+
-/*
- * $Id: Connection.java,v 1.48 2002/06/11 02:55:15 barry Exp $
- *
- * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
- * JDBC2 versions of the Connection class.
- *
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class defines methods of the jdbc1 specification. This class is
+ * extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds the jdbc2
+ * methods. The real Connection class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Connection
*/
-public abstract class Connection
+public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnection
{
// This is the network stream associated with this connection
public PG_Stream pg_stream;
- private String PG_HOST;
- private int PG_PORT;
- private String PG_USER;
- private String PG_DATABASE;
- private boolean PG_STATUS;
- private String compatible;
+ protected String PG_HOST;
+ protected int PG_PORT;
+ protected String PG_USER;
+ protected String PG_DATABASE;
+ protected boolean PG_STATUS;
+ protected String compatible;
+
+ // The PID an cancellation key we get from the backend process
+ protected int pid;
+ protected int ckey;
/*
The encoding to use for this connection.
@@ -43,7 +47,7 @@ public abstract class Connection
public boolean autoCommit = true;
public boolean readOnly = false;
- public Driver this_driver;
+ public org.postgresql.Driver this_driver;
private String this_url;
private String cursor = null; // The positioned update cursor name
@@ -74,50 +78,6 @@ public abstract class Connection
*/
private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;
- // The PID an cancellation key we get from the backend process
- public int pid;
- public int ckey;
-
- /*
- * This is called by Class.forName() from within org.postgresql.Driver
- */
- public Connection()
- {}
-
- public void cancelQuery() throws SQLException
- {
- PG_Stream cancelStream = null;
- try {
- cancelStream = new PG_Stream(PG_HOST, PG_PORT);
- } catch (ConnectException cex) {
- // Added by Peter Mount <peter@retep.org.uk>
- // ConnectException is thrown when the connection cannot be made.
- // we trap this an return a more meaningful message for the end user
- throw new PSQLException ("postgresql.con.refused");
- } catch (IOException e) {
- throw new PSQLException ("postgresql.con.failed",e);
- }
-
- // Now we need to construct and send a cancel packet
- try {
- cancelStream.SendInteger(16, 4);
- cancelStream.SendInteger(80877102, 4);
- cancelStream.SendInteger(pid, 4);
- cancelStream.SendInteger(ckey, 4);
- cancelStream.flush();
- }
- catch(IOException e) {
- throw new PSQLException("postgresql.con.failed",e);
- }
- finally {
- try {
- if(cancelStream != null)
- cancelStream.close();
- }
- catch(IOException e) {} // Ignore
- }
- }
-
/*
* This method actually opens the connection. It is called by Driver.
*
@@ -125,12 +85,11 @@ public abstract class Connection
* @param port the port number of the postmaster process
* @param info a Properties[] thing of the user and password
* @param database the database to connect to
- * @param u the URL of the connection
+ * @param url the URL of the connection
* @param d the Driver instantation of the connection
- * @return a valid connection profile
* @exception SQLException if a database access error occurs
*/
- protected void openConnection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException
+ public void openConnection(String host, int port, Properties info, String database, String url, org.postgresql.Driver d) throws SQLException
{
firstWarning = null;
@@ -140,7 +99,7 @@ public abstract class Connection
if (info.getProperty("user") == null)
throw new PSQLException("postgresql.con.user");
- this_driver = d;
+ this_driver = (org.postgresql.Driver)d;
this_url = url;
PG_DATABASE = database;
@@ -168,19 +127,19 @@ public abstract class Connection
int l_logLevel = 0;
try {
l_logLevel = Integer.parseInt(l_logLevelProp);
- if (l_logLevel > Driver.DEBUG || l_logLevel < Driver.INFO) {
+ if (l_logLevel > org.postgresql.Driver.DEBUG || l_logLevel < org.postgresql.Driver.INFO) {
l_logLevel = 0;
}
} catch (Exception l_e) {
//invalid value for loglevel ignore
}
if (l_logLevel > 0) {
- Driver.setLogLevel(l_logLevel);
+ org.postgresql.Driver.setLogLevel(l_logLevel);
enableDriverManagerLogging();
}
//Print out the driver version number
- if (Driver.logInfo) Driver.info(Driver.getVersion());
+ if (org.postgresql.Driver.logInfo) org.postgresql.Driver.info(org.postgresql.Driver.getVersion());
// Now make the initial connection
try
@@ -238,7 +197,7 @@ public abstract class Connection
rst[0] = (byte)pg_stream.ReceiveChar();
rst[1] = (byte)pg_stream.ReceiveChar();
salt = new String(rst, 0, 2);
- if (Driver.logDebug) Driver.debug("Crypt salt=" + salt);
+ if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("Crypt salt=" + salt);
}
// Or get the md5 password salt if there is one
@@ -250,7 +209,7 @@ public abstract class Connection
rst[2] = (byte)pg_stream.ReceiveChar();
rst[3] = (byte)pg_stream.ReceiveChar();
salt = new String(rst, 0, 4);
- if (Driver.logDebug) Driver.debug("MD5 salt=" + salt);
+ if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("MD5 salt=" + salt);
}
// now send the auth packet
@@ -260,15 +219,15 @@ public abstract class Connection
break;
case AUTH_REQ_KRB4:
- if (Driver.logDebug) Driver.debug("postgresql: KRB4");
+ if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB4");
throw new PSQLException("postgresql.con.kerb4");
case AUTH_REQ_KRB5:
- if (Driver.logDebug) Driver.debug("postgresql: KRB5");
+ if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB5");
throw new PSQLException("postgresql.con.kerb5");
case AUTH_REQ_PASSWORD:
- if (Driver.logDebug) Driver.debug("postgresql: PASSWORD");
+ if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: PASSWORD");
pg_stream.SendInteger(5 + password.length(), 4);
pg_stream.Send(password.getBytes());
pg_stream.SendInteger(0, 1);
@@ -276,7 +235,7 @@ public abstract class Connection
break;
case AUTH_REQ_CRYPT:
- if (Driver.logDebug) Driver.debug("postgresql: CRYPT");
+ if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: CRYPT");
String crypted = UnixCrypt.crypt(salt, password);
pg_stream.SendInteger(5 + crypted.length(), 4);
pg_stream.Send(crypted.getBytes());
@@ -285,7 +244,7 @@ public abstract class Connection
break;
case AUTH_REQ_MD5:
- if (Driver.logDebug) Driver.debug("postgresql: MD5");
+ if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: MD5");
byte[] digest = MD5Digest.encode(PG_USER, password, salt);
pg_stream.SendInteger(5 + digest.length, 4);
pg_stream.Send(digest);
@@ -386,10 +345,23 @@ public abstract class Connection
PG_STATUS = CONNECTION_OK;
}
+
+ /*
+ * Return the instance of org.postgresql.Driver
+ * that created this connection
+ */
+ public org.postgresql.Driver getDriver()
+ {
+ return this_driver;
+ }
+
// These methods used to be in the main Connection implementation. As they
// are common to all implementations (JDBC1 or 2), they are placed here.
// This should make it easy to maintain the two specifications.
+//BJL TODO this method shouldn't need to take a Connection since this can be used.
+ public abstract java.sql.ResultSet getResultSet(java.sql.Statement stat, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException;
+
/*
* This adds a warning to the warning chain.
* @param msg message to add
@@ -448,7 +420,7 @@ public abstract class Connection
*/
public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException
{
- return new QueryExecutor(sql, stat, pg_stream, this).execute();
+ return new QueryExecutor(sql, stat, pg_stream, (java.sql.Connection)this).execute();
}
/*
@@ -569,7 +541,7 @@ public abstract class Connection
public LargeObjectManager getLargeObjectAPI() throws SQLException
{
if (largeobject == null)
- largeobject = new LargeObjectManager(this);
+ largeobject = new LargeObjectManager((java.sql.Connection)this);
return largeobject;
}
@@ -606,7 +578,7 @@ public abstract class Connection
// can handle it
if (o == null)
{
- Serialize ser = new Serialize(this, type);
+ Serialize ser = new Serialize((java.sql.Connection)this, type);
objectTypes.put(type, ser);
return ser.fetch(Integer.parseInt(value));
}
@@ -679,7 +651,7 @@ public abstract class Connection
// can handle it
if (x == null)
{
- Serialize ser = new Serialize(this, type);
+ Serialize ser = new Serialize((java.sql.Connection)this, type);
objectTypes.put(type, ser);
return ser.storeObject(o);
}
@@ -756,15 +728,6 @@ public abstract class Connection
objectTypes.put(defaultObjectTypes[i][0], defaultObjectTypes[i][1]);
}
- // These are required by other common classes
- public abstract java.sql.Statement createStatement() throws SQLException;
-
- /*
- * This returns a resultset. It must be overridden, so that the correct
- * version (from jdbc1 or jdbc2) are returned.
- */
- public abstract java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException;
-
/*
* In some cases, it is desirable to immediately release a Connection's
* database and JDBC resources instead of waiting for them to be
@@ -1162,8 +1125,8 @@ public abstract class Connection
// it's not in the cache, so perform a query, and add the result to the cache
if (sqlType == null)
{
- ResultSet result = (org.postgresql.ResultSet)ExecSQL("select typname from pg_type where oid = " + oid);
- if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+ ResultSet result = ExecSQL("select typname from pg_type where oid = " + oid);
+ if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)result).getTupleCount() != 1)
throw new PSQLException("postgresql.unexpected");
result.next();
String pgType = result.getString(1);
@@ -1178,19 +1141,11 @@ public abstract class Connection
}
/*
- * This returns the java.sql.Types type for a PG type
- *
- * @param pgTypeName PostgreSQL type name
- * @return the java.sql.Types type
- */
- public abstract int getSQLType(String pgTypeName);
-
- /*
* This returns the oid for a given PG data type
* @param typeName PostgreSQL type name
* @return PostgreSQL oid value for a field of this type
*/
- public int getOID(String typeName) throws SQLException
+ public int getPGType(String typeName) throws SQLException
{
int oid = -1;
if (typeName != null)
@@ -1203,9 +1158,9 @@ public abstract class Connection
else
{
// it's not in the cache, so perform a query, and add the result to the cache
- ResultSet result = (org.postgresql.ResultSet)ExecSQL("select oid from pg_type where typname='"
+ ResultSet result = ExecSQL("select oid from pg_type where typname='"
+ typeName + "'");
- if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+ if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)result).getTupleCount() != 1)
throw new PSQLException("postgresql.unexpected");
result.next();
oid = Integer.parseInt(result.getString(1));
@@ -1242,5 +1197,91 @@ public abstract class Connection
}
}
+ // This is a cache of the DatabaseMetaData instance for this connection
+ protected java.sql.DatabaseMetaData metadata;
+
+
+ /*
+ * Tests to see if a Connection is closed
+ *
+ * @return the status of the connection
+ * @exception SQLException (why?)
+ */
+ public boolean isClosed() throws SQLException
+ {
+ return (pg_stream == null);
+ }
+
+ /*
+ * This implemetation uses the jdbc1Types array to support the jdbc1
+ * datatypes. Basically jdbc1 and jdbc2 are the same, except that
+ * jdbc2 adds the Array types.
+ */
+ public int getSQLType(String pgTypeName)
+ {
+ int sqlType = Types.OTHER; // default value
+ for (int i = 0;i < jdbc1Types.length;i++)
+ {
+ if (pgTypeName.equals(jdbc1Types[i]))
+ {
+ sqlType = jdbc1Typei[i];
+ break;
+ }
+ }
+ return sqlType;
+ }
+
+ /*
+ * This table holds the org.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 jdbc1Types[] = {
+ "int2",
+ "int4", "oid",
+ "int8",
+ "cash", "money",
+ "numeric",
+ "float4",
+ "float8",
+ "bpchar", "char", "char2", "char4", "char8", "char16",
+ "varchar", "text", "name", "filename",
+ "bytea",
+ "bool",
+ "date",
+ "time",
+ "abstime", "timestamp", "timestamptz"
+ };
+
+ /*
+ * 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 jdbc1Typei[] = {
+ Types.SMALLINT,
+ Types.INTEGER, Types.INTEGER,
+ Types.BIGINT,
+ Types.DOUBLE, Types.DOUBLE,
+ Types.NUMERIC,
+ 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.BINARY,
+ Types.BIT,
+ Types.DATE,
+ Types.TIME,
+ Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP
+ };
+
+
}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
new file mode 100644
index 00000000000..5aa4f90298a
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
@@ -0,0 +1,957 @@
+package org.postgresql.jdbc1;
+
+
+import java.math.BigDecimal;
+import java.io.*;
+import java.sql.*;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Vector;
+import org.postgresql.Field;
+import org.postgresql.core.Encoding;
+import org.postgresql.largeobject.*;
+import org.postgresql.util.PGbytea;
+import org.postgresql.util.PSQLException;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class defines methods of the jdbc1 specification. This class is
+ * extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2
+ * methods. The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet
+ */
+public abstract class AbstractJdbc1ResultSet
+{
+
+ protected Vector rows; // The results
+ protected Field fields[]; // The field descriptions
+ protected String status; // Status of the result
+ protected boolean binaryCursor = false; // is the data binary or Strings
+ protected int updateCount; // How many rows did we get back?
+ protected long insertOID; // The oid of an inserted row
+ protected int current_row; // Our pointer to where we are at
+ protected byte[][] this_row; // the current row result
+ protected org.postgresql.PGConnection connection; // the connection which we returned from
+ protected SQLWarning warnings = null; // The warning chain
+ protected boolean wasNullFlag = false; // the flag for wasNull()
+
+ // We can chain multiple resultSets together - this points to
+ // next resultSet in the chain.
+ protected ResultSet next = null;
+
+ protected StringBuffer sbuf = null;
+ public byte[][] rowBuffer=null;
+
+
+ public AbstractJdbc1ResultSet(org.postgresql.PGConnection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
+ {
+ this.connection = conn;
+ this.fields = fields;
+ this.rows = tuples;
+ this.status = status;
+ this.updateCount = updateCount;
+ this.insertOID = insertOID;
+ this.this_row = null;
+ this.current_row = -1;
+ this.binaryCursor = binaryCursor;
+ }
+
+
+ public boolean next() throws SQLException
+ {
+ if (rows == null)
+ throw new PSQLException("postgresql.con.closed");
+
+ if (++current_row >= rows.size())
+ return false;
+
+ this_row = (byte [][])rows.elementAt(current_row);
+
+ rowBuffer=new byte[this_row.length][];
+ System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
+ return true;
+ }
+
+ public void close() throws SQLException
+ {
+ //release resources held (memory for tuples)
+ if (rows != null)
+ {
+ rows = null;
+ }
+ }
+
+ public boolean wasNull() throws SQLException
+ {
+ return wasNullFlag;
+ }
+
+ public String getString(int columnIndex) throws SQLException
+ {
+ checkResultSet( columnIndex );
+ wasNullFlag = (this_row[columnIndex - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ Encoding encoding = connection.getEncoding();
+ return encoding.decode(this_row[columnIndex - 1]);
+ }
+
+ public boolean getBoolean(int columnIndex) throws SQLException
+ {
+ return toBoolean( getString(columnIndex) );
+ }
+
+
+ public byte getByte(int columnIndex) throws SQLException
+ {
+ String s = getString(columnIndex);
+
+ if (s != null)
+ {
+ try
+ {
+ return Byte.parseByte(s);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException("postgresql.res.badbyte", s);
+ }
+ }
+ return 0; // SQL NULL
+ }
+
+ public short getShort(int columnIndex) throws SQLException
+ {
+ String s = getFixedString(columnIndex);
+
+ if (s != null)
+ {
+ try
+ {
+ return Short.parseShort(s);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException("postgresql.res.badshort", s);
+ }
+ }
+ return 0; // SQL NULL
+ }
+
+ public int getInt(int columnIndex) throws SQLException
+ {
+ return toInt( getFixedString(columnIndex) );
+ }
+
+ public long getLong(int columnIndex) throws SQLException
+ {
+ return toLong( getFixedString(columnIndex) );
+ }
+
+ public float getFloat(int columnIndex) throws SQLException
+ {
+ return toFloat( getFixedString(columnIndex) );
+ }
+
+ public double getDouble(int columnIndex) throws SQLException
+ {
+ return toDouble( getFixedString(columnIndex) );
+ }
+
+ public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException
+ {
+ return toBigDecimal( getFixedString(columnIndex), scale );
+ }
+
+ /*
+ * 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
+ * is null
+ * @exception SQLException if a database access error occurs
+ */
+ public byte[] getBytes(int columnIndex) throws SQLException
+ {
+ checkResultSet( columnIndex );
+ wasNullFlag = (this_row[columnIndex - 1] == null);
+ if (!wasNullFlag)
+ {
+ if (binaryCursor)
+ {
+ //If the data is already binary then just return it
+ return this_row[columnIndex - 1];
+ }
+ else if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
+ {
+ //Version 7.2 supports the bytea datatype for byte arrays
+ if (fields[columnIndex - 1].getPGType().equals("bytea"))
+ {
+ return PGbytea.toBytes(this_row[columnIndex - 1]);
+ }
+ else
+ {
+ return this_row[columnIndex - 1];
+ }
+ }
+ else
+ {
+ //Version 7.1 and earlier supports LargeObjects for byte arrays
+ // Handle OID's as BLOBS
+ 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;
+ }
+ else
+ {
+ return this_row[columnIndex - 1];
+ }
+ }
+ }
+ return null;
+ }
+
+ public java.sql.Date getDate(int columnIndex) throws SQLException
+ {
+ return toDate( getString(columnIndex) );
+ }
+
+ public Time getTime(int columnIndex) throws SQLException
+ {
+ return toTime( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex-1].getPGType() );
+ }
+
+ public Timestamp getTimestamp(int columnIndex) throws SQLException
+ {
+ return toTimestamp( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex-1].getPGType() );
+ }
+
+ public InputStream getAsciiStream(int columnIndex) throws SQLException
+ {
+ checkResultSet( columnIndex );
+ wasNullFlag = (this_row[columnIndex - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
+ {
+ //Version 7.2 supports AsciiStream for all the PG text types
+ //As the spec/javadoc for this method indicate this is to be used for
+ //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
+ //long string datatype, but with toast the text datatype is capable of
+ //handling very large values. Thus the implementation ends up calling
+ //getString() since there is no current way to stream the value from the server
+ try
+ {
+ return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII"));
+ }
+ catch (UnsupportedEncodingException l_uee)
+ {
+ throw new PSQLException("postgresql.unusual", l_uee);
+ }
+ }
+ else
+ {
+ // In 7.1 Handle as BLOBS so return the LargeObject input stream
+ return getBinaryStream(columnIndex);
+ }
+ }
+
+ public InputStream getUnicodeStream(int columnIndex) throws SQLException
+ {
+ checkResultSet( columnIndex );
+ wasNullFlag = (this_row[columnIndex - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
+ {
+ //Version 7.2 supports AsciiStream for all the PG text types
+ //As the spec/javadoc for this method indicate this is to be used for
+ //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
+ //long string datatype, but with toast the text datatype is capable of
+ //handling very large values. Thus the implementation ends up calling
+ //getString() since there is no current way to stream the value from the server
+ try
+ {
+ return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8"));
+ }
+ catch (UnsupportedEncodingException l_uee)
+ {
+ throw new PSQLException("postgresql.unusual", l_uee);
+ }
+ }
+ else
+ {
+ // In 7.1 Handle as BLOBS so return the LargeObject input stream
+ return getBinaryStream(columnIndex);
+ }
+ }
+
+ public InputStream getBinaryStream(int columnIndex) throws SQLException
+ {
+ checkResultSet( columnIndex );
+ wasNullFlag = (this_row[columnIndex - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
+ {
+ //Version 7.2 supports BinaryStream for all PG bytea type
+ //As the spec/javadoc for this method indicate this is to be used for
+ //large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
+ //long binary datatype, but with toast the bytea datatype is capable of
+ //handling very large values. Thus the implementation ends up calling
+ //getBytes() since there is no current way to stream the value from the server
+ byte b[] = getBytes(columnIndex);
+ if (b != null)
+ return new ByteArrayInputStream(b);
+ }
+ else
+ {
+ // In 7.1 Handle as BLOBS so return the LargeObject input stream
+ if ( fields[columnIndex - 1].getOID() == 26)
+ {
+ LargeObjectManager lom = connection.getLargeObjectAPI();
+ LargeObject lob = lom.open(getInt(columnIndex));
+ return lob.getInputStream();
+ }
+ }
+ return null;
+ }
+
+ public String getString(String columnName) throws SQLException
+ {
+ return getString(findColumn(columnName));
+ }
+
+ public boolean getBoolean(String columnName) throws SQLException
+ {
+ return getBoolean(findColumn(columnName));
+ }
+
+ public byte getByte(String columnName) throws SQLException
+ {
+
+ return getByte(findColumn(columnName));
+ }
+
+ public short getShort(String columnName) throws SQLException
+ {
+ return getShort(findColumn(columnName));
+ }
+
+ public int getInt(String columnName) throws SQLException
+ {
+ return getInt(findColumn(columnName));
+ }
+
+ public long getLong(String columnName) throws SQLException
+ {
+ return getLong(findColumn(columnName));
+ }
+
+ public float getFloat(String columnName) throws SQLException
+ {
+ return getFloat(findColumn(columnName));
+ }
+
+ public double getDouble(String columnName) throws SQLException
+ {
+ return getDouble(findColumn(columnName));
+ }
+
+ public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException
+ {
+ return getBigDecimal(findColumn(columnName), scale);
+ }
+
+ public byte[] getBytes(String columnName) throws SQLException
+ {
+ return getBytes(findColumn(columnName));
+ }
+
+ public java.sql.Date getDate(String columnName) throws SQLException
+ {
+ return getDate(findColumn(columnName));
+ }
+
+ public Time getTime(String columnName) throws SQLException
+ {
+ return getTime(findColumn(columnName));
+ }
+
+ public Timestamp getTimestamp(String columnName) throws SQLException
+ {
+ return getTimestamp(findColumn(columnName));
+ }
+
+ public InputStream getAsciiStream(String columnName) throws SQLException
+ {
+ return getAsciiStream(findColumn(columnName));
+ }
+
+ public InputStream getUnicodeStream(String columnName) throws SQLException
+ {
+ return getUnicodeStream(findColumn(columnName));
+ }
+
+ public InputStream getBinaryStream(String columnName) throws SQLException
+ {
+ return getBinaryStream(findColumn(columnName));
+ }
+
+ public SQLWarning getWarnings() throws SQLException
+ {
+ return warnings;
+ }
+
+ public void clearWarnings() throws SQLException
+ {
+ warnings = null;
+ }
+
+ public void addWarnings(SQLWarning warnings) {
+ if ( this.warnings != null )
+ this.warnings.setNextWarning(warnings);
+ else
+ this.warnings = warnings;
+ }
+
+ public String getCursorName() throws SQLException
+ {
+ return ((AbstractJdbc1Connection)connection).getCursorName();
+ }
+
+ /*
+ * Get the value of a column in the current row as a Java object
+ *
+ * <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.
+ *
+ * <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...
+ * @return a Object holding the column value
+ * @exception SQLException if a database access error occurs
+ */
+ public Object getObject(int columnIndex) throws SQLException
+ {
+ Field field;
+
+ if (columnIndex < 1 || columnIndex > fields.length)
+ throw new PSQLException("postgresql.res.colrange");
+ field = fields[columnIndex - 1];
+
+ // some fields can be null, mainly from those returned by MetaData methods
+ if (field == null)
+ {
+ wasNullFlag = true;
+ return null;
+ }
+
+ switch (field.getSQLType())
+ {
+ case Types.BIT:
+ return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE;
+ case Types.SMALLINT:
+ return new Short(getShort(columnIndex));
+ case Types.INTEGER:
+ return new Integer(getInt(columnIndex));
+ case Types.BIGINT:
+ return new Long(getLong(columnIndex));
+ case Types.NUMERIC:
+ return getBigDecimal
+ (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff));
+ case Types.REAL:
+ return new Float(getFloat(columnIndex));
+ case Types.DOUBLE:
+ return new Double(getDouble(columnIndex));
+ case Types.CHAR:
+ case Types.VARCHAR:
+ return getString(columnIndex);
+ case Types.DATE:
+ return getDate(columnIndex);
+ case Types.TIME:
+ return getTime(columnIndex);
+ case Types.TIMESTAMP:
+ return getTimestamp(columnIndex);
+ case Types.BINARY:
+ case Types.VARBINARY:
+ return getBytes(columnIndex);
+ default:
+ String type = field.getPGType();
+ // if the backend doesn't know the type then coerce to String
+ if (type.equals("unknown"))
+ {
+ return getString(columnIndex);
+ }
+ else
+ {
+ return connection.getObject(field.getPGType(), getString(columnIndex));
+ }
+ }
+ }
+
+ public Object getObject(String columnName) throws SQLException
+ {
+ return getObject(findColumn(columnName));
+ }
+
+ /*
+ * Map a ResultSet column name to a ResultSet column index
+ */
+ public int findColumn(String columnName) throws SQLException
+ {
+ int i;
+
+ final int flen = fields.length;
+ for (i = 0 ; i < flen; ++i)
+ if (fields[i].getName().equalsIgnoreCase(columnName))
+ return (i + 1);
+ throw new PSQLException ("postgresql.res.colname", columnName);
+ }
+
+
+ /*
+ * We at times need to know if the resultSet we are working
+ * with is the result of an UPDATE, DELETE or INSERT (in which
+ * case, we only have a row count), or of a SELECT operation
+ * (in which case, we have multiple fields) - this routine
+ * tells us.
+ */
+ public boolean reallyResultSet()
+ {
+ return (fields != null);
+ }
+
+ /*
+ * Since ResultSets can be chained, we need some method of
+ * finding the next one in the chain. The method getNext()
+ * returns the next one in the chain.
+ *
+ * @return the next ResultSet, or null if there are none
+ */
+ public java.sql.ResultSet getNext()
+ {
+ return (java.sql.ResultSet)next;
+ }
+
+ /*
+ * This following method allows us to add a ResultSet object
+ * to the end of the current chain.
+ */
+ public void append(AbstractJdbc1ResultSet r)
+ {
+ if (next == null)
+ next = (java.sql.ResultSet)r;
+ else
+ ((AbstractJdbc1ResultSet)next).append(r);
+ }
+
+ /*
+ * If we are just a place holder for results, we still need
+ * to get an updateCount. This method returns it.
+ */
+ public int getResultCount()
+ {
+ return updateCount;
+ }
+
+ /*
+ * We also need to provide a couple of auxiliary functions for
+ * the implementation of the ResultMetaData functions. In
+ * particular, we need to know the number of rows and the
+ * number of columns. Rows are also known as Tuples
+ */
+ public int getTupleCount()
+ {
+ return rows.size();
+ }
+
+ /*
+ * getColumnCount returns the number of columns
+ */
+ public int getColumnCount()
+ {
+ return fields.length;
+ }
+
+ /*
+ * Returns the status message from the backend.<p>
+ * It is used internally by the driver.
+ */
+ public String getStatusString()
+ {
+ return status;
+ }
+
+ /*
+ * returns the OID of a field.<p>
+ * It is used internally by the driver.
+ */
+ public int getColumnOID(int field)
+ {
+ return fields[field -1].getOID();
+ }
+
+ /*
+ * returns the OID of the last inserted row. Deprecated in 7.2 because
+ * range for OID values is greater than java signed int.
+ * @deprecated Replaced by getLastOID() in 7.2
+ */
+ public int getInsertedOID()
+ {
+ return (int) getLastOID();
+ }
+
+
+ /*
+ * returns the OID of the last inserted row
+ * @since 7.2
+ */
+ public long getLastOID()
+ {
+ return insertOID;
+ }
+
+ /*
+ * This is used to fix get*() methods on Money fields. It should only be
+ * used by those methods!
+ *
+ * It converts ($##.##) to -##.## and $##.## to ##.##
+ */
+ public String getFixedString(int col) throws SQLException
+ {
+ String s = getString(col);
+
+ // Handle SQL Null
+ wasNullFlag = (this_row[col - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ // Handle Money
+ if (s.charAt(0) == '(')
+ {
+ s = "-" + org.postgresql.util.PGtokenizer.removePara(s).substring(1);
+ }
+ if (s.charAt(0) == '$')
+ {
+ s = s.substring(1);
+ }
+
+ return s;
+ }
+
+ protected void checkResultSet( int column ) throws SQLException
+ {
+ if ( this_row == null ) throw new PSQLException("postgresql.res.nextrequired");
+ if ( column < 1 || column > fields.length ) throw new PSQLException("postgresql.res.colrange" );
+ }
+
+ //----------------- Formatting Methods -------------------
+
+ public static boolean toBoolean(String s)
+ {
+ if (s != null)
+ {
+ int c = s.charAt(0);
+ return ((c == 't') || (c == 'T') || (c == '1'));
+ }
+ return false; // SQL NULL
+ }
+
+ public static int toInt(String s) throws SQLException
+ {
+ if (s != null)
+ {
+ try
+ {
+ return Integer.parseInt(s);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException ("postgresql.res.badint", s);
+ }
+ }
+ return 0; // SQL NULL
+ }
+
+ public static long toLong(String s) throws SQLException
+ {
+ if (s != null)
+ {
+ try
+ {
+ return Long.parseLong(s);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException ("postgresql.res.badlong", s);
+ }
+ }
+ return 0; // SQL NULL
+ }
+
+ public static BigDecimal toBigDecimal(String s, int scale) throws SQLException
+ {
+ BigDecimal val;
+ if (s != null)
+ {
+ try
+ {
+ val = new BigDecimal(s);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException ("postgresql.res.badbigdec", s);
+ }
+ if (scale == -1)
+ return val;
+ try
+ {
+ return val.setScale(scale);
+ }
+ catch (ArithmeticException e)
+ {
+ throw new PSQLException ("postgresql.res.badbigdec", s);
+ }
+ }
+ return null; // SQL NULL
+ }
+
+ public static float toFloat(String s) throws SQLException
+ {
+ if (s != null)
+ {
+ try
+ {
+ return Float.valueOf(s).floatValue();
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException ("postgresql.res.badfloat", s);
+ }
+ }
+ return 0; // SQL NULL
+ }
+
+ public static double toDouble(String s) throws SQLException
+ {
+ if (s != null)
+ {
+ try
+ {
+ return Double.valueOf(s).doubleValue();
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException ("postgresql.res.baddouble", s);
+ }
+ }
+ return 0; // SQL NULL
+ }
+
+ public static java.sql.Date toDate(String s) throws SQLException
+ {
+ if (s == null)
+ return null;
+ // length == 10: SQL Date
+ // length > 10: SQL Timestamp, assumes PGDATESTYLE=ISO
+ try
+ {
+ return java.sql.Date.valueOf((s.length() == 10) ? s : s.substring(0, 10));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException("postgresql.res.baddate", s);
+ }
+ }
+
+ public static Time toTime(String s, java.sql.ResultSet resultSet, String pgDataType) throws SQLException
+ {
+ if (s == null)
+ return null; // SQL NULL
+ try
+ {
+ if (s.length() == 8) {
+ //value is a time value
+ return java.sql.Time.valueOf(s);
+ } else if (s.indexOf(".") == 8) {
+ //value is a time value with fractional seconds
+ java.sql.Time l_time = java.sql.Time.valueOf(s.substring(0,8));
+ String l_strMillis = s.substring(9);
+ if (l_strMillis.length() > 3)
+ l_strMillis = l_strMillis.substring(0,3);
+ int l_millis = Integer.parseInt(l_strMillis);
+ if (l_millis < 10) {
+ l_millis = l_millis * 100;
+ } else if (l_millis < 100) {
+ l_millis = l_millis * 10;
+ }
+ return new java.sql.Time(l_time.getTime() + l_millis);
+ } else {
+ //value is a timestamp
+ return new java.sql.Time(toTimestamp(s, resultSet, pgDataType).getTime());
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PSQLException("postgresql.res.badtime", s);
+ }
+ }
+
+ /**
+ * Parse a string and return a timestamp representing its value.
+ *
+ * The driver is set to return ISO date formated strings. We modify this
+ * string from the ISO format to a format that Java can understand. Java
+ * expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
+ * Java also expects fractional seconds to 3 places where postgres
+ * will give, none, 2 or 6 depending on the time and postgres version.
+ * From version 7.2 postgres returns fractional seconds to 6 places.
+ * If available, we drop the last 3 digits.
+ *
+ * @param s The ISO formated date string to parse.
+ * @param resultSet The ResultSet this date is part of.
+ *
+ * @return null if s is null or a timestamp of the parsed string s.
+ *
+ * @throws SQLException if there is a problem parsing s.
+ **/
+ public static Timestamp toTimestamp(String s, java.sql.ResultSet resultSet, String pgDataType)
+ throws SQLException
+ {
+ AbstractJdbc1ResultSet rs = (AbstractJdbc1ResultSet)resultSet;
+ if (s == null)
+ return null;
+
+ // We must be synchronized here incase more theads access the ResultSet
+ // bad practice but possible. Anyhow this is to protect sbuf and
+ // SimpleDateFormat objects
+ synchronized (rs)
+ {
+ SimpleDateFormat df = null;
+ if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug("the data from the DB is "+s);
+
+ // If first time, create the buffer, otherwise clear it.
+ if (rs.sbuf == null)
+ rs.sbuf = new StringBuffer();
+ else
+ rs.sbuf.setLength(0);
+
+ // Copy s into sbuf for parsing.
+ rs.sbuf.append(s);
+ int slen = s.length();
+
+ if (slen > 19)
+ {
+ // The len of the ISO string to the second value is 19 chars. If
+ // greater then 19, there may be tz info and perhaps fractional
+ // second info which we need to change to java to read it.
+
+ // cut the copy to second value "2001-12-07 16:29:22"
+ int i = 19;
+ rs.sbuf.setLength(i);
+
+ char c = s.charAt(i++);
+ if (c == '.')
+ {
+ // Found a fractional value. Append up to 3 digits including
+ // the leading '.'
+ do
+ {
+ if (i < 24)
+ rs.sbuf.append(c);
+ c = s.charAt(i++);
+ } while (i < slen && Character.isDigit(c));
+
+ // If there wasn't at least 3 digits we should add some zeros
+ // to make up the 3 digits we tell java to expect.
+ for (int j = i; j < 24; j++)
+ rs.sbuf.append('0');
+ }
+ else
+ {
+ // No fractional seconds, lets add some.
+ rs.sbuf.append(".000");
+ }
+
+ if (i < slen)
+ {
+ // prepend the GMT part and then add the remaining bit of
+ // the string.
+ rs.sbuf.append(" GMT");
+ rs.sbuf.append(c);
+ rs.sbuf.append(s.substring(i, slen));
+
+ // Lastly, if the tz part doesn't specify the :MM part then
+ // we add ":00" for java.
+ if (slen - i < 5)
+ rs.sbuf.append(":00");
+
+ // we'll use this dateformat string to parse the result.
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
+ }
+ else
+ {
+ // Just found fractional seconds but no timezone.
+ //If timestamptz then we use GMT, else local timezone
+ if (pgDataType.equals("timestamptz")) {
+ rs.sbuf.append(" GMT");
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
+ } else {
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ }
+ }
+ }
+ else if (slen == 19)
+ {
+ // No tz or fractional second info.
+ //If timestamptz then we use GMT, else local timezone
+ if (pgDataType.equals("timestamptz")) {
+ rs.sbuf.append(" GMT");
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+ } else {
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ }
+ }
+ else
+ {
+ // We must just have a date. This case is
+ // needed if this method is called on a date
+ // column
+ df = new SimpleDateFormat("yyyy-MM-dd");
+ }
+
+ try
+ {
+ // All that's left is to parse the string and return the ts.
+ if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug( "" + df.parse(rs.sbuf.toString()).getTime() );
+
+ return new Timestamp(df.parse(rs.sbuf.toString()).getTime());
+ }
+ catch (ParseException e)
+ {
+ throw new PSQLException("postgresql.res.badtimestamp", new Integer(e.getErrorOffset()), s);
+ }
+ }
+ }
+
+
+
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
index ea2cc0d0c33..9c4d2b1cd9c 100644
--- a/src/interfaces/jdbc/org/postgresql/Statement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
@@ -1,24 +1,22 @@
-package org.postgresql;
+package org.postgresql.jdbc1;
import java.sql.*;
import org.postgresql.util.PSQLException;
-/*
- * This class defines methods implemented by the two subclasses
- * org.postgresql.jdbc1.Statement and org.postgresql.jdbc2.Statement that are
- * unique to PostgreSQL's JDBC driver.
- *
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class defines methods of the jdbc1 specification. This class is
+ * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
+ * methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
*/
-
-public abstract class Statement
+public abstract class AbstractJdbc1Statement implements org.postgresql.PGStatement
{
+ // The connection who created us
+ protected AbstractJdbc1Connection connection;
+
/** The warnings chain. */
protected SQLWarning warnings = null;
- /** The current results */
- protected java.sql.ResultSet result = null;
-
/** Maximum number of rows to return, 0 = unlimited */
protected int maxrows = 0;
@@ -27,14 +25,146 @@ public abstract class Statement
protected boolean escapeProcessing = true;
+ /** The current results */
+ protected java.sql.ResultSet result = null;
+
// Static variables for parsing SQL when escapeProcessing is true.
private static final short IN_SQLCODE = 0;
private static final short IN_STRING = 1;
private static final short BACKSLASH = 2;
private static final short ESC_TIMEDATE = 3;
- public Statement()
- {}
+ /*
+ * Execute a SQL statement that retruns a single ResultSet
+ *
+ * @param sql typically a static SQL SELECT statement
+ * @return a ResulSet that contains the data produced by the query
+ * @exception SQLException if a database access error occurs
+ */
+ public java.sql.ResultSet executeQuery(String sql) throws SQLException
+ {
+ this.execute(sql);
+ while (result != null && !((AbstractJdbc1ResultSet)result).reallyResultSet())
+ result = ((AbstractJdbc1ResultSet)result).getNext();
+ if (result == null)
+ throw new PSQLException("postgresql.stat.noresult");
+ return result;
+ }
+
+ /*
+ * Execute a SQL INSERT, UPDATE or DELETE statement. In addition
+ * SQL statements that return nothing such as SQL DDL statements
+ * can be executed
+ *
+ * @param sql a SQL statement
+ * @return either a row count, or 0 for SQL commands
+ * @exception SQLException if a database access error occurs
+ */
+ public int executeUpdate(String sql) throws SQLException
+ {
+ this.execute(sql);
+ if (((AbstractJdbc1ResultSet)result).reallyResultSet())
+ throw new PSQLException("postgresql.stat.result");
+ return this.getUpdateCount();
+ }
+
+ /*
+ * Execute a SQL statement that may return multiple results. We
+ * don't have to worry about this since we do not support multiple
+ * ResultSets. You can use getResultSet or getUpdateCount to
+ * retrieve the result.
+ *
+ * @param sql any SQL statement
+ * @return true if the next result is a ResulSet, false if it is
+ * an update count or there are no more results
+ * @exception SQLException if a database access error occurs
+ */
+ public boolean execute(String sql) throws SQLException
+ {
+ if (escapeProcessing)
+ sql = escapeSQL(sql);
+
+ // New in 7.1, if we have a previous resultset then force it to close
+ // This brings us nearer to compliance, and helps memory management.
+ // Internal stuff will call ExecSQL directly, bypassing this.
+ if (result != null)
+ {
+ java.sql.ResultSet rs = getResultSet();
+ if (rs != null)
+ rs.close();
+ }
+
+
+ // New in 7.1, pass Statement so that ExecSQL can customise to it
+ result = ((AbstractJdbc1Connection)connection).ExecSQL(sql, (java.sql.Statement)this);
+
+ return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet());
+ }
+
+ /*
+ * setCursorName defines the SQL cursor name that will be used by
+ * subsequent execute methods. This name can then be used in SQL
+ * positioned update/delete statements to identify the current row
+ * in the ResultSet generated by this statement. If a database
+ * doesn't support positioned update/delete, this method is a
+ * no-op.
+ *
+ * <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.
+ *
+ * <p>We throw an additional constriction. There can only be one
+ * cursor active at any one time.
+ *
+ * @param name the new cursor name
+ * @exception SQLException if a database access error occurs
+ */
+ public void setCursorName(String name) throws SQLException
+ {
+ ((AbstractJdbc1Connection)connection).setCursorName(name);
+ }
+
+
+ /*
+ * getUpdateCount returns the current result as an update count,
+ * if the result is a ResultSet or there are no more results, -1
+ * is returned. It should only be called once per result.
+ *
+ * @return the current result as an update count.
+ * @exception SQLException if a database access error occurs
+ */
+ public int getUpdateCount() throws SQLException
+ {
+ if (result == null)
+ return -1;
+ if (((AbstractJdbc1ResultSet)result).reallyResultSet())
+ return -1;
+ return ((AbstractJdbc1ResultSet)result).getResultCount();
+ }
+
+ /*
+ * getMoreResults moves to a Statement's next result. If it returns
+ * true, this result is a ResulSet.
+ *
+ * @return true if the next ResultSet is valid
+ * @exception SQLException if a database access error occurs
+ */
+ public boolean getMoreResults() throws SQLException
+ {
+ result = ((AbstractJdbc1ResultSet)result).getNext();
+ return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet());
+ }
+
+
+
+
+
+
+
+
+
+
/*
* Returns the status message from the current Result.<p>
@@ -46,7 +176,7 @@ public abstract class Statement
{
if (result == null)
return null;
- return ((org.postgresql.ResultSet) result).getStatusString();
+ return ((AbstractJdbc1ResultSet)result).getStatusString();
}
/*
@@ -195,30 +325,6 @@ public abstract class Statement
}
/*
- * Returns the Last inserted/updated oid. Deprecated in 7.2 because
- * range of OID values is greater than a java signed int.
- * @deprecated Replaced by getLastOID in 7.2
- */
- public int getInsertedOID() throws SQLException
- {
- if (result == null)
- return 0;
- return (int)((org.postgresql.ResultSet) result).getLastOID();
- }
-
- /*
- * Returns the Last inserted/updated oid.
- * @return OID of last insert
- * @since 7.2
- */
- public long getLastOID() throws SQLException
- {
- if (result == null)
- return 0;
- return ((org.postgresql.ResultSet) result).getLastOID();
- }
-
- /*
* getResultSet returns the current result as a ResultSet. It
* should only be called once per result.
*
@@ -227,7 +333,7 @@ public abstract class Statement
*/
public java.sql.ResultSet getResultSet() throws SQLException
{
- if (result != null && ((org.postgresql.ResultSet) result).reallyResultSet())
+ if (result != null && ((AbstractJdbc1ResultSet) result).reallyResultSet())
return result;
return null;
}
@@ -328,4 +434,38 @@ public abstract class Statement
return newsql.toString();
}
+
+ /*
+ *
+ * The following methods are postgres extensions and are defined
+ * in the interface org.postgresql.Statement
+ *
+ */
+
+ /*
+ * Returns the Last inserted/updated oid. Deprecated in 7.2 because
+ * range of OID values is greater than a java signed int.
+ * @deprecated Replaced by getLastOID in 7.2
+ */
+ public int getInsertedOID() throws SQLException
+ {
+ if (result == null)
+ return 0;
+ return (int)((AbstractJdbc1ResultSet)result).getLastOID();
+ }
+
+ /*
+ * Returns the Last inserted/updated oid.
+ * @return OID of last insert
+ * @since 7.2
+ */
+ public long getLastOID() throws SQLException
+ {
+ if (result == null)
+ return 0;
+ return ((AbstractJdbc1ResultSet)result).getLastOID();
+ }
+
+
+
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java
index 4a006cd2208..10e8c5f4171 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java
@@ -44,7 +44,7 @@ public class CallableStatement extends PreparedStatement implements java.sql.Cal
/*
* @exception SQLException on failure
*/
- CallableStatement(Connection c, String q) throws SQLException
+ CallableStatement(Jdbc1Connection c, String q) throws SQLException
{
super(c, q);
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
deleted file mode 100644
index 4d3e087f76b..00000000000
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
+++ /dev/null
@@ -1,214 +0,0 @@
-package org.postgresql.jdbc1;
-
-// IMPORTANT NOTE: This file implements the JDBC 1 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 2 class in the
-// org.postgresql.jdbc2 package.
-
-import java.io.*;
-import java.lang.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.util.*;
-import java.sql.*;
-import org.postgresql.Field;
-import org.postgresql.fastpath.*;
-import org.postgresql.largeobject.*;
-import org.postgresql.util.*;
-
-/*
- * $Id: Connection.java,v 1.15 2002/01/15 06:55:13 barry Exp $
- *
- * A Connection represents a session with a specific database. Within the
- * context of a Connection, SQL statements are executed and results are
- * returned.
- *
- * <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.
- *
- * <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.
- *
- * @see java.sql.Connection
- */
-public class Connection extends org.postgresql.Connection implements java.sql.Connection
-{
- // This is a cache of the DatabaseMetaData instance for this connection
- protected DatabaseMetaData metadata;
-
- /*
- * SQL statements without parameters are normally executed using
- * Statement objects. If the same SQL statement is executed many
- * times, it is more efficient to use a PreparedStatement
- *
- * @return a new Statement object
- * @exception SQLException passed through from the constructor
- */
- public java.sql.Statement createStatement() throws SQLException
- {
- return new Statement(this);
- }
-
- /*
- * A SQL statement with or without IN parameters can be pre-compiled
- * and stored in a PreparedStatement object. This object can then
- * be used to efficiently execute this statement multiple times.
- *
- * <B>Note:</B> This method is optimized for handling parametric
- * SQL statements that benefit from precompilation if the drivers
- * supports precompilation. PostgreSQL does not support precompilation.
- * In this case, the statement is not sent to the database until the
- * PreparedStatement is executed. This has no direct effect on users;
- * however it does affect which method throws certain SQLExceptions
- *
- * @param sql a SQL statement that may contain one or more '?' IN
- * parameter placeholders
- * @return a new PreparedStatement object containing the pre-compiled
- * statement.
- * @exception SQLException if a database access error occurs.
- */
- public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
- {
- return new PreparedStatement(this, sql);
- }
-
- /*
- * A SQL stored procedure call statement is handled by creating a
- * CallableStatement for it. The CallableStatement provides methods
- * for setting up its IN and OUT parameters and methods for executing
- * it.
- *
- * <B>Note:</B> This method is optimised for handling stored procedure
- * call statements. Some drivers may send the call statement to the
- * database when the prepareCall is done; others may wait until the
- * CallableStatement is executed. This has no direct effect on users;
- * however, it does affect which method throws certain SQLExceptions
- *
- * @param sql a SQL statement that may contain one or more '?' parameter
- * placeholders. Typically this statement is a JDBC function call
- * escape string.
- * @return a new CallableStatement object containing the pre-compiled
- * SQL statement
- * @exception SQLException if a database access error occurs
- */
- public java.sql.CallableStatement prepareCall(String sql) throws SQLException
- {
- throw new PSQLException("postgresql.con.call");
- // return new CallableStatement(this, sql);
- }
-
- /*
- * Tests to see if a Connection is closed
- *
- * @return the status of the connection
- * @exception SQLException (why?)
- */
- public boolean isClosed() throws SQLException
- {
- return (pg_stream == null);
- }
-
- /*
- * 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 made
- * available through a DatabaseMetaData object.
- *
- * @return a DatabaseMetaData object for this connection
- * @exception SQLException if a database access error occurs
- */
- public java.sql.DatabaseMetaData getMetaData() throws SQLException
- {
- if (metadata == null)
- metadata = new DatabaseMetaData(this);
- return metadata;
- }
-
- /*
- * This overides the method in org.postgresql.Connection and returns a
- * ResultSet.
- */
- public java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
- {
- // in jdbc1 stat is ignored.
- return new org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
- }
-
-
- /* An implementation of the abstract method in the parent class.
- * This implemetation uses the jdbc1Types array to support the jdbc1
- * datatypes. Basically jdbc1 and jdbc2 are the same, except that
- * jdbc2 adds the Array types.
- */
- public int getSQLType(String pgTypeName)
- {
- int sqlType = Types.OTHER; // default value
- for (int i = 0;i < jdbc1Types.length;i++)
- {
- if (pgTypeName.equals(jdbc1Types[i]))
- {
- sqlType = jdbc1Typei[i];
- break;
- }
- }
- return sqlType;
- }
-
- /*
- * This table holds the org.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 jdbc1Types[] = {
- "int2",
- "int4", "oid",
- "int8",
- "cash", "money",
- "numeric",
- "float4",
- "float8",
- "bpchar", "char", "char2", "char4", "char8", "char16",
- "varchar", "text", "name", "filename",
- "bytea",
- "bool",
- "date",
- "time",
- "abstime", "timestamp", "timestamptz"
- };
-
- /*
- * 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 jdbc1Typei[] = {
- Types.SMALLINT,
- Types.INTEGER, Types.INTEGER,
- Types.BIGINT,
- Types.DOUBLE, Types.DOUBLE,
- Types.NUMERIC,
- 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.BINARY,
- Types.BIT,
- Types.DATE,
- Types.TIME,
- Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP
- };
-
-
-}
-
-// ***********************************************************************
-
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
index 5fba1d68c00..747ee1f1ea4 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
@@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException;
/*
* This class provides information about the database as a whole.
*
- * $Id: DatabaseMetaData.java,v 1.47 2002/06/20 16:00:44 momjian Exp $
+ * $Id: DatabaseMetaData.java,v 1.48 2002/07/23 03:59:55 barry Exp $
*
* <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
@@ -37,7 +37,7 @@ import org.postgresql.util.PSQLException;
*/
public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
- Connection connection; // The connection association
+ Jdbc1Connection connection; // The connection association
// These define various OID's. Hopefully they will stay constant.
static final int iVarcharOid = 1043; // OID for varchar
@@ -46,7 +46,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
static final int iInt4Oid = 23; // OID for int4
static final int VARHDRSZ = 4; // length for int4
- public DatabaseMetaData(Connection conn)
+ public DatabaseMetaData(Jdbc1Connection conn)
{
this.connection = conn;
}
@@ -196,7 +196,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getDriverVersion() throws SQLException
{
- return connection.this_driver.getVersion();
+ return connection.getDriver().getVersion();
}
/*
@@ -206,7 +206,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public int getDriverMajorVersion()
{
- return connection.this_driver.getMajorVersion();
+ return connection.getDriver().getMajorVersion();
}
/*
@@ -216,7 +216,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public int getDriverMinorVersion()
{
- return connection.this_driver.getMinorVersion();
+ return connection.getDriver().getMinorVersion();
}
/*
@@ -1549,7 +1549,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
v.addElement(tuple);
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -1627,7 +1627,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
// add query loop here
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -1721,7 +1721,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
byte remarks[] = null;
- if (((org.postgresql.ResultSet)dr).getTupleCount() == 1)
+ if (((AbstractJdbc1ResultSet)dr).getTupleCount() == 1)
{
dr.next();
remarks = dr.getBytes(1);
@@ -1762,7 +1762,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
v.addElement(tuple);
}
r.close();
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
// This array contains the valid values for the types argument
@@ -1809,7 +1809,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[0] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32);
tuple[0] = "".getBytes();
v.addElement(tuple);
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -1854,7 +1854,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
tuple[0] = getTableTypes[i][0].getBytes();
v.addElement(tuple);
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2050,7 +2050,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
}
r.close();
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2113,7 +2113,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
//v.addElement(tuple);
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2203,7 +2203,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[6] = new Field(connection, "DECIMAL_DIGITS", iInt2Oid, 2);
f[7] = new Field(connection, "PSEUDO_COLUMN", iInt2Oid, 2);
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2413,7 +2413,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
while (hasMore);
}
- return new ResultSet(connection, f, tuples, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, tuples, "OK", 1);
}
/*
@@ -2692,7 +2692,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
v.addElement(tuple);
}
rs.close();
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
throw new PSQLException("postgresql.metadata.unavailable");
@@ -2832,7 +2832,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
}
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc1ResultSet(connection, f, v, "OK", 1);
}
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java
new file mode 100644
index 00000000000..55e527bd490
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java
@@ -0,0 +1,47 @@
+package org.postgresql.jdbc1;
+
+
+import java.util.Vector;
+import java.sql.*;
+import org.postgresql.Field;
+import org.postgresql.util.PSQLException;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class implements the java.sql.Connection interface for JDBC1.
+ * However most of the implementation is really done in
+ * org.postgresql.jdbc1.AbstractJdbc1Connection
+ */
+public class Jdbc1Connection extends org.postgresql.jdbc1.AbstractJdbc1Connection implements java.sql.Connection
+{
+
+ public java.sql.Statement createStatement() throws SQLException
+ {
+ return new org.postgresql.jdbc1.Jdbc1Statement(this);
+ }
+
+ public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
+ {
+ return new org.postgresql.jdbc1.PreparedStatement(this, sql);
+ }
+
+//BJL TODO - merge callable statement logic from jdbc2 to jdbc1
+ public java.sql.CallableStatement prepareCall(String sql) throws SQLException
+ {
+ throw new PSQLException("postgresql.con.call");
+ }
+
+ public java.sql.DatabaseMetaData getMetaData() throws SQLException
+ {
+ if (metadata == null)
+ metadata = new org.postgresql.jdbc1.DatabaseMetaData(this);
+ return metadata;
+ }
+
+ public java.sql.ResultSet getResultSet(java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
+ {
+ return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
+
+}
+
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java
new file mode 100644
index 00000000000..a959fef9d39
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java
@@ -0,0 +1,32 @@
+package org.postgresql.jdbc1;
+
+
+import java.sql.*;
+import java.util.Vector;
+import org.postgresql.Field;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1ResultSet.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class implements the java.sql.ResultSet interface for JDBC1.
+ * However most of the implementation is really done in
+ * org.postgresql.jdbc1.AbstractJdbc1ResultSet
+ */
+public class Jdbc1ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet implements java.sql.ResultSet
+{
+
+ public Jdbc1ResultSet(Jdbc1Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
+ {
+ super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
+
+ public Jdbc1ResultSet(Jdbc1Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
+ {
+ super(conn, fields, tuples, status, updateCount, 0, false);
+ }
+
+ public java.sql.ResultSetMetaData getMetaData() throws SQLException
+ {
+ return new ResultSetMetaData(rows, fields);
+ }
+
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
new file mode 100644
index 00000000000..bb073eae998
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
@@ -0,0 +1,19 @@
+package org.postgresql.jdbc1;
+
+
+import java.sql.*;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class implements the java.sql.Statement interface for JDBC1.
+ * However most of the implementation is really done in
+ * org.postgresql.jdbc1.AbstractJdbc1Statement
+ */
+public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement implements java.sql.Statement
+{
+
+ public Jdbc1Statement (Jdbc1Connection c)
+ {
+ connection = c;
+ }
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java
index 31926c500bd..9ef9a4289e5 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java
@@ -29,12 +29,12 @@ import org.postgresql.util.*;
* @see ResultSet
* @see java.sql.PreparedStatement
*/
-public class PreparedStatement extends Statement implements java.sql.PreparedStatement
+public class PreparedStatement extends Jdbc1Statement implements java.sql.PreparedStatement
{
String sql;
String[] templateStrings;
String[] inStrings;
- Connection connection;
+ Jdbc1Connection connection;
// Some performance caches
private StringBuffer sbuf = new StringBuffer();
@@ -49,7 +49,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
* @param sql the SQL statement with ? for IN markers
* @exception SQLException if something bad occurs
*/
- public PreparedStatement(Connection connection, String sql) throws SQLException
+ public PreparedStatement(Jdbc1Connection connection, String sql) throws SQLException
{
super(connection);
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java
deleted file mode 100644
index b6e054a3368..00000000000
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java
+++ /dev/null
@@ -1,1026 +0,0 @@
-package org.postgresql.jdbc1;
-
-// IMPORTANT NOTE: This file implements the JDBC 1 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 2 class in the
-// org.postgresql.jdbc2 package.
-
-import java.lang.*;
-import java.io.*;
-import java.math.*;
-import java.text.*;
-import java.util.*;
-import java.sql.*;
-import org.postgresql.Field;
-import org.postgresql.largeobject.*;
-import org.postgresql.util.*;
-import org.postgresql.core.Encoding;
-
-/*
- * 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.
- *
- * <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.
- *
- * <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.
- *
- * <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.
- *
- *<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.
- *
- * <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
- * SQL Query. For columns that are NOT explicitly named in the query, it is
- * best to use column numbers. If column names were used there is no way for
- * the programmer to guarentee that they actually refer to the intended
- * columns.
- *
- * <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.
- *
- * <P>The number, types and properties of a ResultSet's columns are provided by
- * the ResultSetMetaData object returned by the getMetaData method.
- *
- * @see ResultSetMetaData
- * @see java.sql.ResultSet
- */
-public class ResultSet extends org.postgresql.ResultSet implements java.sql.ResultSet
-{
- /*
- * Create a new ResultSet - Note that we create ResultSets to
- * represent the results of everything.
- *
- * @param fields an array of Field objects (basically, the
- * ResultSet MetaData)
- * @param tuples Vector of the actual data
- * @param status the status string returned from the back end
- * @param updateCount the number of rows affected by the operation
- * @param cursor the positioned update/delete cursor name
- */
- public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
- {
- super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
- }
-
- /*
- * Create a new ResultSet - Note that we create ResultSets to
- * represent the results of everything.
- *
- * @param fields an array of Field objects (basically, the
- * ResultSet MetaData)
- * @param tuples Vector of the actual data
- * @param status the status string returned from the back end
- * @param updateCount the number of rows affected by the operation
- * @param cursor the positioned update/delete cursor name
- */
- public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
- {
- super(conn, fields, tuples, status, updateCount, 0, false);
- }
-
- /*
- * A ResultSet is initially positioned before its first row,
- * the first call to next makes the first row the current row;
- * the second call makes the second row the current row, etc.
- *
- * <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
- *
- * @return true if the new current is valid; false if there are no
- * more rows
- * @exception SQLException if a database access error occurs
- */
- public boolean next() throws SQLException
- {
- if (rows == null)
- throw new PSQLException("postgresql.con.closed");
-
- if (++current_row >= rows.size())
- return false;
- this_row = (byte [][])rows.elementAt(current_row);
- return true;
- }
-
- /*
- * In some cases, it is desirable to immediately release a ResultSet
- * database and JDBC resources instead of waiting for this to happen
- * when it is automatically closed. The close method provides this
- * immediate release.
- *
- * <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
- * when it is garbage collected.
- *
- * @exception SQLException if a database access error occurs
- */
- public void close() throws SQLException
- {
- //release resources held (memory for tuples)
- rows.setSize(0);
- }
-
- /*
- * A column may have the value of SQL NULL; wasNull() reports whether
- * the last column read had this special value. Note that you must
- * first call getXXX on a column to try to read its value and then
- * call wasNull() to find if the value was SQL NULL
- *
- * @return true if the last column read was SQL NULL
- * @exception SQLException if a database access error occurred
- */
- public boolean wasNull() throws SQLException
- {
- return wasNullFlag;
- }
-
- /*
- * Get the value of a column in the current row as a Java String
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value, null for SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public String getString(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- Encoding encoding = connection.getEncoding();
- return encoding.decode(this_row[columnIndex - 1]);
- }
-
- /*
- * Get the value of a column in the current row as a Java boolean
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value, false for SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public boolean getBoolean(int columnIndex) throws SQLException
- {
- String s = getString(columnIndex);
-
- if (s != null)
- {
- int c = s.charAt(0);
- return ((c == 't') || (c == 'T') || (c == '1'));
- }
- return false; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java byte.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public byte getByte(int columnIndex) throws SQLException
- {
- String s = getString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Byte.parseByte(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.badbyte", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java short.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public short getShort(int columnIndex) throws SQLException
- {
- String s = getFixedString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Short.parseShort(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.badshort", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java int.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public int getInt(int columnIndex) throws SQLException
- {
- String s = getFixedString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Integer.parseInt(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badint", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java long.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public long getLong(int columnIndex) throws SQLException
- {
- String s = getFixedString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Long.parseLong(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badlong", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java float.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public float getFloat(int columnIndex) throws SQLException
- {
- String s = getFixedString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Float.valueOf(s).floatValue();
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badfloat", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java double.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public double getDouble(int columnIndex) throws SQLException
- {
- String s = getFixedString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Double.valueOf(s).doubleValue();
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.baddouble", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a
- * java.math.BigDecimal object
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @param scale the number of digits to the right of the decimal
- * @return the column value; if the value is SQL NULL, null
- * @exception SQLException if a database access error occurs
- */
- public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException
- {
- String s = getFixedString(columnIndex);
- BigDecimal val;
-
- if (s != null)
- {
- try
- {
- val = new BigDecimal(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badbigdec", s);
- }
- try
- {
- return val.setScale(scale);
- }
- catch (ArithmeticException e)
- {
- throw new PSQLException ("postgresql.res.badbigdec", s);
- }
- }
- return null; // SQL NULL
- }
-
- /*
- * 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
- * is null
- * @exception SQLException if a database access error occurs
- */
- public byte[] getBytes(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (!wasNullFlag)
- {
- if (binaryCursor)
- {
- //If the data is already binary then just return it
- return this_row[columnIndex - 1];
- }
- else if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports the bytea datatype for byte arrays
- if (fields[columnIndex - 1].getPGType().equals("bytea"))
- {
- return PGbytea.toBytes(this_row[columnIndex - 1]);
- }
- else
- {
- return this_row[columnIndex - 1];
- }
- }
- else
- {
- //Version 7.1 and earlier supports LargeObjects for byte arrays
- // Handle OID's as BLOBS
- 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;
- }
- else
- {
- return this_row[columnIndex - 1];
- }
- }
- }
- return null;
- }
-
- /*
- * Get the value of a column in the current row as a java.sql.Date
- * object
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value; null if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public java.sql.Date getDate(int columnIndex) throws SQLException
- {
- String s = getString(columnIndex);
- if (s == null)
- return null;
- // length == 10: SQL Date
- // length > 10: SQL Timestamp, assumes PGDATESTYLE=ISO
- try
- {
- return java.sql.Date.valueOf((s.length() == 10) ? s : s.substring(0, 10));
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.baddate", s);
- }
- }
-
- /*
- * Get the value of a column in the current row as a java.sql.Time
- * object
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value; null if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public Time getTime(int columnIndex) throws SQLException
- {
- String s = getString(columnIndex);
-
- if (s == null)
- return null; // SQL NULL
- try
- {
- if (s.length() == 8) {
- //value is a time value
- return java.sql.Time.valueOf(s);
- } else if (s.indexOf(".") == 8) {
- //value is a time value with fractional seconds
- java.sql.Time l_time = java.sql.Time.valueOf(s.substring(0,8));
- String l_strMillis = s.substring(9);
- if (l_strMillis.length() > 3)
- l_strMillis = l_strMillis.substring(0,3);
- int l_millis = Integer.parseInt(l_strMillis);
- if (l_millis < 10) {
- l_millis = l_millis * 100;
- } else if (l_millis < 100) {
- l_millis = l_millis * 10;
- }
- return new java.sql.Time(l_time.getTime() + l_millis);
- } else {
- //value is a timestamp
- return new java.sql.Time(getTimestamp(columnIndex).getTime());
- }
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.badtime", s);
- }
- }
-
- /*
- * Get the value of a column in the current row as a
- * java.sql.Timestamp object
- *
- * The driver is set to return ISO date formated strings. We modify this
- * string from the ISO format to a format that Java can understand. Java
- * expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
- * Java also expects fractional seconds to 3 places where postgres
- * will give, none, 2 or 6 depending on the time and postgres version.
- * From version 7.2 postgres returns fractional seconds to 6 places.
- * If available, we drop the last 3 digits.
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value; null if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public Timestamp getTimestamp(int columnIndex) throws SQLException
- {
- String s = getString(columnIndex);
-
- if (s == null)
- return null;
-
- StringBuffer sbuf = new StringBuffer(s);
- SimpleDateFormat df = null;
-
- int slen = s.length();
-
- if (slen > 19)
- {
- // The len of the ISO string to the second value is 19 chars. If
- // greater then 19, there should be tz info and perhaps fractional
- // second info which we need to change to java to read it.
-
- // cut the copy to second value "2001-12-07 16:29:22"
- int i = 19;
- sbuf.setLength(i);
-
- char c = s.charAt(i++);
- if (c == '.')
- {
- // Found a fractional value. Append up to 3 digits including
- // the leading '.'
- do
- {
- if (i < 24)
- sbuf.append(c);
- c = s.charAt(i++);
- } while (i < slen && Character.isDigit(c));
-
- // If there wasn't at least 3 digits we should add some zeros
- // to make up the 3 digits we tell java to expect.
- for (int j = i; j < 24; j++)
- sbuf.append('0');
- }
- else
- {
- // No fractional seconds, lets add some.
- sbuf.append(".000");
- }
-
- if (i < slen)
- {
- // prepend the GMT part and then add the remaining bit of
- // the string.
- sbuf.append(" GMT");
- sbuf.append(c);
- sbuf.append(s.substring(i, slen));
-
- // Lastly, if the tz part doesn't specify the :MM part then
- // we add ":00" for java.
- if (slen - i < 5)
- sbuf.append(":00");
-
- // we'll use this dateformat string to parse the result.
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
- }
- else
- {
- //if type is timestamptz then data is in GMT, else it is in local timezone
- if (fields[columnIndex - 1].getPGType().equals("timestamptz")) {
- sbuf.append(" GMT");
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
- } else {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
- }
- }
- }
- else if (slen == 19)
- {
- // No tz or fractional second info.
- // if type is timestamptz then data is in GMT, else it is in local timezone
- if (fields[columnIndex - 1].getPGType().equals("timestamptz")) {
- sbuf.append(" GMT");
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
- } else {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- }
- }
- else
- {
- // We must just have a date. This case is
- // needed if this method is called on a date column
- df = new SimpleDateFormat("yyyy-MM-dd");
- }
-
- try
- {
- // All that's left is to parse the string and return the ts.
- return new Timestamp(df.parse(sbuf.toString()).getTime());
- }
- catch (ParseException e)
- {
- throw new PSQLException("postgresql.res.badtimestamp", new Integer(e.getErrorOffset()), s);
- }
- }
-
- /*
- * A column value can be retrieved as a stream of ASCII characters
- * and then read in chunks from the stream. This method is
- * particular suitable for retrieving large LONGVARCHAR values.
- * The JDBC driver will do any necessary conversion from the
- * database format into ASCII.
- *
- * <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.
- *
- *<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.
- *
- * @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 one byte ASCII characters. If the
- * value is SQL NULL then the result is null
- * @exception SQLException if a database access error occurs
- * @see getBinaryStream
- */
- public InputStream getAsciiStream(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports AsciiStream for all the PG text types
- //As the spec/javadoc for this method indicate this is to be used for
- //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
- //long string datatype, but with toast the text datatype is capable of
- //handling very large values. Thus the implementation ends up calling
- //getString() since there is no current way to stream the value from the server
- try
- {
- return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII"));
- }
- catch (UnsupportedEncodingException l_uee)
- {
- throw new PSQLException("postgresql.unusual", l_uee);
- }
- }
- else
- {
- // In 7.1 Handle as BLOBS so return the LargeObject input stream
- return getBinaryStream(columnIndex);
- }
- }
-
- /*
- * A column value can also be retrieved as a stream of Unicode
- * characters. We implement this as a binary stream.
- *
- * @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
- * @exception SQLException if a database access error occurs
- * @see getAsciiStream
- * @see getBinaryStream
- */
- public InputStream getUnicodeStream(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports AsciiStream for all the PG text types
- //As the spec/javadoc for this method indicate this is to be used for
- //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
- //long string datatype, but with toast the text datatype is capable of
- //handling very large values. Thus the implementation ends up calling
- //getString() since there is no current way to stream the value from the server
- try
- {
- return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8"));
- }
- catch (UnsupportedEncodingException l_uee)
- {
- throw new PSQLException("postgresql.unusual", l_uee);
- }
- }
- else
- {
- // In 7.1 Handle as BLOBS so return the LargeObject input stream
- return getBinaryStream(columnIndex);
- }
- }
-
- /*
- * A column value can also be retrieved as a binary strea. This
- * method is suitable for retrieving LONGVARBINARY values.
- *
- * @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 bytes. If the value is SQL NULL, then the result
- * is null
- * @exception SQLException if a database access error occurs
- * @see getAsciiStream
- * @see getUnicodeStream
- */
- public InputStream getBinaryStream(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports BinaryStream for all PG bytea type
- //As the spec/javadoc for this method indicate this is to be used for
- //large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
- //long binary datatype, but with toast the bytea datatype is capable of
- //handling very large values. Thus the implementation ends up calling
- //getBytes() since there is no current way to stream the value from the server
- byte b[] = getBytes(columnIndex);
- if (b != null)
- return new ByteArrayInputStream(b);
- }
- else
- {
- // In 7.1 Handle as BLOBS so return the LargeObject input stream
- if ( fields[columnIndex - 1].getOID() == 26)
- {
- LargeObjectManager lom = connection.getLargeObjectAPI();
- LargeObject lob = lom.open(getInt(columnIndex));
- return lob.getInputStream();
- }
- }
- return null;
- }
-
- /*
- * The following routines simply convert the columnName into
- * a columnIndex and then call the appropriate routine above.
- *
- * @param columnName is the SQL name of the column
- * @return the column value
- * @exception SQLException if a database access error occurs
- */
- public String getString(String columnName) throws SQLException
- {
- return getString(findColumn(columnName));
- }
-
- public boolean getBoolean(String columnName) throws SQLException
- {
- return getBoolean(findColumn(columnName));
- }
-
- public byte getByte(String columnName) throws SQLException
- {
-
- return getByte(findColumn(columnName));
- }
-
- public short getShort(String columnName) throws SQLException
- {
- return getShort(findColumn(columnName));
- }
-
- public int getInt(String columnName) throws SQLException
- {
- return getInt(findColumn(columnName));
- }
-
- public long getLong(String columnName) throws SQLException
- {
- return getLong(findColumn(columnName));
- }
-
- public float getFloat(String columnName) throws SQLException
- {
- return getFloat(findColumn(columnName));
- }
-
- public double getDouble(String columnName) throws SQLException
- {
- return getDouble(findColumn(columnName));
- }
-
- public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException
- {
- return getBigDecimal(findColumn(columnName), scale);
- }
-
- public byte[] getBytes(String columnName) throws SQLException
- {
- return getBytes(findColumn(columnName));
- }
-
- public java.sql.Date getDate(String columnName) throws SQLException
- {
- return getDate(findColumn(columnName));
- }
-
- public Time getTime(String columnName) throws SQLException
- {
- return getTime(findColumn(columnName));
- }
-
- public Timestamp getTimestamp(String columnName) throws SQLException
- {
- return getTimestamp(findColumn(columnName));
- }
-
- public InputStream getAsciiStream(String columnName) throws SQLException
- {
- return getAsciiStream(findColumn(columnName));
- }
-
- public InputStream getUnicodeStream(String columnName) throws SQLException
- {
- return getUnicodeStream(findColumn(columnName));
- }
-
- public InputStream getBinaryStream(String columnName) throws SQLException
- {
- return getBinaryStream(findColumn(columnName));
- }
-
- /*
- * The first warning reported by calls on this ResultSet is
- * returned. Subsequent ResultSet warnings will be chained
- * to this SQLWarning.
- *
- * <p>The warning chain is automatically cleared each time a new
- * row is read.
- *
- * <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.
- *
- * @return the first SQLWarning or null;
- * @exception SQLException if a database access error occurs.
- */
- public SQLWarning getWarnings() throws SQLException
- {
- return warnings;
- }
-
- /*
- * After this call, getWarnings returns null until a new warning
- * is reported for this ResultSet
- *
- * @exception SQLException if a database access error occurs
- */
- public void clearWarnings() throws SQLException
- {
- warnings = null;
- }
-
- /*
- * Get the name of the SQL cursor used by this ResultSet
- *
- * <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.
- *
- * <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.
- *
- * <p><B>Note:</B> If positioned update is not supported, a SQLException
- * is thrown.
- *
- * @return the ResultSet's SQL cursor name.
- * @exception SQLException if a database access error occurs
- */
- public String getCursorName() throws SQLException
- {
- return connection.getCursorName();
- }
-
- /*
- * The numbers, types and properties of a ResultSet's columns are
- * provided by the getMetaData method
- *
- * @return a description of the ResultSet's columns
- * @exception SQLException if a database access error occurs
- */
- public java.sql.ResultSetMetaData getMetaData() throws SQLException
- {
- return new ResultSetMetaData(rows, fields);
- }
-
- /*
- * Get the value of a column in the current row as a Java object
- *
- * <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.
- *
- * <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...
- * @return a Object holding the column value
- * @exception SQLException if a database access error occurs
- */
- public Object getObject(int columnIndex) throws SQLException
- {
- Field field;
-
- if (columnIndex < 1 || columnIndex > fields.length)
- throw new PSQLException("postgresql.res.colrange");
- field = fields[columnIndex - 1];
-
- // some fields can be null, mainly from those returned by MetaData methods
- if (field == null)
- {
- wasNullFlag = true;
- return null;
- }
-
- switch (field.getSQLType())
- {
- case Types.BIT:
- return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE;
- case Types.SMALLINT:
- return new Short(getShort(columnIndex));
- case Types.INTEGER:
- return new Integer(getInt(columnIndex));
- case Types.BIGINT:
- return new Long(getLong(columnIndex));
- case Types.NUMERIC:
- return getBigDecimal(columnIndex, ((field.getMod() - 4) & 0xffff));
- case Types.REAL:
- return new Float(getFloat(columnIndex));
- case Types.DOUBLE:
- return new Double(getDouble(columnIndex));
- case Types.CHAR:
- case Types.VARCHAR:
- return getString(columnIndex);
- case Types.DATE:
- return getDate(columnIndex);
- case Types.TIME:
- return getTime(columnIndex);
- case Types.TIMESTAMP:
- return getTimestamp(columnIndex);
- case Types.BINARY:
- case Types.VARBINARY:
- return getBytes(columnIndex);
- default:
- String type = field.getPGType();
- // if the backend doesn't know the type then coerce to String
- if (type.equals("unknown"))
- {
- return getString(columnIndex);
- }
- else
- {
- return connection.getObject(field.getPGType(), getString(columnIndex));
- }
- }
- }
-
- /*
- * Get the value of a column in the current row as a Java object
- *
- *<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.
- *
- * <p>This method may also be used to read database specific abstract
- * data types.
- *
- * @param columnName is the SQL name of the column
- * @return a Object holding the column value
- * @exception SQLException if a database access error occurs
- */
- public Object getObject(String columnName) throws SQLException
- {
- return getObject(findColumn(columnName));
- }
-
- /*
- * Map a ResultSet column name to a ResultSet column index
- *
- * @param columnName the name of the column
- * @return the column index
- * @exception SQLException if a database access error occurs
- */
- public int findColumn(String columnName) throws SQLException
- {
- int i;
-
- for (i = 0 ; i < fields.length; ++i)
- if (fields[i].getName().equalsIgnoreCase(columnName))
- return (i + 1);
- throw new PSQLException ("postgresql.res.colname", columnName);
- }
-}
-
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java
deleted file mode 100644
index 8898f5a69dd..00000000000
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package org.postgresql.jdbc1;
-
-// IMPORTANT NOTE: This file implements the JDBC 1 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 2 class in the
-// org.postgresql.jdbc2 package.
-
-import java.sql.*;
-
-import org.postgresql.util.PSQLException;
-
-/*
- * A Statement object is used for executing a static SQL statement and
- * obtaining the results produced by it.
- *
- * <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
- * statement's current ResultSet if an open one exists.
- *
- * @see java.sql.Statement
- * @see ResultSet
- */
-public class Statement extends org.postgresql.Statement implements java.sql.Statement
-{
- private Connection connection; // The connection who created us
-
- /*
- * Constructor for a Statement. It simply sets the connection
- * that created us.
- *
- * @param c the Connection instantation that creates us
- */
- public Statement (Connection c)
- {
- connection = c;
- }
-
- /*
- * Execute a SQL statement that retruns a single ResultSet
- *
- * @param sql typically a static SQL SELECT statement
- * @return a ResulSet that contains the data produced by the query
- * @exception SQLException if a database access error occurs
- */
- public java.sql.ResultSet executeQuery(String sql) throws SQLException
- {
- this.execute(sql);
- while (result != null && !((org.postgresql.ResultSet)result).reallyResultSet())
- result = ((org.postgresql.ResultSet)result).getNext();
- if (result == null)
- throw new PSQLException("postgresql.stat.noresult");
- return result;
- }
-
- /*
- * Execute a SQL INSERT, UPDATE or DELETE statement. In addition
- * SQL statements that return nothing such as SQL DDL statements
- * can be executed
- *
- * @param sql a SQL statement
- * @return either a row count, or 0 for SQL commands
- * @exception SQLException if a database access error occurs
- */
- public int executeUpdate(String sql) throws SQLException
- {
- this.execute(sql);
- return this.getUpdateCount();
- }
-
- /*
- * setCursorName defines the SQL cursor name that will be used by
- * subsequent execute methods. This name can then be used in SQL
- * positioned update/delete statements to identify the current row
- * in the ResultSet generated by this statement. If a database
- * doesn't support positioned update/delete, this method is a
- * no-op.
- *
- * <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.
- *
- * <p>We throw an additional constriction. There can only be one
- * cursor active at any one time.
- *
- * @param name the new cursor name
- * @exception SQLException if a database access error occurs
- */
- public void setCursorName(String name) throws SQLException
- {
- connection.setCursorName(name);
- }
-
- /*
- * Execute a SQL statement that may return multiple results. We
- * don't have to worry about this since we do not support multiple
- * ResultSets. You can use getResultSet or getUpdateCount to
- * retrieve the result.
- *
- * @param sql any SQL statement
- * @return true if the next result is a ResulSet, false if it is
- * an update count or there are no more results
- * @exception SQLException if a database access error occurs
- */
- public boolean execute(String sql) throws SQLException
- {
- if (escapeProcessing)
- sql = escapeSQL(sql);
- result = connection.ExecSQL(sql);
- return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
- }
-
- /*
- * getUpdateCount returns the current result as an update count,
- * if the result is a ResultSet or there are no more results, -1
- * is returned. It should only be called once per result.
- *
- * @return the current result as an update count.
- * @exception SQLException if a database access error occurs
- */
- public int getUpdateCount() throws SQLException
- {
- if (result == null)
- return -1;
- if (((org.postgresql.ResultSet)result).reallyResultSet())
- return -1;
- return ((org.postgresql.ResultSet)result).getResultCount();
- }
-
- /*
- * getMoreResults moves to a Statement's next result. If it returns
- * true, this result is a ResulSet.
- *
- * @return true if the next ResultSet is valid
- * @exception SQLException if a database access error occurs
- */
- public boolean getMoreResults() throws SQLException
- {
- result = ((org.postgresql.ResultSet)result).getNext();
- return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
- }
-}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java
new file mode 100644
index 00000000000..8faefad65ff
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java
@@ -0,0 +1,203 @@
+package org.postgresql.jdbc2;
+
+
+import java.io.*;
+import java.net.ConnectException;
+import java.sql.*;
+import org.postgresql.util.PSQLException;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Connection.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class defines methods of the jdbc2 specification. This class extends
+ * org.postgresql.jdbc1.AbstractJdbc1Connection which provides the jdbc1
+ * methods. The real Connection class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Connection
+ */
+public abstract class AbstractJdbc2Connection extends org.postgresql.jdbc1.AbstractJdbc1Connection
+{
+ /*
+ * The current type mappings
+ */
+ protected java.util.Map typemap;
+
+ public java.sql.Statement createStatement() throws SQLException
+ {
+ // The spec says default of TYPE_FORWARD_ONLY but everyone is used to
+ // using TYPE_SCROLL_INSENSITIVE
+ return createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
+ }
+
+ public abstract java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException;
+
+ public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
+ {
+ return prepareStatement(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
+ }
+
+ public abstract java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException;
+
+ public java.sql.CallableStatement prepareCall(String sql) throws SQLException
+ {
+ return prepareCall(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
+ }
+
+ public abstract java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException;
+
+ public java.util.Map getTypeMap() throws SQLException
+ {
+ return typemap;
+ }
+
+
+ public void setTypeMap(java.util.Map map) throws SQLException
+ {
+ typemap = map;
+ }
+
+ public void cancelQuery() throws SQLException
+ {
+ org.postgresql.PG_Stream cancelStream = null;
+ try {
+ cancelStream = new org.postgresql.PG_Stream(PG_HOST, PG_PORT);
+ } catch (ConnectException cex) {
+ // Added by Peter Mount <peter@retep.org.uk>
+ // ConnectException is thrown when the connection cannot be made.
+ // we trap this an return a more meaningful message for the end user
+ throw new PSQLException ("postgresql.con.refused");
+ } catch (IOException e) {
+ throw new PSQLException ("postgresql.con.failed",e);
+ }
+
+ // Now we need to construct and send a cancel packet
+ try {
+ cancelStream.SendInteger(16, 4);
+ cancelStream.SendInteger(80877102, 4);
+ cancelStream.SendInteger(pid, 4);
+ cancelStream.SendInteger(ckey, 4);
+ cancelStream.flush();
+ }
+ catch(IOException e) {
+ throw new PSQLException("postgresql.con.failed",e);
+ }
+ finally {
+ try {
+ if(cancelStream != null)
+ cancelStream.close();
+ }
+ catch(IOException e) {} // Ignore
+ }
+ }
+
+
+ /*
+ * This overides the standard internal getObject method so that we can
+ * check the jdbc2 type map first
+ */
+ public Object getObject(String type, String value) throws SQLException
+ {
+ if (typemap != null)
+ {
+ SQLData d = (SQLData) typemap.get(type);
+ if (d != null)
+ {
+ // Handle the type (requires SQLInput & SQLOutput classes to be implemented)
+ throw org.postgresql.Driver.notImplemented();
+ }
+ }
+
+ // Default to the original method
+ return super.getObject(type, value);
+ }
+
+
+ //Because the get/setLogStream methods are deprecated in JDBC2
+ //we use the get/setLogWriter methods here for JDBC2 by overriding
+ //the base version of this method
+ protected void enableDriverManagerLogging() {
+ if (DriverManager.getLogWriter() == null) {
+ DriverManager.setLogWriter(new PrintWriter(System.out));
+ }
+ }
+
+
+ /*
+ * This implemetation uses the jdbc2Types array to support the jdbc2
+ * datatypes. Basically jdbc1 and jdbc2 are the same, except that
+ * jdbc2 adds the Array types.
+ */
+ public int getSQLType(String pgTypeName)
+ {
+ int sqlType = Types.OTHER; // default value
+ for (int i = 0;i < jdbc2Types.length;i++)
+ {
+ if (pgTypeName.equals(jdbc2Types[i]))
+ {
+ sqlType = jdbc2Typei[i];
+ break;
+ }
+ }
+ return sqlType;
+ }
+
+ /*
+ * This table holds the org.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 jdbc2Types[] = {
+ "int2",
+ "int4", "oid",
+ "int8",
+ "cash", "money",
+ "numeric",
+ "float4",
+ "float8",
+ "bpchar", "char", "char2", "char4", "char8", "char16",
+ "varchar", "text", "name", "filename",
+ "bytea",
+ "bool",
+ "date",
+ "time",
+ "abstime", "timestamp", "timestamptz",
+ "_bool", "_char", "_int2", "_int4", "_text",
+ "_oid", "_varchar", "_int8", "_float4", "_float8",
+ "_abstime", "_date", "_time", "_timestamp", "_numeric",
+ "_bytea"
+ };
+
+ /*
+ * 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 jdbc2Typei[] = {
+ Types.SMALLINT,
+ Types.INTEGER, Types.INTEGER,
+ Types.BIGINT,
+ Types.DOUBLE, Types.DOUBLE,
+ Types.NUMERIC,
+ 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.BINARY,
+ Types.BIT,
+ Types.DATE,
+ Types.TIME,
+ Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP,
+ Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
+ Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
+ Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
+ Types.ARRAY
+ };
+
+
+
+
+}
+
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
new file mode 100644
index 00000000000..50c5d942bbf
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
@@ -0,0 +1,752 @@
+package org.postgresql.jdbc2;
+
+
+import java.math.BigDecimal;
+import java.io.*;
+import java.sql.*;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Vector;
+import org.postgresql.Field;
+import org.postgresql.core.Encoding;
+import org.postgresql.largeobject.*;
+import org.postgresql.util.PGbytea;
+import org.postgresql.util.PSQLException;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class defines methods of the jdbc2 specification. This class extends
+ * org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1
+ * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet
+ */
+public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet
+{
+ protected Jdbc2Statement statement;
+
+ protected String sqlQuery=null;
+
+ public AbstractJdbc2ResultSet(org.postgresql.PGConnection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
+ {
+ super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
+
+ public java.net.URL getURL(int columnIndex) throws SQLException
+ {
+ return null;
+ }
+
+ public java.net.URL getURL(String columnName) throws SQLException
+ {
+ return null;
+ }
+
+ /*
+ * Get the value of a column in the current row as a Java object
+ *
+ * <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.
+ *
+ * <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...
+ * @return a Object holding the column value
+ * @exception SQLException if a database access error occurs
+ */
+ public Object getObject(int columnIndex) throws SQLException
+ {
+ Field field;
+
+ checkResultSet( columnIndex );
+
+ wasNullFlag = (this_row[columnIndex - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ field = fields[columnIndex - 1];
+
+ // some fields can be null, mainly from those returned by MetaData methods
+ if (field == null)
+ {
+ wasNullFlag = true;
+ return null;
+ }
+
+ switch (field.getSQLType())
+ {
+ case Types.BIT:
+ return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE;
+ case Types.SMALLINT:
+ return new Short(getShort(columnIndex));
+ case Types.INTEGER:
+ return new Integer(getInt(columnIndex));
+ case Types.BIGINT:
+ return new Long(getLong(columnIndex));
+ case Types.NUMERIC:
+ return getBigDecimal
+ (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff));
+ case Types.REAL:
+ return new Float(getFloat(columnIndex));
+ case Types.DOUBLE:
+ return new Double(getDouble(columnIndex));
+ case Types.CHAR:
+ case Types.VARCHAR:
+ return getString(columnIndex);
+ case Types.DATE:
+ return getDate(columnIndex);
+ case Types.TIME:
+ return getTime(columnIndex);
+ case Types.TIMESTAMP:
+ return getTimestamp(columnIndex);
+ case Types.BINARY:
+ case Types.VARBINARY:
+ return getBytes(columnIndex);
+ case Types.ARRAY:
+ return getArray(columnIndex);
+ default:
+ String type = field.getPGType();
+ // if the backend doesn't know the type then coerce to String
+ if (type.equals("unknown"))
+ {
+ return getString(columnIndex);
+ }
+ else
+ {
+ return connection.getObject(field.getPGType(), getString(columnIndex));
+ }
+ }
+ }
+
+ public boolean absolute(int index) throws SQLException
+ {
+ // index is 1-based, but internally we use 0-based indices
+ int internalIndex;
+
+ if (index == 0)
+ throw new SQLException("Cannot move to index of 0");
+
+ final int rows_size = rows.size();
+
+ //if index<0, count from the end of the result set, but check
+ //to be sure that it is not beyond the first index
+ if (index < 0)
+ {
+ if (index >= -rows_size)
+ internalIndex = rows_size + index;
+ else
+ {
+ beforeFirst();
+ return false;
+ }
+ }
+ else
+ {
+ //must be the case that index>0,
+ //find the correct place, assuming that
+ //the index is not too large
+ if (index <= rows_size)
+ internalIndex = index - 1;
+ else
+ {
+ afterLast();
+ return false;
+ }
+ }
+
+ current_row = internalIndex;
+ this_row = (byte [][])rows.elementAt(internalIndex);
+ return true;
+ }
+
+ public void afterLast() throws SQLException
+ {
+ final int rows_size = rows.size();
+ if (rows_size > 0)
+ current_row = rows_size;
+ }
+
+ public void beforeFirst() throws SQLException
+ {
+ if (rows.size() > 0)
+ current_row = -1;
+ }
+
+ public void cancelRowUpdates() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void deleteRow() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public boolean first() throws SQLException
+ {
+ if (rows.size() <= 0)
+ return false;
+
+ current_row = 0;
+ this_row = (byte [][])rows.elementAt(current_row);
+
+ rowBuffer=new byte[this_row.length][];
+ System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
+
+ return true;
+ }
+
+ public java.sql.Array getArray(String colName) throws SQLException
+ {
+ return getArray(findColumn(colName));
+ }
+
+ public java.sql.Array getArray(int i) throws SQLException
+ {
+ wasNullFlag = (this_row[i - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ if (i < 1 || i > fields.length)
+ throw new PSQLException("postgresql.res.colrange");
+ return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i - 1], (java.sql.ResultSet)this );
+ }
+
+ public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException
+ {
+ return getBigDecimal(columnIndex, -1);
+ }
+
+ public java.math.BigDecimal getBigDecimal(String columnName) throws SQLException
+ {
+ return getBigDecimal(findColumn(columnName));
+ }
+
+ public Blob getBlob(String columnName) throws SQLException
+ {
+ return getBlob(findColumn(columnName));
+ }
+
+ public Blob getBlob(int i) throws SQLException
+ {
+ return new org.postgresql.largeobject.PGblob(connection, getInt(i));
+ }
+
+ public java.io.Reader getCharacterStream(String columnName) throws SQLException
+ {
+ return getCharacterStream(findColumn(columnName));
+ }
+
+ public java.io.Reader getCharacterStream(int i) throws SQLException
+ {
+ checkResultSet( i );
+ wasNullFlag = (this_row[i - 1] == null);
+ if (wasNullFlag)
+ return null;
+
+ if (((AbstractJdbc2Connection)connection).haveMinimumCompatibleVersion("7.2"))
+ {
+ //Version 7.2 supports AsciiStream for all the PG text types
+ //As the spec/javadoc for this method indicate this is to be used for
+ //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
+ //long string datatype, but with toast the text datatype is capable of
+ //handling very large values. Thus the implementation ends up calling
+ //getString() since there is no current way to stream the value from the server
+ return new CharArrayReader(getString(i).toCharArray());
+ }
+ else
+ {
+ // In 7.1 Handle as BLOBS so return the LargeObject input stream
+ Encoding encoding = connection.getEncoding();
+ InputStream input = getBinaryStream(i);
+ return encoding.getDecodingReader(input);
+ }
+ }
+
+ public Clob getClob(String columnName) throws SQLException
+ {
+ return getClob(findColumn(columnName));
+ }
+
+ public Clob getClob(int i) throws SQLException
+ {
+ return new org.postgresql.largeobject.PGclob(connection, getInt(i));
+ }
+
+ public int getConcurrency() throws SQLException
+ {
+ // The standard ResultSet class will now return
+ // CONCUR_READ_ONLY. A sub-class will overide this if the query was
+ // updateable.
+ return java.sql.ResultSet.CONCUR_READ_ONLY;
+ }
+
+ public java.sql.Date getDate(int i, java.util.Calendar cal) throws SQLException
+ {
+ // If I read the specs, this should use cal only if we don't
+ // store the timezone, and if we do, then act just like getDate()?
+ // for now...
+ return getDate(i);
+ }
+
+ public Time getTime(int i, java.util.Calendar cal) throws SQLException
+ {
+ // If I read the specs, this should use cal only if we don't
+ // store the timezone, and if we do, then act just like getTime()?
+ // for now...
+ return getTime(i);
+ }
+
+ public Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException
+ {
+ // If I read the specs, this should use cal only if we don't
+ // store the timezone, and if we do, then act just like getDate()?
+ // for now...
+ return getTimestamp(i);
+ }
+
+ public java.sql.Date getDate(String c, java.util.Calendar cal) throws SQLException
+ {
+ return getDate(findColumn(c), cal);
+ }
+
+ public Time getTime(String c, java.util.Calendar cal) throws SQLException
+ {
+ return getTime(findColumn(c), cal);
+ }
+
+ public Timestamp getTimestamp(String c, java.util.Calendar cal) throws SQLException
+ {
+ return getTimestamp(findColumn(c), cal);
+ }
+
+ public int getFetchDirection() throws SQLException
+ {
+ //PostgreSQL normally sends rows first->last
+ return java.sql.ResultSet.FETCH_FORWARD;
+ }
+
+ public int getFetchSize() throws SQLException
+ {
+ // In this implementation we return the entire result set, so
+ // here return the number of rows we have. Sub-classes can return a proper
+ // value
+ return rows.size();
+ }
+
+ public Object getObject(String columnName, java.util.Map map) throws SQLException
+ {
+ return getObject(findColumn(columnName), map);
+ }
+
+ /*
+ * This checks against map for the type of column i, and if found returns
+ * an object based on that mapping. The class must implement the SQLData
+ * interface.
+ */
+ public Object getObject(int i, java.util.Map map) throws SQLException
+ {
+ throw org.postgresql.Driver.notImplemented();
+ }
+
+ public Ref getRef(String columnName) throws SQLException
+ {
+ return getRef(findColumn(columnName));
+ }
+
+ public Ref getRef(int i) throws SQLException
+ {
+ //The backend doesn't yet have SQL3 REF types
+ throw new PSQLException("postgresql.psqlnotimp");
+ }
+
+ public int getRow() throws SQLException
+ {
+ final int rows_size = rows.size();
+
+ if (current_row < 0 || current_row >= rows_size)
+ return 0;
+
+ return current_row + 1;
+ }
+
+ // This one needs some thought, as not all ResultSets come from a statement
+ public java.sql.Statement getStatement() throws SQLException
+ {
+ return statement;
+ }
+
+ public int getType() throws SQLException
+ {
+ // This implementation allows scrolling but is not able to
+ // see any changes. Sub-classes may overide this to return a more
+ // meaningful result.
+ return java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
+ }
+
+ public void insertRow() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public boolean isAfterLast() throws SQLException
+ {
+ final int rows_size = rows.size();
+ return (current_row >= rows_size && rows_size > 0);
+ }
+
+ public boolean isBeforeFirst() throws SQLException
+ {
+ return (current_row < 0 && rows.size() > 0);
+ }
+
+ public boolean isFirst() throws SQLException
+ {
+ return (current_row == 0 && rows.size() >= 0);
+ }
+
+ public boolean isLast() throws SQLException
+ {
+ final int rows_size = rows.size();
+ return (current_row == rows_size - 1 && rows_size > 0);
+ }
+
+ public boolean last() throws SQLException
+ {
+ final int rows_size = rows.size();
+ if (rows_size <= 0)
+ return false;
+
+ current_row = rows_size - 1;
+ this_row = (byte [][])rows.elementAt(current_row);
+
+ rowBuffer=new byte[this_row.length][];
+ System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
+
+ return true;
+ }
+
+ public void moveToCurrentRow() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void moveToInsertRow() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public boolean previous() throws SQLException
+ {
+ if (--current_row < 0)
+ return false;
+ this_row = (byte [][])rows.elementAt(current_row);
+ System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
+ return true;
+ }
+
+ public void refreshRow() throws SQLException
+ {
+ throw new PSQLException("postgresql.notsensitive");
+ }
+
+ public boolean relative(int rows) throws SQLException
+ {
+ //have to add 1 since absolute expects a 1-based index
+ return absolute(current_row + 1 + rows);
+ }
+
+ public boolean rowDeleted() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ return false; // javac complains about not returning a value!
+ }
+
+ public boolean rowInserted() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ return false; // javac complains about not returning a value!
+ }
+
+ public boolean rowUpdated() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ return false; // javac complains about not returning a value!
+ }
+
+ public void setFetchDirection(int direction) throws SQLException
+ {
+ throw new PSQLException("postgresql.psqlnotimp");
+ }
+
+ public void setFetchSize(int rows) throws SQLException
+ {
+ // Sub-classes should implement this as part of their cursor support
+ throw org.postgresql.Driver.notImplemented();
+ }
+
+ public void updateAsciiStream(int columnIndex,
+ java.io.InputStream x,
+ int length
+ ) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateAsciiStream(String columnName,
+ java.io.InputStream x,
+ int length
+ ) throws SQLException
+ {
+ updateAsciiStream(findColumn(columnName), x, length);
+ }
+
+ public void updateBigDecimal(int columnIndex,
+ java.math.BigDecimal x
+ ) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateBigDecimal(String columnName,
+ java.math.BigDecimal x
+ ) throws SQLException
+ {
+ updateBigDecimal(findColumn(columnName), x);
+ }
+
+ public void updateBinaryStream(int columnIndex,
+ java.io.InputStream x,
+ int length
+ ) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateBinaryStream(String columnName,
+ java.io.InputStream x,
+ int length
+ ) throws SQLException
+ {
+ updateBinaryStream(findColumn(columnName), x, length);
+ }
+
+ public void updateBoolean(int columnIndex, boolean x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateBoolean(String columnName, boolean x) throws SQLException
+ {
+ updateBoolean(findColumn(columnName), x);
+ }
+
+ public void updateByte(int columnIndex, byte x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateByte(String columnName, byte x) throws SQLException
+ {
+ updateByte(findColumn(columnName), x);
+ }
+
+ public void updateBytes(String columnName, byte[] x) throws SQLException
+ {
+ updateBytes(findColumn(columnName), x);
+ }
+
+ public void updateBytes(int columnIndex, byte[] x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateCharacterStream(int columnIndex,
+ java.io.Reader x,
+ int length
+ ) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateCharacterStream(String columnName,
+ java.io.Reader x,
+ int length
+ ) throws SQLException
+ {
+ updateCharacterStream(findColumn(columnName), x, length);
+ }
+
+ public void updateDate(int columnIndex, java.sql.Date x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateDate(String columnName, java.sql.Date x) throws SQLException
+ {
+ updateDate(findColumn(columnName), x);
+ }
+
+ public void updateDouble(int columnIndex, double x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateDouble(String columnName, double x) throws SQLException
+ {
+ updateDouble(findColumn(columnName), x);
+ }
+
+ public void updateFloat(int columnIndex, float x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateFloat(String columnName, float x) throws SQLException
+ {
+ updateFloat(findColumn(columnName), x);
+ }
+
+ public void updateInt(int columnIndex, int x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateInt(String columnName, int x) throws SQLException
+ {
+ updateInt(findColumn(columnName), x);
+ }
+
+ public void updateLong(int columnIndex, long x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateLong(String columnName, long x) throws SQLException
+ {
+ updateLong(findColumn(columnName), x);
+ }
+
+ public void updateNull(int columnIndex) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateNull(String columnName) throws SQLException
+ {
+ updateNull(findColumn(columnName));
+ }
+
+ public void updateObject(int columnIndex, Object x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateObject(String columnName, Object x) throws SQLException
+ {
+ updateObject(findColumn(columnName), x);
+ }
+
+ public void updateObject(int columnIndex, Object x, int scale) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateObject(String columnName, Object x, int scale) throws SQLException
+ {
+ updateObject(findColumn(columnName), x, scale);
+ }
+
+ public void updateRow() throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateShort(int columnIndex, short x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateShort(String columnName, short x) throws SQLException
+ {
+ updateShort(findColumn(columnName), x);
+ }
+
+ public void updateString(int columnIndex, String x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateString(String columnName, String x) throws SQLException
+ {
+ updateString(findColumn(columnName), x);
+ }
+
+ public void updateTime(int columnIndex, Time x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateTime(String columnName, Time x) throws SQLException
+ {
+ updateTime(findColumn(columnName), x);
+ }
+
+ public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException
+ {
+ // only sub-classes implement CONCUR_UPDATEABLE
+ notUpdateable();
+ }
+
+ public void updateTimestamp(String columnName, Timestamp x) throws SQLException
+ {
+ updateTimestamp(findColumn(columnName), x);
+ }
+
+ // helper method. Throws an SQLException when an update is not possible
+ public void notUpdateable() throws SQLException
+ {
+ throw new PSQLException("postgresql.noupdate");
+ }
+
+ /*
+ * It's used currently by getStatement() but may also with the new core
+ * package.
+ */
+ public void setStatement(Jdbc2Statement statement)
+ {
+ this.statement = statement;
+ }
+
+ public void setSQLQuery(String sqlQuery) {
+ this.sqlQuery=sqlQuery;
+ }
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
new file mode 100644
index 00000000000..3d6f6553ced
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
@@ -0,0 +1,142 @@
+package org.postgresql.jdbc2;
+
+
+import java.sql.*;
+import java.util.Vector;
+import org.postgresql.util.PSQLException;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class defines methods of the jdbc2 specification. This class extends
+ * org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1
+ * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement
+ */
+public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement
+{
+
+ protected Vector batch = null;
+ protected int resultsettype; // the resultset type to return
+ protected int concurrency; // is it updateable or not?
+
+ /*
+ * Execute a SQL statement that may return multiple results. We
+ * don't have to worry about this since we do not support multiple
+ * ResultSets. You can use getResultSet or getUpdateCount to
+ * retrieve the result.
+ *
+ * @param sql any SQL statement
+ * @return true if the next result is a ResulSet, false if it is
+ * an update count or there are no more results
+ * @exception SQLException if a database access error occurs
+ */
+ public boolean execute(String sql) throws SQLException
+ {
+ boolean l_return = super.execute(sql);
+
+ //Now do the jdbc2 specific stuff
+ //required for ResultSet.getStatement() to work
+ ((AbstractJdbc2ResultSet)result).setStatement((Jdbc2Statement)this);
+
+ // Added this so that the Updateable resultset knows the query that gave this
+ ((AbstractJdbc2ResultSet)result).setSQLQuery(sql);
+
+ return l_return;
+ }
+
+ // ** JDBC 2 Extensions **
+
+ public void addBatch(String sql) throws SQLException
+ {
+ if (batch == null)
+ batch = new Vector();
+ batch.addElement(sql);
+ }
+
+ public void clearBatch() throws SQLException
+ {
+ if (batch != null)
+ batch.removeAllElements();
+ }
+
+ public int[] executeBatch() throws SQLException
+ {
+ if (batch == null)
+ batch = new Vector();
+ int size = batch.size();
+ int[] result = new int[size];
+ int i = 0;
+ try
+ {
+ for (i = 0;i < size;i++)
+ result[i] = this.executeUpdate((String)batch.elementAt(i));
+ }
+ catch (SQLException e)
+ {
+ int[] resultSucceeded = new int[i];
+ System.arraycopy(result, 0, resultSucceeded, 0, i);
+
+ PBatchUpdateException updex =
+ new PBatchUpdateException("postgresql.stat.batch.error",
+ new Integer(i), batch.elementAt(i), resultSucceeded);
+ updex.setNextException(e);
+
+ throw updex;
+ }
+ finally
+ {
+ batch.removeAllElements();
+ }
+ return result;
+ }
+
+ public void cancel() throws SQLException
+ {
+ ((AbstractJdbc2Connection)connection).cancelQuery();
+ }
+
+ public java.sql.Connection getConnection() throws SQLException
+ {
+ return (java.sql.Connection)connection;
+ }
+
+ public int getFetchDirection() throws SQLException
+ {
+ throw new PSQLException("postgresql.psqlnotimp");
+ }
+
+ public int getFetchSize() throws SQLException
+ {
+ // This one can only return a valid value when were a cursor?
+ throw org.postgresql.Driver.notImplemented();
+ }
+
+ public int getResultSetConcurrency() throws SQLException
+ {
+ return concurrency;
+ }
+
+ public int getResultSetType() throws SQLException
+ {
+ return resultsettype;
+ }
+
+ public void setFetchDirection(int direction) throws SQLException
+ {
+ throw org.postgresql.Driver.notImplemented();
+ }
+
+ public void setFetchSize(int rows) throws SQLException
+ {
+ throw org.postgresql.Driver.notImplemented();
+ }
+
+ public void setResultSetConcurrency(int value) throws SQLException
+ {
+ concurrency = value;
+ }
+
+ public void setResultSetType(int value) throws SQLException
+ {
+ resultsettype = value;
+ }
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
index 7cc842ec36e..2105802d66a 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
@@ -25,9 +25,9 @@ import org.postgresql.util.*;
public class Array implements java.sql.Array
{
- private org.postgresql.Connection conn = null;
+ private org.postgresql.PGConnection conn = null;
private org.postgresql.Field field = null;
- private org.postgresql.jdbc2.ResultSet rs = null;
+ private ResultSet rs;
private int idx = 0;
private String rawString = null;
@@ -39,14 +39,14 @@ public class Array implements java.sql.Array
* @param field the Field descriptor for the field to load into this Array
* @param rs the ResultSet from which to get the data for this Array
*/
- public Array( org.postgresql.Connection conn, int idx, Field field, org.postgresql.jdbc2.ResultSet rs )
+ public Array( org.postgresql.PGConnection conn, int idx, Field field, ResultSet rs )
throws SQLException
{
this.conn = conn;
this.field = field;
- this.rs = rs;
+ this.rs = rs;
this.idx = idx;
- this.rawString = rs.getFixedString(idx);
+ this.rawString = ((AbstractJdbc2ResultSet)rs).getFixedString(idx);
}
public Object getArray() throws SQLException
@@ -124,33 +124,33 @@ public class Array implements java.sql.Array
case Types.BIT:
retVal = new boolean[ count ];
for ( ; count > 0; count-- )
- ((boolean[])retVal)[i++] = ResultSet.toBoolean( arrayContents[(int)index++] );
+ ((boolean[])retVal)[i++] = Jdbc2ResultSet.toBoolean( arrayContents[(int)index++] );
break;
case Types.SMALLINT:
case Types.INTEGER:
retVal = new int[ count ];
for ( ; count > 0; count-- )
- ((int[])retVal)[i++] = ResultSet.toInt( arrayContents[(int)index++] );
+ ((int[])retVal)[i++] = Jdbc2ResultSet.toInt( arrayContents[(int)index++] );
break;
case Types.BIGINT:
retVal = new long[ count ];
for ( ; count > 0; count-- )
- ((long[])retVal)[i++] = ResultSet.toLong( arrayContents[(int)index++] );
+ ((long[])retVal)[i++] = Jdbc2ResultSet.toLong( arrayContents[(int)index++] );
break;
case Types.NUMERIC:
retVal = new BigDecimal[ count ];
for ( ; count > 0; count-- )
- ((BigDecimal[])retVal)[i++] = ResultSet.toBigDecimal( arrayContents[(int)index++], 0 );
+ ((BigDecimal[])retVal)[i++] = Jdbc2ResultSet.toBigDecimal( arrayContents[(int)index++], 0 );
break;
case Types.REAL:
retVal = new float[ count ];
for ( ; count > 0; count-- )
- ((float[])retVal)[i++] = ResultSet.toFloat( arrayContents[(int)index++] );
+ ((float[])retVal)[i++] = Jdbc2ResultSet.toFloat( arrayContents[(int)index++] );
break;
case Types.DOUBLE:
retVal = new double[ count ];
for ( ; count > 0; count-- )
- ((double[])retVal)[i++] = ResultSet.toDouble( arrayContents[(int)index++] );
+ ((double[])retVal)[i++] = Jdbc2ResultSet.toDouble( arrayContents[(int)index++] );
break;
case Types.CHAR:
case Types.VARCHAR:
@@ -161,18 +161,18 @@ public class Array implements java.sql.Array
case Types.DATE:
retVal = new java.sql.Date[ count ];
for ( ; count > 0; count-- )
- ((java.sql.Date[])retVal)[i++] = ResultSet.toDate( arrayContents[(int)index++] );
+ ((java.sql.Date[])retVal)[i++] = Jdbc2ResultSet.toDate( arrayContents[(int)index++] );
break;
case Types.TIME:
retVal = new java.sql.Time[ count ];
for ( ; count > 0; count-- )
- ((java.sql.Time[])retVal)[i++] = ResultSet.toTime( arrayContents[(int)index++], rs, getBaseTypeName() );
+ ((java.sql.Time[])retVal)[i++] = Jdbc2ResultSet.toTime( arrayContents[(int)index++], rs, getBaseTypeName() );
break;
case Types.TIMESTAMP:
retVal = new Timestamp[ count ];
StringBuffer sbuf = null;
for ( ; count > 0; count-- )
- ((java.sql.Timestamp[])retVal)[i++] = ResultSet.toTimestamp( arrayContents[(int)index++], rs, getBaseTypeName() );
+ ((java.sql.Timestamp[])retVal)[i++] = Jdbc2ResultSet.toTimestamp( arrayContents[(int)index++], rs, getBaseTypeName() );
break;
// Other datatypes not currently supported. If you are really using other types ask
@@ -216,12 +216,12 @@ public class Array implements java.sql.Array
Object array = getArray( index, count, map );
Vector rows = new Vector();
Field[] fields = new Field[2];
- fields[0] = new Field(conn, "INDEX", conn.getOID("int2"), 2);
+ fields[0] = new Field(conn, "INDEX", conn.getPGType("int2"), 2);
switch ( getBaseType() )
{
case Types.BIT:
boolean[] booleanArray = (boolean[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("bool"), 1);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("bool"), 1);
for ( int i = 0; i < booleanArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -230,11 +230,11 @@ public class Array implements java.sql.Array
rows.addElement(tuple);
}
case Types.SMALLINT:
- fields[1] = new Field(conn, "VALUE", conn.getOID("int2"), 2);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("int2"), 2);
case Types.INTEGER:
int[] intArray = (int[]) array;
if ( fields[1] == null )
- fields[1] = new Field(conn, "VALUE", conn.getOID("int4"), 4);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("int4"), 4);
for ( int i = 0; i < intArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -245,7 +245,7 @@ public class Array implements java.sql.Array
break;
case Types.BIGINT:
long[] longArray = (long[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("int8"), 8);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("int8"), 8);
for ( int i = 0; i < longArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -256,7 +256,7 @@ public class Array implements java.sql.Array
break;
case Types.NUMERIC:
BigDecimal[] bdArray = (BigDecimal[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("numeric"), -1);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("numeric"), -1);
for ( int i = 0; i < bdArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -267,7 +267,7 @@ public class Array implements java.sql.Array
break;
case Types.REAL:
float[] floatArray = (float[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("float4"), 4);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("float4"), 4);
for ( int i = 0; i < floatArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -278,7 +278,7 @@ public class Array implements java.sql.Array
break;
case Types.DOUBLE:
double[] doubleArray = (double[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("float8"), 8);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("float8"), 8);
for ( int i = 0; i < doubleArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -288,11 +288,11 @@ public class Array implements java.sql.Array
}
break;
case Types.CHAR:
- fields[1] = new Field(conn, "VALUE", conn.getOID("char"), 1);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("char"), 1);
case Types.VARCHAR:
String[] strArray = (String[]) array;
if ( fields[1] == null )
- fields[1] = new Field(conn, "VALUE", conn.getOID("varchar"), -1);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("varchar"), -1);
for ( int i = 0; i < strArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -303,7 +303,7 @@ public class Array implements java.sql.Array
break;
case Types.DATE:
java.sql.Date[] dateArray = (java.sql.Date[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("date"), 4);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("date"), 4);
for ( int i = 0; i < dateArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -314,7 +314,7 @@ public class Array implements java.sql.Array
break;
case Types.TIME:
java.sql.Time[] timeArray = (java.sql.Time[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("time"), 8);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("time"), 8);
for ( int i = 0; i < timeArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -325,7 +325,7 @@ public class Array implements java.sql.Array
break;
case Types.TIMESTAMP:
java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
- fields[1] = new Field(conn, "VALUE", conn.getOID("timestamp"), 8);
+ fields[1] = new Field(conn, "VALUE", conn.getPGType("timestamp"), 8);
for ( int i = 0; i < timestampArray.length; i++ )
{
byte[][] tuple = new byte[2][0];
@@ -340,7 +340,7 @@ public class Array implements java.sql.Array
default:
throw org.postgresql.Driver.notImplemented();
}
- return new ResultSet((org.postgresql.jdbc2.Connection)conn, fields, rows, "OK", 1 );
+ return new Jdbc2ResultSet((org.postgresql.jdbc2.Jdbc2Connection)conn, fields, rows, "OK", 1 );
}
public String toString()
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
index 4aa03483253..9d37bf04bc5 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
@@ -45,7 +45,7 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im
/*
* @exception SQLException on failure
*/
- public CallableStatement(Connection c, String q) throws SQLException
+ public CallableStatement(Jdbc2Connection c, String q) throws SQLException
{
super(c, q); // don't parse yet..
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
deleted file mode 100644
index 9ab3cced8ed..00000000000
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
+++ /dev/null
@@ -1,332 +0,0 @@
-package org.postgresql.jdbc2;
-
-// IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 1 class in the
-// org.postgresql.jdbc1 package.
-
-import java.io.*;
-import java.lang.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.util.*;
-import java.sql.*;
-import org.postgresql.Field;
-import org.postgresql.fastpath.*;
-import org.postgresql.largeobject.*;
-import org.postgresql.util.*;
-
-/*
- * $Id: Connection.java,v 1.20 2002/06/24 06:16:27 barry Exp $
- *
- * A Connection represents a session with a specific database. Within the
- * context of a Connection, SQL statements are executed and results are
- * returned.
- *
- * <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.
- *
- * <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.
- *
- * @see java.sql.Connection
- */
-public class Connection extends org.postgresql.Connection implements java.sql.Connection
-{
- // This is a cache of the DatabaseMetaData instance for this connection
- protected DatabaseMetaData metadata;
-
- /*
- * The current type mappings
- */
- protected java.util.Map typemap;
-
- /*
- * SQL statements without parameters are normally executed using
- * Statement objects. If the same SQL statement is executed many
- * times, it is more efficient to use a PreparedStatement
- *
- * @return a new Statement object
- * @exception SQLException passed through from the constructor
- */
- public java.sql.Statement createStatement() throws SQLException
- {
- // The spec says default of TYPE_FORWARD_ONLY but everyone is used to
- // using TYPE_SCROLL_INSENSITIVE
- return createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
- }
-
- /*
- * SQL statements without parameters are normally executed using
- * Statement objects. If the same SQL statement is executed many
- * times, it is more efficient to use a PreparedStatement
- *
- * @param resultSetType to use
- * @param resultSetCuncurrency to use
- * @return a new Statement object
- * @exception SQLException passed through from the constructor
- */
- public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
- {
- Statement s = new Statement(this);
- s.setResultSetType(resultSetType);
- s.setResultSetConcurrency(resultSetConcurrency);
- return s;
- }
-
-
- /*
- * A SQL statement with or without IN parameters can be pre-compiled
- * and stored in a PreparedStatement object. This object can then
- * be used to efficiently execute this statement multiple times.
- *
- * <B>Note:</B> This method is optimized for handling parametric
- * SQL statements that benefit from precompilation if the drivers
- * supports precompilation. PostgreSQL does not support precompilation.
- * In this case, the statement is not sent to the database until the
- * PreparedStatement is executed. This has no direct effect on users;
- * however it does affect which method throws certain SQLExceptions
- *
- * @param sql a SQL statement that may contain one or more '?' IN
- * parameter placeholders
- * @return a new PreparedStatement object containing the pre-compiled
- * statement.
- * @exception SQLException if a database access error occurs.
- */
- public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
- {
- return prepareStatement(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
- }
-
- public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
- {
- PreparedStatement s = new PreparedStatement(this, sql);
- s.setResultSetType(resultSetType);
- s.setResultSetConcurrency(resultSetConcurrency);
- return s;
- }
-
- /*
- * A SQL stored procedure call statement is handled by creating a
- * CallableStatement for it. The CallableStatement provides methods
- * for setting up its IN and OUT parameters and methods for executing
- * it.
- *
- * <B>Note:</B> This method is optimised for handling stored procedure
- * call statements. Some drivers may send the call statement to the
- * database when the prepareCall is done; others may wait until the
- * CallableStatement is executed. This has no direct effect on users;
- * however, it does affect which method throws certain SQLExceptions
- *
- * @param sql a SQL statement that may contain one or more '?' parameter
- * placeholders. Typically this statement is a JDBC function call
- * escape string.
- * @return a new CallableStatement object containing the pre-compiled
- * SQL statement
- * @exception SQLException if a database access error occurs
- */
- public java.sql.CallableStatement prepareCall(String sql) throws SQLException
- {
- return prepareCall(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
- }
-
- public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
- {
- CallableStatement s = new CallableStatement(this,sql);
- s.setResultSetType(resultSetType);
- s.setResultSetConcurrency(resultSetConcurrency);
- return s;
- }
-
- /*
- * Tests to see if a Connection is closed.
- *
- * Peter Feb 7 2000: Now I've discovered that this doesn't actually obey the
- * specifications. Under JDBC2.1, this should only be valid _after_ close()
- * has been called. It's result is not guraranteed to be valid before, and
- * client code should not use it to see if a connection is open. The spec says
- * that the client should monitor the SQLExceptions thrown when their queries
- * fail because the connection is dead.
- *
- * I don't like this definition. As it doesn't hurt breaking it here, our
- * isClosed() implementation does test the connection, so for PostgreSQL, you
- * can rely on isClosed() returning a valid result.
- *
- * @return the status of the connection
- * @exception SQLException (why?)
- */
- public boolean isClosed() throws SQLException
- {
- // If the stream is gone, then close() was called
- if (pg_stream == null)
- return true;
- return false;
- }
-
- /*
- * 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 made
- * available through a DatabaseMetaData object.
- *
- * @return a DatabaseMetaData object for this connection
- * @exception SQLException if a database access error occurs
- */
- public java.sql.DatabaseMetaData getMetaData() throws SQLException
- {
- if (metadata == null)
- metadata = new DatabaseMetaData(this);
- return metadata;
- }
-
- /*
- * This overides the method in org.postgresql.Connection and returns a
- * ResultSet.
- */
- public java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
- {
- // In 7.1 we now test concurrency to see which class to return. If we are not working with a
- // Statement then default to a normal ResultSet object.
- if (stat != null)
- {
- if (stat.getResultSetConcurrency() == java.sql.ResultSet.CONCUR_UPDATABLE)
- return new org.postgresql.jdbc2.UpdateableResultSet((org.postgresql.jdbc2.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
- }
-
- return new org.postgresql.jdbc2.ResultSet((org.postgresql.jdbc2.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
- }
-
- // *****************
- // JDBC 2 extensions
- // *****************
-
- public java.util.Map getTypeMap() throws SQLException
- {
- // new in 7.1
- return typemap;
- }
-
-
- public void setTypeMap(java.util.Map map) throws SQLException
- {
- // new in 7.1
- typemap = map;
- }
-
- /*
- * This overides the standard internal getObject method so that we can
- * check the jdbc2 type map first
- *
- * @return PGobject for this type, and set to value
- * @exception SQLException if value is not correct for this type
- * @see org.postgresql.util.Serialize
- */
- public Object getObject(String type, String value) throws SQLException
- {
- if (typemap != null)
- {
- SQLData d = (SQLData) typemap.get(type);
- if (d != null)
- {
- // Handle the type (requires SQLInput & SQLOutput classes to be implemented)
- throw org.postgresql.Driver.notImplemented();
- }
- }
-
- // Default to the original method
- return super.getObject(type, value);
- }
-
- /* An implementation of the abstract method in the parent class.
- * This implemetation uses the jdbc2Types array to support the jdbc2
- * datatypes. Basically jdbc1 and jdbc2 are the same, except that
- * jdbc2 adds the Array types.
- */
- public int getSQLType(String pgTypeName)
- {
- int sqlType = Types.OTHER; // default value
- for (int i = 0;i < jdbc2Types.length;i++)
- {
- if (pgTypeName.equals(jdbc2Types[i]))
- {
- sqlType = jdbc2Typei[i];
- break;
- }
- }
- return sqlType;
- }
-
- /*
- * This table holds the org.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 jdbc2Types[] = {
- "int2",
- "int4", "oid",
- "int8",
- "cash", "money",
- "numeric",
- "float4",
- "float8",
- "bpchar", "char", "char2", "char4", "char8", "char16",
- "varchar", "text", "name", "filename",
- "bytea",
- "bool",
- "date",
- "time",
- "abstime", "timestamp", "timestamptz",
- "_bool", "_char", "_int2", "_int4", "_text",
- "_oid", "_varchar", "_int8", "_float4", "_float8",
- "_abstime", "_date", "_time", "_timestamp", "_numeric",
- "_bytea"
- };
-
- /*
- * 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 jdbc2Typei[] = {
- Types.SMALLINT,
- Types.INTEGER, Types.INTEGER,
- Types.BIGINT,
- Types.DOUBLE, Types.DOUBLE,
- Types.NUMERIC,
- 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.BINARY,
- Types.BIT,
- Types.DATE,
- Types.TIME,
- Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP,
- Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
- Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
- Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
- Types.ARRAY
- };
-
- //Because the get/setLogStream methods are deprecated in JDBC2
- //we use the get/setLogWriter methods here for JDBC2 by overriding
- //the base version of this method
- protected void enableDriverManagerLogging() {
- if (DriverManager.getLogWriter() == null) {
- DriverManager.setLogWriter(new PrintWriter(System.out));
- }
- }
-
-}
-
-// ***********************************************************************
-
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
index 3cc224e6e8f..77415d051d4 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
@@ -15,7 +15,7 @@ import org.postgresql.util.PSQLException;
/*
* This class provides information about the database as a whole.
*
- * $Id: DatabaseMetaData.java,v 1.58 2002/07/12 13:07:48 davec Exp $
+ * $Id: DatabaseMetaData.java,v 1.59 2002/07/23 03:59:55 barry Exp $
*
* <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
@@ -39,7 +39,7 @@ import org.postgresql.util.PSQLException;
*/
public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
- Connection connection; // The connection association
+ Jdbc2Connection connection; // The connection association
// These define various OID's. Hopefully they will stay constant.
static final int iVarcharOid = 1043; // OID for varchar
@@ -48,7 +48,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
static final int iInt4Oid = 23; // OID for int4
static final int VARHDRSZ = 4; // length for int4
- public DatabaseMetaData(Connection conn)
+ public DatabaseMetaData(Jdbc2Connection conn)
{
this.connection = conn;
}
@@ -1653,7 +1653,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
v.addElement(tuple);
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -1731,7 +1731,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
// add query loop here
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -1825,7 +1825,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
byte remarks[] = null;
- if (((org.postgresql.ResultSet)dr).getTupleCount() == 1)
+ if (((AbstractJdbc2ResultSet)dr).getTupleCount() == 1)
{
dr.next();
remarks = dr.getBytes(1);
@@ -1866,7 +1866,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
v.addElement(tuple);
}
r.close();
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
// This array contains the valid values for the types argument
@@ -1913,7 +1913,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[0] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32);
tuple[0] = "".getBytes();
v.addElement(tuple);
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -1958,7 +1958,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
tuple[0] = getTableTypes[i][0].getBytes();
v.addElement(tuple);
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2154,7 +2154,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
}
r.close();
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2218,7 +2218,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
//v.addElement(tuple);
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2281,7 +2281,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
//v.addElement(tuple);
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2337,7 +2337,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[6] = new Field(connection, "DECIMAL_DIGITS", iInt2Oid, 2);
f[7] = new Field(connection, "PSEUDO_COLUMN", iInt2Oid, 2);
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
/*
@@ -2680,7 +2680,7 @@ WHERE
tuples.addElement(tuple);
}
- return new ResultSet(connection, f, tuples, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, tuples, "OK", 1);
}
/*
@@ -2959,7 +2959,7 @@ WHERE
v.addElement(tuple);
}
rs.close();
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
throw new PSQLException("postgresql.metadata.unavailable");
@@ -3097,7 +3097,7 @@ WHERE
}
}
- return new ResultSet(connection, f, v, "OK", 1);
+ return new Jdbc2ResultSet(connection, f, v, "OK", 1);
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java
new file mode 100644
index 00000000000..cfbb3486ec6
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java
@@ -0,0 +1,62 @@
+package org.postgresql.jdbc2;
+
+
+import java.sql.*;
+import java.util.Vector;
+import org.postgresql.Field;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class implements the java.sql.Connection interface for JDBC2.
+ * However most of the implementation is really done in
+ * org.postgresql.jdbc2.AbstractJdbc2Connection or one of it's parents
+ */
+public class Jdbc2Connection extends org.postgresql.jdbc2.AbstractJdbc2Connection implements java.sql.Connection
+{
+
+ public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ Jdbc2Statement s = new Jdbc2Statement(this);
+ s.setResultSetType(resultSetType);
+ s.setResultSetConcurrency(resultSetConcurrency);
+ return s;
+ }
+
+
+ public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ org.postgresql.jdbc2.PreparedStatement s = new org.postgresql.jdbc2.PreparedStatement(this, sql);
+ s.setResultSetType(resultSetType);
+ s.setResultSetConcurrency(resultSetConcurrency);
+ return s;
+ }
+
+ public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ org.postgresql.jdbc2.CallableStatement s = new org.postgresql.jdbc2.CallableStatement(this,sql);
+ s.setResultSetType(resultSetType);
+ s.setResultSetConcurrency(resultSetConcurrency);
+ return s;
+ }
+
+ public java.sql.DatabaseMetaData getMetaData() throws SQLException
+ {
+ if (metadata == null)
+ metadata = new org.postgresql.jdbc2.DatabaseMetaData(this);
+ return metadata;
+ }
+
+ public java.sql.ResultSet getResultSet(java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
+ {
+ if (stat != null)
+ {
+ if (stat.getResultSetConcurrency() == java.sql.ResultSet.CONCUR_UPDATABLE)
+ return new org.postgresql.jdbc2.UpdateableResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
+
+ return new Jdbc2ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
+
+
+}
+
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java
new file mode 100644
index 00000000000..7200cf549ad
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java
@@ -0,0 +1,32 @@
+package org.postgresql.jdbc2;
+
+
+import java.sql.*;
+import java.util.Vector;
+import org.postgresql.Field;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2ResultSet.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class implements the java.sql.ResultSet interface for JDBC2.
+ * However most of the implementation is really done in
+ * org.postgresql.jdbc2.AbstractJdbc2ResultSet or one of it's parents
+ */
+public class Jdbc2ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet implements java.sql.ResultSet
+{
+
+ public Jdbc2ResultSet(Jdbc2Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
+ {
+ super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
+
+ public Jdbc2ResultSet(Jdbc2Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
+ {
+ super(conn, fields, tuples, status, updateCount, 0, false);
+ }
+
+ public java.sql.ResultSetMetaData getMetaData() throws SQLException
+ {
+ return new ResultSetMetaData(rows, fields);
+ }
+
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
new file mode 100644
index 00000000000..31cec93821a
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
@@ -0,0 +1,21 @@
+package org.postgresql.jdbc2;
+
+
+import java.sql.*;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.1 2002/07/23 03:59:55 barry Exp $
+ * This class implements the java.sql.Statement interface for JDBC2.
+ * However most of the implementation is really done in
+ * org.postgresql.jdbc2.AbstractJdbc2Statement or one of it's parents
+ */
+public class Jdbc2Statement extends org.postgresql.jdbc2.AbstractJdbc2Statement implements java.sql.Statement
+{
+
+ public Jdbc2Statement (Jdbc2Connection c)
+ {
+ connection = c;
+ resultsettype = java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
+ concurrency = java.sql.ResultSet.CONCUR_READ_ONLY;
+ }
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
index 5638a2692d6..21aba8d9ee0 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
@@ -29,12 +29,12 @@ import org.postgresql.util.*;
* @see ResultSet
* @see java.sql.PreparedStatement
*/
-public class PreparedStatement extends Statement implements java.sql.PreparedStatement
+public class PreparedStatement extends Jdbc2Statement implements java.sql.PreparedStatement
{
String sql;
String[] templateStrings;
String[] inStrings;
- Connection connection;
+ Jdbc2Connection connection;
// Some performance caches
private StringBuffer sbuf = new StringBuffer();
@@ -49,7 +49,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
* @param sql the SQL statement with ? for IN markers
* @exception SQLException if something bad occurs
*/
- public PreparedStatement(Connection connection, String sql) throws SQLException
+ public PreparedStatement(Jdbc2Connection connection, String sql) throws SQLException
{
super(connection);
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
deleted file mode 100644
index f5489f4e979..00000000000
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
+++ /dev/null
@@ -1,1802 +0,0 @@
-package org.postgresql.jdbc2;
-
-// IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 1 class in the
-// org.postgresql.jdbc1 package.
-
-import java.lang.*;
-import java.io.*;
-import java.math.*;
-import java.text.*;
-import java.util.*;
-import java.sql.*;
-import org.postgresql.Field;
-import org.postgresql.largeobject.*;
-import org.postgresql.util.*;
-import org.postgresql.core.Encoding;
-
-/*
- * 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.
- *
- * <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.
- *
- * <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.
- *
- * <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.
- *
- *<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.
- *
- * <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
- * SQL Query. For columns that are NOT explicitly named in the query, it is
- * best to use column numbers. If column names were used there is no way for
- * the programmer to guarentee that they actually refer to the intended
- * columns.
- *
- * <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.
- *
- * <P>The number, types and properties of a ResultSet's columns are provided by
- * the ResultSetMetaData object returned by the getMetaData method.
- *
- * @see ResultSetMetaData
- * @see java.sql.ResultSet
- */
-public class ResultSet extends org.postgresql.ResultSet implements java.sql.ResultSet
-{
- protected org.postgresql.jdbc2.Statement statement;
-
- private StringBuffer sbuf = null;
- protected byte[][] rowBuffer=null;
- protected String sqlQuery=null;
-
- /*
- * Create a new ResultSet - Note that we create ResultSets to
- * represent the results of everything.
- *
- * @param fields an array of Field objects (basically, the
- * ResultSet MetaData)
- * @param tuples Vector of the actual data
- * @param status the status string returned from the back end
- * @param updateCount the number of rows affected by the operation
- * @param cursor the positioned update/delete cursor name
- */
- public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
- {
- super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
- }
-
- /*
- * Create a new ResultSet - Note that we create ResultSets to
- * represent the results of everything.
- *
- * @param fields an array of Field objects (basically, the
- * ResultSet MetaData)
- * @param tuples Vector of the actual data
- * @param status the status string returned from the back end
- * @param updateCount the number of rows affected by the operation
- * @param cursor the positioned update/delete cursor name
- */
- public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
- {
- super(conn, fields, tuples, status, updateCount, 0, false);
- }
-
- /*
- * A ResultSet is initially positioned before its first row,
- * the first call to next makes the first row the current row;
- * the second call makes the second row the current row, etc.
- *
- * <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
- *
- * @return true if the new current is valid; false if there are no
- * more rows
- * @exception SQLException if a database access error occurs
- */
- public boolean next() throws SQLException
- {
- if (rows == null)
- throw new PSQLException("postgresql.con.closed");
-
-
- if (++current_row >= rows.size())
- return false;
-
- this_row = (byte [][])rows.elementAt(current_row);
-
- rowBuffer=new byte[this_row.length][];
- System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
- return true;
- }
-
- /*
- * In some cases, it is desirable to immediately release a ResultSet
- * database and JDBC resources instead of waiting for this to happen
- * when it is automatically closed. The close method provides this
- * immediate release.
- *
- * <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
- * when it is garbage collected.
- *
- * @exception SQLException if a database access error occurs
- */
- public void close() throws SQLException
- {
- //release resources held (memory for tuples)
- if (rows != null)
- {
- rows = null;
- }
- }
-
- /*
- * A column may have the value of SQL NULL; wasNull() reports whether
- * the last column read had this special value. Note that you must
- * first call getXXX on a column to try to read its value and then
- * call wasNull() to find if the value was SQL NULL
- *
- * @return true if the last column read was SQL NULL
- * @exception SQLException if a database access error occurred
- */
- public boolean wasNull() throws SQLException
- {
- return wasNullFlag;
- }
-
- /*
- * Get the value of a column in the current row as a Java String
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value, null for SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public String getString(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- Encoding encoding = connection.getEncoding();
- return encoding.decode(this_row[columnIndex - 1]);
- }
-
- /*
- * Get the value of a column in the current row as a Java boolean
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value, false for SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public boolean getBoolean(int columnIndex) throws SQLException
- {
- return toBoolean( getString(columnIndex) );
- }
-
- /*
- * Get the value of a column in the current row as a Java byte.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public byte getByte(int columnIndex) throws SQLException
- {
- String s = getString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Byte.parseByte(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.badbyte", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java short.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public short getShort(int columnIndex) throws SQLException
- {
- String s = getFixedString(columnIndex);
-
- if (s != null)
- {
- try
- {
- return Short.parseShort(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.badshort", s);
- }
- }
- return 0; // SQL NULL
- }
-
- /*
- * Get the value of a column in the current row as a Java int.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public int getInt(int columnIndex) throws SQLException
- {
- return toInt( getFixedString(columnIndex) );
- }
-
- /*
- * Get the value of a column in the current row as a Java long.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public long getLong(int columnIndex) throws SQLException
- {
- return toLong( getFixedString(columnIndex) );
- }
-
- /*
- * Get the value of a column in the current row as a Java float.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public float getFloat(int columnIndex) throws SQLException
- {
- return toFloat( getFixedString(columnIndex) );
- }
-
- /*
- * Get the value of a column in the current row as a Java double.
- *
- * @param columnIndex the first column is 1, the second is 2,...
- * @return the column value; 0 if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public double getDouble(int columnIndex) throws SQLException
- {
- return toDouble( getFixedString(columnIndex) );
- }
-
- /*
- * Get the value of a column in the current row as a
- * java.math.BigDecimal object
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @param scale the number of digits to the right of the decimal
- * @return the column value; if the value is SQL NULL, null
- * @exception SQLException if a database access error occurs
- * @deprecated
- */
- public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException
- {
- return toBigDecimal( getFixedString(columnIndex), scale );
- }
-
- /*
- * 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
- * is null
- * @exception SQLException if a database access error occurs
- */
- public byte[] getBytes(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (!wasNullFlag)
- {
- if (binaryCursor)
- {
- //If the data is already binary then just return it
- return this_row[columnIndex - 1];
- }
- else if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports the bytea datatype for byte arrays
- if (fields[columnIndex - 1].getPGType().equals("bytea"))
- {
- return PGbytea.toBytes(this_row[columnIndex - 1]);
- }
- else
- {
- return this_row[columnIndex - 1];
- }
- }
- else
- {
- //Version 7.1 and earlier supports LargeObjects for byte arrays
- // Handle OID's as BLOBS
- 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;
- }
- else
- {
- return this_row[columnIndex - 1];
- }
- }
- }
- return null;
- }
-
- /*
- * Get the value of a column in the current row as a java.sql.Date
- * object
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value; null if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public java.sql.Date getDate(int columnIndex) throws SQLException
- {
- return toDate( getString(columnIndex) );
- }
-
- /*
- * Get the value of a column in the current row as a java.sql.Time
- * object
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value; null if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public Time getTime(int columnIndex) throws SQLException
- {
- return toTime( getString(columnIndex), this, fields[columnIndex-1].getPGType() );
- }
-
- /*
- * Get the value of a column in the current row as a
- * java.sql.Timestamp object
- *
- * @param columnIndex the first column is 1, the second is 2...
- * @return the column value; null if SQL NULL
- * @exception SQLException if a database access error occurs
- */
- public Timestamp getTimestamp(int columnIndex) throws SQLException
- {
- return toTimestamp( getString(columnIndex), this, fields[columnIndex-1].getPGType() );
- }
-
- /*
- * A column value can be retrieved as a stream of ASCII characters
- * and then read in chunks from the stream. This method is
- * particular suitable for retrieving large LONGVARCHAR values.
- * The JDBC driver will do any necessary conversion from the
- * database format into ASCII.
- *
- * <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.
- *
- *<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.
- *
- * @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 one byte ASCII characters. If the
- * value is SQL NULL then the result is null
- * @exception SQLException if a database access error occurs
- * @see getBinaryStream
- */
- public InputStream getAsciiStream(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports AsciiStream for all the PG text types
- //As the spec/javadoc for this method indicate this is to be used for
- //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
- //long string datatype, but with toast the text datatype is capable of
- //handling very large values. Thus the implementation ends up calling
- //getString() since there is no current way to stream the value from the server
- try
- {
- return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII"));
- }
- catch (UnsupportedEncodingException l_uee)
- {
- throw new PSQLException("postgresql.unusual", l_uee);
- }
- }
- else
- {
- // In 7.1 Handle as BLOBS so return the LargeObject input stream
- return getBinaryStream(columnIndex);
- }
- }
-
- /*
- * A column value can also be retrieved as a stream of Unicode
- * characters. We implement this as a binary stream.
- *
- * ** DEPRECATED IN JDBC 2 **
- *
- * @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
- * @exception SQLException if a database access error occurs
- * @see getAsciiStream
- * @see getBinaryStream
- * @deprecated in JDBC2.0
- */
- public InputStream getUnicodeStream(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports AsciiStream for all the PG text types
- //As the spec/javadoc for this method indicate this is to be used for
- //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
- //long string datatype, but with toast the text datatype is capable of
- //handling very large values. Thus the implementation ends up calling
- //getString() since there is no current way to stream the value from the server
- try
- {
- return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8"));
- }
- catch (UnsupportedEncodingException l_uee)
- {
- throw new PSQLException("postgresql.unusual", l_uee);
- }
- }
- else
- {
- // In 7.1 Handle as BLOBS so return the LargeObject input stream
- return getBinaryStream(columnIndex);
- }
- }
-
- /*
- * A column value can also be retrieved as a binary strea. This
- * method is suitable for retrieving LONGVARBINARY values.
- *
- * @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 bytes. If the value is SQL NULL, then the result
- * is null
- * @exception SQLException if a database access error occurs
- * @see getAsciiStream
- * @see getUnicodeStream
- */
- public InputStream getBinaryStream(int columnIndex) throws SQLException
- {
- checkResultSet( columnIndex );
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports BinaryStream for all PG bytea type
- //As the spec/javadoc for this method indicate this is to be used for
- //large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
- //long binary datatype, but with toast the bytea datatype is capable of
- //handling very large values. Thus the implementation ends up calling
- //getBytes() since there is no current way to stream the value from the server
- byte b[] = getBytes(columnIndex);
- if (b != null)
- return new ByteArrayInputStream(b);
- }
- else
- {
- // In 7.1 Handle as BLOBS so return the LargeObject input stream
- if ( fields[columnIndex - 1].getOID() == 26)
- {
- LargeObjectManager lom = connection.getLargeObjectAPI();
- LargeObject lob = lom.open(getInt(columnIndex));
- return lob.getInputStream();
- }
- }
- return null;
- }
-
- /*
- * The following routines simply convert the columnName into
- * a columnIndex and then call the appropriate routine above.
- *
- * @param columnName is the SQL name of the column
- * @return the column value
- * @exception SQLException if a database access error occurs
- */
- public String getString(String columnName) throws SQLException
- {
- return getString(findColumn(columnName));
- }
-
- public boolean getBoolean(String columnName) throws SQLException
- {
- return getBoolean(findColumn(columnName));
- }
-
- public byte getByte(String columnName) throws SQLException
- {
-
- return getByte(findColumn(columnName));
- }
-
- public short getShort(String columnName) throws SQLException
- {
- return getShort(findColumn(columnName));
- }
-
- public int getInt(String columnName) throws SQLException
- {
- return getInt(findColumn(columnName));
- }
-
- public long getLong(String columnName) throws SQLException
- {
- return getLong(findColumn(columnName));
- }
-
- public float getFloat(String columnName) throws SQLException
- {
- return getFloat(findColumn(columnName));
- }
-
- public double getDouble(String columnName) throws SQLException
- {
- return getDouble(findColumn(columnName));
- }
-
- /*
- * @deprecated
- */
- public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException
- {
- return getBigDecimal(findColumn(columnName), scale);
- }
-
- public byte[] getBytes(String columnName) throws SQLException
- {
- return getBytes(findColumn(columnName));
- }
-
- public java.sql.Date getDate(String columnName) throws SQLException
- {
- return getDate(findColumn(columnName));
- }
-
- public Time getTime(String columnName) throws SQLException
- {
- return getTime(findColumn(columnName));
- }
-
- public Timestamp getTimestamp(String columnName) throws SQLException
- {
- return getTimestamp(findColumn(columnName));
- }
-
- public InputStream getAsciiStream(String columnName) throws SQLException
- {
- return getAsciiStream(findColumn(columnName));
- }
-
- /*
- *
- * ** DEPRECATED IN JDBC 2 **
- *
- * @deprecated
- */
- public InputStream getUnicodeStream(String columnName) throws SQLException
- {
- return getUnicodeStream(findColumn(columnName));
- }
-
- public InputStream getBinaryStream(String columnName) throws SQLException
- {
- return getBinaryStream(findColumn(columnName));
- }
-
- public java.net.URL getURL(int columnIndex) throws SQLException
- {
- return null;
- }
-
- public java.net.URL getURL(String columnName) throws SQLException
- {
- return null;
-
- }
-
- public void updateRef(int colIndex,java.sql.Ref ref) throws SQLException {
-
- }
- public void updateRef(String colName,java.sql.Ref ref) throws SQLException {
- }
- public void updateBlob(int colIndex,java.sql.Blob blob) throws SQLException {
- }
- public void updateBlob(String colName,java.sql.Blob blob) throws SQLException {
- }
- public void updateClob(int colIndex,java.sql.Clob clob) throws SQLException {
- }
- public void updateClob(String colName,java.sql.Clob clob) throws SQLException {
- }
- public void updateArray(int colIndex,java.sql.Array array) throws SQLException {
- }
- public void updateArray(String colName,java.sql.Array array) throws SQLException {
- }
-
- /*
- * The first warning reported by calls on this ResultSet is
- * returned. Subsequent ResultSet warnings will be chained
- * to this SQLWarning.
- *
- * <p>The warning chain is automatically cleared each time a new
- * row is read.
- *
- * <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.
- *
- * @return the first SQLWarning or null;
- * @exception SQLException if a database access error occurs.
- */
- public SQLWarning getWarnings() throws SQLException
- {
- return warnings;
- }
-
- /*
- * After this call, getWarnings returns null until a new warning
- * is reported for this ResultSet
- *
- * @exception SQLException if a database access error occurs
- */
- public void clearWarnings() throws SQLException
- {
- warnings = null;
- }
-
- /*
- * Get the name of the SQL cursor used by this ResultSet
- *
- * <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.
- *
- * <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.
- *
- * <p><B>Note:</B> If positioned update is not supported, a SQLException
- * is thrown.
- *
- * @return the ResultSet's SQL cursor name.
- * @exception SQLException if a database access error occurs
- */
- public String getCursorName() throws SQLException
- {
- return connection.getCursorName();
- }
-
- /*
- * The numbers, types and properties of a ResultSet's columns are
- * provided by the getMetaData method
- *
- * @return a description of the ResultSet's columns
- * @exception SQLException if a database access error occurs
- */
- public java.sql.ResultSetMetaData getMetaData() throws SQLException
- {
- return new ResultSetMetaData(rows, fields);
- }
-
- /*
- * Get the value of a column in the current row as a Java object
- *
- * <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.
- *
- * <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...
- * @return a Object holding the column value
- * @exception SQLException if a database access error occurs
- */
- public Object getObject(int columnIndex) throws SQLException
- {
- Field field;
-
- checkResultSet( columnIndex );
-
- wasNullFlag = (this_row[columnIndex - 1] == null);
- if (wasNullFlag)
- return null;
-
- field = fields[columnIndex - 1];
-
- // some fields can be null, mainly from those returned by MetaData methods
- if (field == null)
- {
- wasNullFlag = true;
- return null;
- }
-
- switch (field.getSQLType())
- {
- case Types.BIT:
- return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE;
- case Types.SMALLINT:
- return new Short(getShort(columnIndex));
- case Types.INTEGER:
- return new Integer(getInt(columnIndex));
- case Types.BIGINT:
- return new Long(getLong(columnIndex));
- case Types.NUMERIC:
- return getBigDecimal
- (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff));
- case Types.REAL:
- return new Float(getFloat(columnIndex));
- case Types.DOUBLE:
- return new Double(getDouble(columnIndex));
- case Types.CHAR:
- case Types.VARCHAR:
- return getString(columnIndex);
- case Types.DATE:
- return getDate(columnIndex);
- case Types.TIME:
- return getTime(columnIndex);
- case Types.TIMESTAMP:
- return getTimestamp(columnIndex);
- case Types.BINARY:
- case Types.VARBINARY:
- return getBytes(columnIndex);
- case Types.ARRAY:
- return getArray(columnIndex);
- default:
- String type = field.getPGType();
- // if the backend doesn't know the type then coerce to String
- if (type.equals("unknown"))
- {
- return getString(columnIndex);
- }
- else
- {
- return connection.getObject(field.getPGType(), getString(columnIndex));
- }
- }
- }
-
- /*
- * Get the value of a column in the current row as a Java object
- *
- *<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.
- *
- * <p>This method may also be used to read database specific abstract
- * data types.
- *
- * @param columnName is the SQL name of the column
- * @return a Object holding the column value
- * @exception SQLException if a database access error occurs
- */
- public Object getObject(String columnName) throws SQLException
- {
- return getObject(findColumn(columnName));
- }
-
- /*
- * Map a ResultSet column name to a ResultSet column index
- *
- * @param columnName the name of the column
- * @return the column index
- * @exception SQLException if a database access error occurs
- */
- public int findColumn(String columnName) throws SQLException
- {
- int i;
-
- final int flen = fields.length;
- for (i = 0 ; i < flen; ++i)
- if (fields[i].getName().equalsIgnoreCase(columnName))
- return (i + 1);
- throw new PSQLException ("postgresql.res.colname", columnName);
- }
-
- // ** JDBC 2 Extensions **
-
- public boolean absolute(int index) throws SQLException
- {
- // index is 1-based, but internally we use 0-based indices
- int internalIndex;
-
- if (index == 0)
- throw new SQLException("Cannot move to index of 0");
-
- final int rows_size = rows.size();
-
- //if index<0, count from the end of the result set, but check
- //to be sure that it is not beyond the first index
- if (index < 0)
- {
- if (index >= -rows_size)
- internalIndex = rows_size + index;
- else
- {
- beforeFirst();
- return false;
- }
- }
- else
- {
- //must be the case that index>0,
- //find the correct place, assuming that
- //the index is not too large
- if (index <= rows_size)
- internalIndex = index - 1;
- else
- {
- afterLast();
- return false;
- }
- }
-
- current_row = internalIndex;
- this_row = (byte [][])rows.elementAt(internalIndex);
- return true;
- }
-
- public void afterLast() throws SQLException
- {
- final int rows_size = rows.size();
- if (rows_size > 0)
- current_row = rows_size;
- }
-
- public void beforeFirst() throws SQLException
- {
- if (rows.size() > 0)
- current_row = -1;
- }
-
- public void cancelRowUpdates() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void deleteRow() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public boolean first() throws SQLException
- {
- if (rows.size() <= 0)
- return false;
-
- current_row = 0;
- this_row = (byte [][])rows.elementAt(current_row);
-
- rowBuffer=new byte[this_row.length][];
- System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
-
- return true;
- }
-
- public java.sql.Array getArray(String colName) throws SQLException
- {
- return getArray(findColumn(colName));
- }
-
- public java.sql.Array getArray(int i) throws SQLException
- {
- wasNullFlag = (this_row[i - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (i < 1 || i > fields.length)
- throw new PSQLException("postgresql.res.colrange");
- return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i - 1], this );
- }
-
- public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException
- {
- return getBigDecimal(columnIndex, -1);
- }
-
- public java.math.BigDecimal getBigDecimal(String columnName) throws SQLException
- {
- return getBigDecimal(findColumn(columnName));
- }
-
- public Blob getBlob(String columnName) throws SQLException
- {
- return getBlob(findColumn(columnName));
- }
-
- public Blob getBlob(int i) throws SQLException
- {
- return new org.postgresql.largeobject.PGblob(connection, getInt(i));
- }
-
- public java.io.Reader getCharacterStream(String columnName) throws SQLException
- {
- return getCharacterStream(findColumn(columnName));
- }
-
- public java.io.Reader getCharacterStream(int i) throws SQLException
- {
- checkResultSet( i );
- wasNullFlag = (this_row[i - 1] == null);
- if (wasNullFlag)
- return null;
-
- if (connection.haveMinimumCompatibleVersion("7.2"))
- {
- //Version 7.2 supports AsciiStream for all the PG text types
- //As the spec/javadoc for this method indicate this is to be used for
- //large text values (i.e. LONGVARCHAR) PG doesn't have a separate
- //long string datatype, but with toast the text datatype is capable of
- //handling very large values. Thus the implementation ends up calling
- //getString() since there is no current way to stream the value from the server
- return new CharArrayReader(getString(i).toCharArray());
- }
- else
- {
- // In 7.1 Handle as BLOBS so return the LargeObject input stream
- Encoding encoding = connection.getEncoding();
- InputStream input = getBinaryStream(i);
- return encoding.getDecodingReader(input);
- }
- }
-
- /*
- * New in 7.1
- */
- public Clob getClob(String columnName) throws SQLException
- {
- return getClob(findColumn(columnName));
- }
-
- /*
- * New in 7.1
- */
- public Clob getClob(int i) throws SQLException
- {
- return new org.postgresql.largeobject.PGclob(connection, getInt(i));
- }
-
- public int getConcurrency() throws SQLException
- {
- // New in 7.1 - The standard ResultSet class will now return
- // CONCUR_READ_ONLY. A sub-class will overide this if the query was
- // updateable.
- return CONCUR_READ_ONLY;
- }
-
- public java.sql.Date getDate(int i, java.util.Calendar cal) throws SQLException
- {
- // new in 7.1: If I read the specs, this should use cal only if we don't
- // store the timezone, and if we do, then act just like getDate()?
- // for now...
- return getDate(i);
- }
-
- public Time getTime(int i, java.util.Calendar cal) throws SQLException
- {
- // new in 7.1: If I read the specs, this should use cal only if we don't
- // store the timezone, and if we do, then act just like getTime()?
- // for now...
- return getTime(i);
- }
-
- public Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException
- {
- // new in 7.1: If I read the specs, this should use cal only if we don't
- // store the timezone, and if we do, then act just like getDate()?
- // for now...
- return getTimestamp(i);
- }
-
- public java.sql.Date getDate(String c, java.util.Calendar cal) throws SQLException
- {
- return getDate(findColumn(c), cal);
- }
-
- public Time getTime(String c, java.util.Calendar cal) throws SQLException
- {
- return getTime(findColumn(c), cal);
- }
-
- public Timestamp getTimestamp(String c, java.util.Calendar cal) throws SQLException
- {
- return getTimestamp(findColumn(c), cal);
- }
-
- public int getFetchDirection() throws SQLException
- {
- // new in 7.1: PostgreSQL normally sends rows first->last
- return FETCH_FORWARD;
- }
-
- public int getFetchSize() throws SQLException
- {
- // new in 7.1: In this implementation we return the entire result set, so
- // here return the number of rows we have. Sub-classes can return a proper
- // value
- return rows.size();
- }
-
- public Object getObject(String columnName, java.util.Map map) throws SQLException
- {
- return getObject(findColumn(columnName), map);
- }
-
- /*
- * This checks against map for the type of column i, and if found returns
- * an object based on that mapping. The class must implement the SQLData
- * interface.
- */
- public Object getObject(int i, java.util.Map map) throws SQLException
- {
- /* In preparation
- SQLInput s = new PSQLInput(this,i);
- String t = getTypeName(i);
- SQLData o = (SQLData) map.get(t);
- // If the type is not in the map, then pass to the existing code
- if (o==null)
- return getObject(i);
- o.readSQL(s,t);
- return o;
- */throw org.postgresql.Driver.notImplemented();
- }
-
- public Ref getRef(String columnName) throws SQLException
- {
- return getRef(findColumn(columnName));
- }
-
- public Ref getRef(int i) throws SQLException
- {
- // new in 7.1: The backend doesn't yet have SQL3 REF types
- throw new PSQLException("postgresql.psqlnotimp");
- }
-
- public int getRow() throws SQLException
- {
- final int rows_size = rows.size();
-
- if (current_row < 0 || current_row >= rows_size)
- return 0;
-
- return current_row + 1;
- }
-
- // This one needs some thought, as not all ResultSets come from a statement
- public java.sql.Statement getStatement() throws SQLException
- {
- return statement;
- }
-
- public int getType() throws SQLException
- {
- // New in 7.1. This implementation allows scrolling but is not able to
- // see any changes. Sub-classes may overide this to return a more
- // meaningful result.
- return TYPE_SCROLL_INSENSITIVE;
- }
-
- public void insertRow() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public boolean isAfterLast() throws SQLException
- {
- final int rows_size = rows.size();
- return (current_row >= rows_size && rows_size > 0);
- }
-
- public boolean isBeforeFirst() throws SQLException
- {
- return (current_row < 0 && rows.size() > 0);
- }
-
- public boolean isFirst() throws SQLException
- {
- return (current_row == 0 && rows.size() >= 0);
- }
-
- public boolean isLast() throws SQLException
- {
- final int rows_size = rows.size();
- return (current_row == rows_size - 1 && rows_size > 0);
- }
-
- public boolean last() throws SQLException
- {
- final int rows_size = rows.size();
- if (rows_size <= 0)
- return false;
-
- current_row = rows_size - 1;
- this_row = (byte [][])rows.elementAt(current_row);
-
- rowBuffer=new byte[this_row.length][];
- System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
-
- return true;
- }
-
- public void moveToCurrentRow() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void moveToInsertRow() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public boolean previous() throws SQLException
- {
- if (--current_row < 0)
- return false;
- this_row = (byte [][])rows.elementAt(current_row);
- System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
- return true;
- }
-
- public void refreshRow() throws SQLException
- {
- throw new PSQLException("postgresql.notsensitive");
- }
-
- // Peter: Implemented in 7.0
- public boolean relative(int rows) throws SQLException
- {
- //have to add 1 since absolute expects a 1-based index
- return absolute(current_row + 1 + rows);
- }
-
- public boolean rowDeleted() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- return false; // javac complains about not returning a value!
- }
-
- public boolean rowInserted() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- return false; // javac complains about not returning a value!
- }
-
- public boolean rowUpdated() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- return false; // javac complains about not returning a value!
- }
-
- public void setFetchDirection(int direction) throws SQLException
- {
- // In 7.1, the backend doesn't yet support this
- throw new PSQLException("postgresql.psqlnotimp");
- }
-
- public void setFetchSize(int rows) throws SQLException
- {
- // Sub-classes should implement this as part of their cursor support
- throw org.postgresql.Driver.notImplemented();
- }
-
- public void updateAsciiStream(int columnIndex,
- java.io.InputStream x,
- int length
- ) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateAsciiStream(String columnName,
- java.io.InputStream x,
- int length
- ) throws SQLException
- {
- updateAsciiStream(findColumn(columnName), x, length);
- }
-
- public void updateBigDecimal(int columnIndex,
- java.math.BigDecimal x
- ) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateBigDecimal(String columnName,
- java.math.BigDecimal x
- ) throws SQLException
- {
- updateBigDecimal(findColumn(columnName), x);
- }
-
- public void updateBinaryStream(int columnIndex,
- java.io.InputStream x,
- int length
- ) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateBinaryStream(String columnName,
- java.io.InputStream x,
- int length
- ) throws SQLException
- {
- updateBinaryStream(findColumn(columnName), x, length);
- }
-
- public void updateBoolean(int columnIndex, boolean x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateBoolean(String columnName, boolean x) throws SQLException
- {
- updateBoolean(findColumn(columnName), x);
- }
-
- public void updateByte(int columnIndex, byte x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateByte(String columnName, byte x) throws SQLException
- {
- updateByte(findColumn(columnName), x);
- }
-
- public void updateBytes(String columnName, byte[] x) throws SQLException
- {
- updateBytes(findColumn(columnName), x);
- }
-
- public void updateBytes(int columnIndex, byte[] x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateCharacterStream(int columnIndex,
- java.io.Reader x,
- int length
- ) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateCharacterStream(String columnName,
- java.io.Reader x,
- int length
- ) throws SQLException
- {
- updateCharacterStream(findColumn(columnName), x, length);
- }
-
- public void updateDate(int columnIndex, java.sql.Date x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateDate(String columnName, java.sql.Date x) throws SQLException
- {
- updateDate(findColumn(columnName), x);
- }
-
- public void updateDouble(int columnIndex, double x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateDouble(String columnName, double x) throws SQLException
- {
- updateDouble(findColumn(columnName), x);
- }
-
- public void updateFloat(int columnIndex, float x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateFloat(String columnName, float x) throws SQLException
- {
- updateFloat(findColumn(columnName), x);
- }
-
- public void updateInt(int columnIndex, int x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateInt(String columnName, int x) throws SQLException
- {
- updateInt(findColumn(columnName), x);
- }
-
- public void updateLong(int columnIndex, long x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateLong(String columnName, long x) throws SQLException
- {
- updateLong(findColumn(columnName), x);
- }
-
- public void updateNull(int columnIndex) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateNull(String columnName) throws SQLException
- {
- updateNull(findColumn(columnName));
- }
-
- public void updateObject(int columnIndex, Object x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateObject(String columnName, Object x) throws SQLException
- {
- updateObject(findColumn(columnName), x);
- }
-
- public void updateObject(int columnIndex, Object x, int scale) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateObject(String columnName, Object x, int scale) throws SQLException
- {
- updateObject(findColumn(columnName), x, scale);
- }
-
- public void updateRow() throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateShort(int columnIndex, short x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateShort(String columnName, short x) throws SQLException
- {
- updateShort(findColumn(columnName), x);
- }
-
- public void updateString(int columnIndex, String x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateString(String columnName, String x) throws SQLException
- {
- updateString(findColumn(columnName), x);
- }
-
- public void updateTime(int columnIndex, Time x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateTime(String columnName, Time x) throws SQLException
- {
- updateTime(findColumn(columnName), x);
- }
-
- public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException
- {
- // only sub-classes implement CONCUR_UPDATEABLE
- notUpdateable();
- }
-
- public void updateTimestamp(String columnName, Timestamp x) throws SQLException
- {
- updateTimestamp(findColumn(columnName), x);
- }
-
- // helper method. Throws an SQLException when an update is not possible
- public void notUpdateable() throws SQLException
- {
- throw new PSQLException("postgresql.noupdate");
- }
-
- /*
- * This is called by Statement to register itself with this statement.
- * It's used currently by getStatement() but may also with the new core
- * package.
- */
- public void setStatement(org.postgresql.jdbc2.Statement statement)
- {
- this.statement = statement;
- }
-
- //----------------- Formatting Methods -------------------
-
- public static boolean toBoolean(String s)
- {
- if (s != null)
- {
- int c = s.charAt(0);
- return ((c == 't') || (c == 'T') || (c == '1'));
- }
- return false; // SQL NULL
- }
-
- public static int toInt(String s) throws SQLException
- {
- if (s != null)
- {
- try
- {
- return Integer.parseInt(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badint", s);
- }
- }
- return 0; // SQL NULL
- }
-
- public static long toLong(String s) throws SQLException
- {
- if (s != null)
- {
- try
- {
- return Long.parseLong(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badlong", s);
- }
- }
- return 0; // SQL NULL
- }
-
- public static BigDecimal toBigDecimal(String s, int scale) throws SQLException
- {
- BigDecimal val;
- if (s != null)
- {
- try
- {
- val = new BigDecimal(s);
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badbigdec", s);
- }
- if (scale == -1)
- return val;
- try
- {
- return val.setScale(scale);
- }
- catch (ArithmeticException e)
- {
- throw new PSQLException ("postgresql.res.badbigdec", s);
- }
- }
- return null; // SQL NULL
- }
-
- public static float toFloat(String s) throws SQLException
- {
- if (s != null)
- {
- try
- {
- return Float.valueOf(s).floatValue();
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.badfloat", s);
- }
- }
- return 0; // SQL NULL
- }
-
- public static double toDouble(String s) throws SQLException
- {
- if (s != null)
- {
- try
- {
- return Double.valueOf(s).doubleValue();
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException ("postgresql.res.baddouble", s);
- }
- }
- return 0; // SQL NULL
- }
-
- public static java.sql.Date toDate(String s) throws SQLException
- {
- if (s == null)
- return null;
- // length == 10: SQL Date
- // length > 10: SQL Timestamp, assumes PGDATESTYLE=ISO
- try
- {
- return java.sql.Date.valueOf((s.length() == 10) ? s : s.substring(0, 10));
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.baddate", s);
- }
- }
-
- public static Time toTime(String s, ResultSet resultSet, String pgDataType) throws SQLException
- {
- if (s == null)
- return null; // SQL NULL
- try
- {
- if (s.length() == 8) {
- //value is a time value
- return java.sql.Time.valueOf(s);
- } else if (s.indexOf(".") == 8) {
- //value is a time value with fractional seconds
- java.sql.Time l_time = java.sql.Time.valueOf(s.substring(0,8));
- String l_strMillis = s.substring(9);
- if (l_strMillis.length() > 3)
- l_strMillis = l_strMillis.substring(0,3);
- int l_millis = Integer.parseInt(l_strMillis);
- if (l_millis < 10) {
- l_millis = l_millis * 100;
- } else if (l_millis < 100) {
- l_millis = l_millis * 10;
- }
- return new java.sql.Time(l_time.getTime() + l_millis);
- } else {
- //value is a timestamp
- return new java.sql.Time(toTimestamp(s, resultSet, pgDataType).getTime());
- }
- }
- catch (NumberFormatException e)
- {
- throw new PSQLException("postgresql.res.badtime", s);
- }
- }
-
- /**
- * Parse a string and return a timestamp representing its value.
- *
- * The driver is set to return ISO date formated strings. We modify this
- * string from the ISO format to a format that Java can understand. Java
- * expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
- * Java also expects fractional seconds to 3 places where postgres
- * will give, none, 2 or 6 depending on the time and postgres version.
- * From version 7.2 postgres returns fractional seconds to 6 places.
- * If available, we drop the last 3 digits.
- *
- * @param s The ISO formated date string to parse.
- * @param resultSet The ResultSet this date is part of.
- *
- * @return null if s is null or a timestamp of the parsed string s.
- *
- * @throws SQLException if there is a problem parsing s.
- **/
- public static Timestamp toTimestamp(String s, ResultSet resultSet, String pgDataType)
- throws SQLException
- {
- if (s == null)
- return null;
-
- // We must be synchronized here incase more theads access the ResultSet
- // bad practice but possible. Anyhow this is to protect sbuf and
- // SimpleDateFormat objects
- synchronized (resultSet)
- {
- SimpleDateFormat df = null;
- if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug("the data from the DB is "+s);
-
- // If first time, create the buffer, otherwise clear it.
- if (resultSet.sbuf == null)
- resultSet.sbuf = new StringBuffer();
- else
- resultSet.sbuf.setLength(0);
-
- // Copy s into sbuf for parsing.
- resultSet.sbuf.append(s);
- int slen = s.length();
-
- if (slen > 19)
- {
- // The len of the ISO string to the second value is 19 chars. If
- // greater then 19, there may be tz info and perhaps fractional
- // second info which we need to change to java to read it.
-
- // cut the copy to second value "2001-12-07 16:29:22"
- int i = 19;
- resultSet.sbuf.setLength(i);
-
- char c = s.charAt(i++);
- if (c == '.')
- {
- // Found a fractional value. Append up to 3 digits including
- // the leading '.'
- do
- {
- if (i < 24)
- resultSet.sbuf.append(c);
- c = s.charAt(i++);
- } while (i < slen && Character.isDigit(c));
-
- // If there wasn't at least 3 digits we should add some zeros
- // to make up the 3 digits we tell java to expect.
- for (int j = i; j < 24; j++)
- resultSet.sbuf.append('0');
- }
- else
- {
- // No fractional seconds, lets add some.
- resultSet.sbuf.append(".000");
- }
-
- if (i < slen)
- {
- // prepend the GMT part and then add the remaining bit of
- // the string.
- resultSet.sbuf.append(" GMT");
- resultSet.sbuf.append(c);
- resultSet.sbuf.append(s.substring(i, slen));
-
- // Lastly, if the tz part doesn't specify the :MM part then
- // we add ":00" for java.
- if (slen - i < 5)
- resultSet.sbuf.append(":00");
-
- // we'll use this dateformat string to parse the result.
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
- }
- else
- {
- // Just found fractional seconds but no timezone.
- //If timestamptz then we use GMT, else local timezone
- if (pgDataType.equals("timestamptz")) {
- resultSet.sbuf.append(" GMT");
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
- } else {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
- }
- }
- }
- else if (slen == 19)
- {
- // No tz or fractional second info.
- //If timestamptz then we use GMT, else local timezone
- if (pgDataType.equals("timestamptz")) {
- resultSet.sbuf.append(" GMT");
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
- } else {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- }
- }
- else
- {
- // We must just have a date. This case is
- // needed if this method is called on a date
- // column
- df = new SimpleDateFormat("yyyy-MM-dd");
- }
-
- try
- {
- // All that's left is to parse the string and return the ts.
- if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug( "" + df.parse(resultSet.sbuf.toString()).getTime() );
-
- return new Timestamp(df.parse(resultSet.sbuf.toString()).getTime());
- }
- catch (ParseException e)
- {
- throw new PSQLException("postgresql.res.badtimestamp", new Integer(e.getErrorOffset()), s);
- }
- }
- }
-
- public void setSQLQuery(String sqlQuery) {
- this.sqlQuery=sqlQuery;
- }
-}
-
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java
deleted file mode 100644
index a00025ff72a..00000000000
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java
+++ /dev/null
@@ -1,381 +0,0 @@
-package org.postgresql.jdbc2;
-
-// IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 1 class in the
-// org.postgresql.jdbc1 package.
-
-import java.sql.*;
-import java.util.Vector;
-import org.postgresql.util.*;
-
-/*
- * A Statement object is used for executing a static SQL statement and
- * obtaining the results produced by it.
- *
- * <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
- * statement's current ResultSet if an open one exists.
- *
- * @see java.sql.Statement
- * @see ResultSet
- */
-public class Statement extends org.postgresql.Statement implements java.sql.Statement
-{
- private Connection connection; // The connection who created us
- private Vector batch = null;
- private int resultsettype; // the resultset type to return
- private int concurrency; // is it updateable or not?
-
- /*
- * Constructor for a Statement. It simply sets the connection
- * that created us.
- *
- * @param c the Connection instantation that creates us
- */
- public Statement (Connection c)
- {
- connection = c;
- resultsettype = java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
- concurrency = java.sql.ResultSet.CONCUR_READ_ONLY;
- }
-
- /*
- * Execute a SQL statement that retruns a single ResultSet
- *
- * @param sql typically a static SQL SELECT statement
- * @return a ResulSet that contains the data produced by the query
- * @exception SQLException if a database access error occurs
- */
- public java.sql.ResultSet executeQuery(String sql) throws SQLException
- {
- this.execute(sql);
- while (result != null && !((org.postgresql.ResultSet)result).reallyResultSet())
- result = ((org.postgresql.ResultSet)result).getNext();
- if (result == null)
- throw new PSQLException("postgresql.stat.noresult");
- return result;
- }
-
- /*
- * Execute a SQL INSERT, UPDATE or DELETE statement. In addition
- * SQL statements that return nothing such as SQL DDL statements
- * can be executed
- *
- * @param sql a SQL statement
- * @return either a row count, or 0 for SQL commands
- * @exception SQLException if a database access error occurs
- */
- public int executeUpdate(String sql) throws SQLException
- {
- this.execute(sql);
- if (((org.postgresql.ResultSet)result).reallyResultSet())
- throw new PSQLException("postgresql.stat.result");
- return this.getUpdateCount();
- }
-
- /*
- * setCursorName defines the SQL cursor name that will be used by
- * subsequent execute methods. This name can then be used in SQL
- * positioned update/delete statements to identify the current row
- * in the ResultSet generated by this statement. If a database
- * doesn't support positioned update/delete, this method is a
- * no-op.
- *
- * <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.
- *
- * <p>We throw an additional constriction. There can only be one
- * cursor active at any one time.
- *
- * @param name the new cursor name
- * @exception SQLException if a database access error occurs
- */
- public void setCursorName(String name) throws SQLException
- {
- connection.setCursorName(name);
- }
-
- /*
- * Execute a SQL statement that may return multiple results. We
- * don't have to worry about this since we do not support multiple
- * ResultSets. You can use getResultSet or getUpdateCount to
- * retrieve the result.
- *
- * @param sql any SQL statement
- * @return true if the next result is a ResulSet, false if it is
- * an update count or there are no more results
- * @exception SQLException if a database access error occurs
- */
- public boolean execute(String sql) throws SQLException
- {
- if (escapeProcessing)
- sql = escapeSQL(sql);
-
- // New in 7.1, if we have a previous resultset then force it to close
- // This brings us nearer to compliance, and helps memory management.
- // Internal stuff will call ExecSQL directly, bypassing this.
- if (result != null)
- {
- java.sql.ResultSet rs = getResultSet();
- if (rs != null)
- rs.close();
- }
-
-
- // New in 7.1, pass Statement so that ExecSQL can customise to it
- result = connection.ExecSQL(sql, this);
-
- // New in 7.1, required for ResultSet.getStatement() to work
- ((org.postgresql.jdbc2.ResultSet)result).setStatement(this);
-
- // Added this so that the Updateable resultset knows the query that gave this
- ((org.postgresql.jdbc2.ResultSet)result).setSQLQuery(sql);
-
-
- return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
- }
-
- /*
- * getUpdateCount returns the current result as an update count,
- * if the result is a ResultSet or there are no more results, -1
- * is returned. It should only be called once per result.
- *
- * @return the current result as an update count.
- * @exception SQLException if a database access error occurs
- */
- public int getUpdateCount() throws SQLException
- {
- if (result == null)
- return -1;
- if (((org.postgresql.ResultSet)result).reallyResultSet())
- return -1;
- return ((org.postgresql.ResultSet)result).getResultCount();
- }
-
- /*
- * getMoreResults moves to a Statement's next result. If it returns
- * true, this result is a ResulSet.
- *
- * @return true if the next ResultSet is valid
- * @exception SQLException if a database access error occurs
- */
- public boolean getMoreResults() throws SQLException
- {
- result = ((org.postgresql.ResultSet)result).getNext();
- return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
- }
-
- // ** JDBC 2 Extensions **
-
- public void addBatch(String sql) throws SQLException
- {
- if (batch == null)
- batch = new Vector();
- batch.addElement(sql);
- }
-
- public void clearBatch() throws SQLException
- {
- if (batch != null)
- batch.removeAllElements();
- }
-
- public int[] executeBatch() throws SQLException
- {
- if (batch == null)
- batch = new Vector();
- int size = batch.size();
- int[] result = new int[size];
- int i = 0;
- try
- {
- for (i = 0;i < size;i++)
- result[i] = this.executeUpdate((String)batch.elementAt(i));
- }
- catch (SQLException e)
- {
- int[] resultSucceeded = new int[i];
- System.arraycopy(result, 0, resultSucceeded, 0, i);
-
- PBatchUpdateException updex =
- new PBatchUpdateException("postgresql.stat.batch.error",
- new Integer(i), batch.elementAt(i), resultSucceeded);
- updex.setNextException(e);
-
- throw updex;
- }
- finally
- {
- batch.removeAllElements();
- }
- return result;
- }
-
- public void cancel() throws SQLException
- {
- connection.cancelQuery();
- }
-
- public java.sql.Connection getConnection() throws SQLException
- {
- return (java.sql.Connection)connection;
- }
-
- public int getFetchDirection() throws SQLException
- {
- throw new PSQLException("postgresql.psqlnotimp");
- }
-
- public int getFetchSize() throws SQLException
- {
- // This one can only return a valid value when were a cursor?
- throw org.postgresql.Driver.notImplemented();
- }
-
- public int getResultSetConcurrency() throws SQLException
- {
- // new in 7.1
- return concurrency;
- }
-
- public int getResultSetType() throws SQLException
- {
- // new in 7.1
- return resultsettype;
- }
-
- public void setFetchDirection(int direction) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
- }
-
- public void setFetchSize(int rows) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
- }
-
- /*
- * New in 7.1
- */
- public void setResultSetConcurrency(int value) throws SQLException
- {
- concurrency = value;
- }
-
- /*
- * New in 7.1
- */
- public void setResultSetType(int value) throws SQLException
- {
- resultsettype = value;
- }
-
- // In JDK 1.4 not implemented
- /**
- *
- * @param num
- * @return
- * @throws SQLException
- */
- public boolean getMoreResults(int num) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
- }
-
- /**
- *
- * @return
- * @throws SQLException
- */
- public java.sql.ResultSet getGeneratedKeys() throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
- }
-
- /**
- *
- * @param a
- * @param b
- * @return
- * @throws SQLException
- */
- public int executeUpdate(String a, int b) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
- }
-
- /**
- *
- * @param a
- * @param b
- * @return
- * @throws SQLException
- */
- public int executeUpdate(String a, int[] b) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
-
- }
-
- public int executeUpdate(String a, String[] b) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
-
- }
-
- /**
- *
- * @param a
- * @param b
- * @return
- * @throws SQLException
- */
- public boolean execute(String a, int b) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
-
- }
-
- /**
- *
- * @param a
- * @param b
- * @return
- * @throws SQLException
- */
- public boolean execute(String a, int[] b) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
-
- }
-
- /**
- *
- * @param a
- * @param b
- * @return
- * @throws SQLException
- */
- public boolean execute(String a, String[] b) throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
-
- }
-
- /**
- *
- * @return
- * @throws SQLException
- */
- public int getResultSetHoldability() throws SQLException
- {
- throw org.postgresql.Driver.notImplemented();
-
- }
-
-} \ No newline at end of file
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/UpdateableResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/UpdateableResultSet.java
index 9ff8be4080d..6f6f67d8394 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/UpdateableResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/UpdateableResultSet.java
@@ -1,9 +1,7 @@
package org.postgresql.jdbc2;
// IMPORTANT NOTE: This is the begining of supporting updateable ResultSets.
-// It is not a working solution (yet)!
//
-// You will notice here we really do throw org.postgresql.Driver.notImplemented()
// This is because here we should be updateable, so any unimplemented methods
// must say so.
//
@@ -27,7 +25,7 @@ import org.postgresql.Driver;
* @see ResultSetMetaData
* @see java.sql.ResultSet
*/
-public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
+public class UpdateableResultSet extends org.postgresql.jdbc2.Jdbc2ResultSet
{
@@ -118,7 +116,7 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
* @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name
*/
- public UpdateableResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
+ public UpdateableResultSet(Jdbc2Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
{
super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
@@ -274,7 +272,7 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
{
// we have to get the last inserted OID and put it in the resultset
- long insertedOID = ((org.postgresql.Statement)insertStatement).getLastOID();
+ long insertedOID = ((AbstractJdbc2Statement)insertStatement).getLastOID();
updateValues.put("oid", new Long(insertedOID) );
@@ -670,7 +668,7 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
selectStatement.setObject( i, ((PrimaryKey)primaryKeys.get(j)).getValue() );
}
- org.postgresql.jdbc2.ResultSet rs = (org.postgresql.jdbc2.ResultSet) selectStatement.executeQuery();
+ Jdbc2ResultSet rs = (Jdbc2ResultSet) selectStatement.executeQuery();
if( rs.first() )
{
@@ -1274,7 +1272,7 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
else
{
// otherwise go and get the primary keys and create a hashtable of keys
- java.sql.ResultSet rs = ((org.postgresql.jdbc2.Connection)connection).getMetaData().getPrimaryKeys("","",tableName);
+ java.sql.ResultSet rs = ((java.sql.Connection)connection).getMetaData().getPrimaryKeys("","",tableName);
for( ; rs.next(); i++ )
diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
index e5296189cdc..a037ab28a21 100644
--- a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
+++ b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
@@ -94,16 +94,16 @@ public class LargeObjectManager
* org.postgresql.Connection class keeps track of the various extension API's
* and it's advised you use those to gain access, and not going direct.
*/
- public LargeObjectManager(org.postgresql.Connection conn) throws SQLException
+ public LargeObjectManager(Connection conn) throws SQLException
{
// We need Fastpath to do anything
- this.fp = conn.getFastpathAPI();
+ this.fp = ((org.postgresql.PGConnection)conn).getFastpathAPI();
// Now get the function oid's for the api
//
// This is an example of Fastpath.addFunctions();
//
- java.sql.ResultSet res = (java.sql.ResultSet)conn.createStatement().executeQuery("select proname, oid from pg_proc" +
+ ResultSet res = conn.createStatement().executeQuery("select proname, oid from pg_proc" +
" where proname = 'lo_open'" +
" or proname = 'lo_close'" +
" or proname = 'lo_creat'" +
diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java b/src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java
index 12e04e4c14a..87c1ac24774 100644
--- a/src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java
+++ b/src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java
@@ -20,18 +20,16 @@ import org.postgresql.largeobject.*;
* This implements the Blob interface, which is basically another way to
* access a LargeObject.
*
- * $Id: PGblob.java,v 1.3 2001/11/19 22:33:39 momjian Exp $
+ * $Id: PGblob.java,v 1.4 2002/07/23 03:59:55 barry Exp $
*
*/
public class PGblob implements java.sql.Blob
{
- private org.postgresql.Connection conn;
private int oid;
private LargeObject lo;
- public PGblob(org.postgresql.Connection conn, int oid) throws SQLException
+ public PGblob(org.postgresql.PGConnection conn, int oid) throws SQLException
{
- this.conn = conn;
this.oid = oid;
LargeObjectManager lom = conn.getLargeObjectAPI();
this.lo = lom.open(oid);
diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java b/src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java
index 63d39c07b0f..71c3f8a2f0c 100644
--- a/src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java
+++ b/src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java
@@ -20,18 +20,16 @@ import org.postgresql.largeobject.*;
* This implements the Blob interface, which is basically another way to
* access a LargeObject.
*
- * $Id: PGclob.java,v 1.3 2001/11/19 22:33:39 momjian Exp $
+ * $Id: PGclob.java,v 1.4 2002/07/23 03:59:55 barry Exp $
*
*/
public class PGclob implements java.sql.Clob
{
- private org.postgresql.Connection conn;
private int oid;
private LargeObject lo;
- public PGclob(org.postgresql.Connection conn, int oid) throws SQLException
+ public PGclob(org.postgresql.PGConnection conn, int oid) throws SQLException
{
- this.conn = conn;
this.oid = oid;
LargeObjectManager lom = conn.getLargeObjectAPI();
this.lo = lom.open(oid);
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java
index ae436fbf18b..45bab13b0e0 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java
@@ -8,7 +8,7 @@ import java.sql.*;
import org.postgresql.largeobject.*;
/*
- * $Id: BlobTest.java,v 1.5 2001/11/19 23:16:46 momjian Exp $
+ * $Id: BlobTest.java,v 1.6 2002/07/23 03:59:55 barry Exp $
*
* Some simple tests based on problems reported by users. Hopefully these will
* help prevent previous problems from re-occuring ;-)
@@ -95,7 +95,7 @@ public class BlobTest extends TestCase
*/
private int uploadFile(String file, int method) throws Exception
{
- LargeObjectManager lom = ((org.postgresql.Connection)con).getLargeObjectAPI();
+ LargeObjectManager lom = ((org.postgresql.PGConnection)con).getLargeObjectAPI();
FileInputStream fis = new FileInputStream(file);
@@ -160,7 +160,7 @@ public class BlobTest extends TestCase
{
boolean result = true;
- LargeObjectManager lom = ((org.postgresql.Connection)con).getLargeObjectAPI();
+ LargeObjectManager lom = ((org.postgresql.PGConnection)con).getLargeObjectAPI();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(JDBC2Tests.selectSQL("testblob", "id,lo"));
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java
index 6db4f412184..682118b6c17 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java
@@ -10,7 +10,7 @@ import java.sql.*;
*
* PS: Do you know how difficult it is to type on a train? ;-)
*
- * $Id: ConnectionTest.java,v 1.7 2001/11/19 22:33:39 momjian Exp $
+ * $Id: ConnectionTest.java,v 1.8 2002/07/23 03:59:55 barry Exp $
*/
public class ConnectionTest extends TestCase
@@ -199,13 +199,13 @@ public class ConnectionTest extends TestCase
String testStr = "This Is OuR TeSt message";
// The connection must be ours!
- assertTrue(con instanceof org.postgresql.Connection);
+ assertTrue(con instanceof org.postgresql.PGConnection);
// Clear any existing warnings
con.clearWarnings();
// Set the test warning
- ((org.postgresql.Connection)con).addWarning(testStr);
+ ((org.postgresql.jdbc2.AbstractJdbc2Connection)con).addWarning(testStr);
// Retrieve it
SQLWarning warning = con.getWarnings();
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
index e6acfc0d700..26675a7ca6a 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
@@ -9,7 +9,7 @@ import java.sql.*;
*
* PS: Do you know how difficult it is to type on a train? ;-)
*
- * $Id: DatabaseMetaDataTest.java,v 1.8 2002/06/05 19:12:01 davec Exp $
+ * $Id: DatabaseMetaDataTest.java,v 1.9 2002/07/23 03:59:55 barry Exp $
*/
public class DatabaseMetaDataTest extends TestCase
@@ -163,13 +163,13 @@ public class DatabaseMetaDataTest extends TestCase
// We need to type cast the connection to get access to the
// PostgreSQL-specific method haveMinimumServerVersion().
// This is not available through the java.sql.Connection interface.
- assertTrue( con instanceof org.postgresql.Connection );
+ assertTrue( con instanceof org.postgresql.PGConnection );
assertTrue(!dbmd.nullsAreSortedAtStart());
assertTrue( dbmd.nullsAreSortedAtEnd() !=
- ((org.postgresql.Connection)con).haveMinimumServerVersion("7.2"));
+ ((org.postgresql.jdbc2.AbstractJdbc2Connection)con).haveMinimumServerVersion("7.2"));
assertTrue( dbmd.nullsAreSortedHigh() ==
- ((org.postgresql.Connection)con).haveMinimumServerVersion("7.2"));
+ ((org.postgresql.jdbc2.AbstractJdbc2Connection)con).haveMinimumServerVersion("7.2"));
assertTrue(!dbmd.nullsAreSortedLow());
assertTrue(dbmd.nullPlusNonNullIsNull());
@@ -250,7 +250,7 @@ public class DatabaseMetaDataTest extends TestCase
{
String pkTableName = rs.getString( "PKTABLE_NAME" );
- assertTrue ( pkTableName.equals("people") || pkTableName.equals("policy") );
+ assertTrue ( pkTableName.equals("people") || pkTableName.equals("policy") );
String pkColumnName = rs.getString( "PKCOLUMN_NAME" );
assertTrue( pkColumnName.equals("id") );
@@ -367,14 +367,20 @@ public class DatabaseMetaDataTest extends TestCase
{
try
{
- assertTrue(con instanceof org.postgresql.Connection);
- org.postgresql.Connection pc = (org.postgresql.Connection) con;
+ assertTrue(con instanceof org.postgresql.PGConnection);
+ org.postgresql.jdbc2.AbstractJdbc2Connection pc = (org.postgresql.jdbc2.AbstractJdbc2Connection) con;
DatabaseMetaData dbmd = con.getMetaData();
assertNotNull(dbmd);
assertTrue(dbmd.getDatabaseProductName().equals("PostgreSQL"));
- assertTrue(dbmd.getDatabaseProductVersion().startsWith(Integer.toString(pc.this_driver.getMajorVersion()) + "." + Integer.toString(pc.this_driver.getMinorVersion())));
+ //The test below doesn't make sense to me, it tests that
+ //the version of the driver = the version of the database it is connected to
+ //since the driver should be backwardly compatible this test is commented out
+ //assertTrue(dbmd.getDatabaseProductVersion().startsWith(
+ // Integer.toString(pc.getDriver().getMajorVersion())
+ // + "."
+ // + Integer.toString(pc.getDriver().getMinorVersion())));
assertTrue(dbmd.getDriverName().equals("PostgreSQL Native Driver"));
}
@@ -388,15 +394,15 @@ public class DatabaseMetaDataTest extends TestCase
{
try
{
- assertTrue(con instanceof org.postgresql.Connection);
- org.postgresql.Connection pc = (org.postgresql.Connection) con;
+ assertTrue(con instanceof org.postgresql.PGConnection);
+ org.postgresql.jdbc2.AbstractJdbc2Connection pc = (org.postgresql.jdbc2.AbstractJdbc2Connection) con;
DatabaseMetaData dbmd = con.getMetaData();
assertNotNull(dbmd);
- assertTrue(dbmd.getDriverVersion().equals(pc.this_driver.getVersion()));
- assertTrue(dbmd.getDriverMajorVersion() == pc.this_driver.getMajorVersion());
- assertTrue(dbmd.getDriverMinorVersion() == pc.this_driver.getMinorVersion());
+ assertTrue(dbmd.getDriverVersion().equals(pc.getDriver().getVersion()));
+ assertTrue(dbmd.getDriverMajorVersion() == pc.getDriver().getMajorVersion());
+ assertTrue(dbmd.getDriverMinorVersion() == pc.getDriver().getMinorVersion());
}
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java
index f7bf62e6d60..37eff6c5b75 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java
@@ -5,12 +5,10 @@ import junit.framework.TestCase;
import java.sql.*;
/*
- * $Id: TimestampTest.java,v 1.6 2001/11/19 22:33:39 momjian Exp $
+ * $Id: TimestampTest.java,v 1.7 2002/07/23 03:59:55 barry Exp $
*
- * This has been the most controversial pair of methods since 6.5 was released!
- *
- * From now on, any changes made to either getTimestamp or setTimestamp
- * MUST PASS this TestCase!!!
+ * Test get/setTimestamp for both timestamp with time zone and
+ * timestamp without time zone datatypes
*
*/
public class TimestampTest extends TestCase
@@ -28,39 +26,74 @@ public class TimestampTest extends TestCase
con = JDBC2Tests.openDB();
Statement stmt = con.createStatement();
- JDBC2Tests.createTable(con, "testtimestamp", "ts timestamp");
+ JDBC2Tests.createTable(con, TSWTZ_TABLE, "ts timestamp with time zone");
+ JDBC2Tests.createTable(con, TSWOTZ_TABLE, "ts timestamp without time zone");
}
protected void tearDown() throws Exception
{
- JDBC2Tests.dropTable(con, "testtimestamp");
+ JDBC2Tests.dropTable(con, TSWTZ_TABLE);
+ JDBC2Tests.dropTable(con, TSWOTZ_TABLE);
JDBC2Tests.closeDB(con);
}
/*
- * Tests the time methods in ResultSet
+ * Tests the timestamp methods in ResultSet on timestamp with time zone
+ * we insert a known string value (don't use setTimestamp) then see that
+ * we get back the same value from getTimestamp
*/
- public void testGetTimestamp()
+ public void testGetTimestampWTZ()
{
try
{
Statement stmt = con.createStatement();
- assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testtimestamp",
- "'1950-02-07 15:00:00'")));
+ //Insert the three timestamp values in raw pg format
+ assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWTZ_TABLE,"'" + TS1WTZ_PGFORMAT + "'")));
+ assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWTZ_TABLE,"'" + TS2WTZ_PGFORMAT + "'")));
+ assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWTZ_TABLE,"'" + TS3WTZ_PGFORMAT + "'")));
+
+ // Fall through helper
+ timestampTestWTZ();
+
+ assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWTZ_TABLE));
+
+ stmt.close();
+ }
+ catch (Exception ex)
+ {
+ fail(ex.getMessage());
+ }
+ }
+
+ /*
+ * Tests the timestamp methods in PreparedStatement on timestamp with time zone
+ * we insert a value using setTimestamp then see that
+ * we get back the same value from getTimestamp (which we know works as it was tested
+ * independently of setTimestamp
+ */
+ public void testSetTimestampWTZ()
+ {
+ try
+ {
+ Statement stmt = con.createStatement();
+ PreparedStatement pstmt = con.prepareStatement(JDBC2Tests.insertSQL(TSWTZ_TABLE, "?"));
- assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testtimestamp", "'" +
- getTimestamp(1970, 6, 2, 8, 13, 0, 0).toString() +
- "'")));
+ pstmt.setTimestamp(1, TS1WTZ);
+ assertEquals(1, pstmt.executeUpdate());
- assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testtimestamp",
- "'1970-06-02 08:13:00'")));
+ pstmt.setTimestamp(1, TS2WTZ);
+ assertEquals(1, pstmt.executeUpdate());
+
+ pstmt.setTimestamp(1, TS3WTZ);
+ assertEquals(1, pstmt.executeUpdate());
// Fall through helper
- timestampTest();
+ timestampTestWTZ();
- assertEquals(3, stmt.executeUpdate("DELETE FROM testtimestamp"));
+ assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWTZ_TABLE));
+ pstmt.close();
stmt.close();
}
catch (Exception ex)
@@ -70,28 +103,61 @@ public class TimestampTest extends TestCase
}
/*
- * Tests the time methods in PreparedStatement
+ * Tests the timestamp methods in ResultSet on timestamp without time zone
+ * we insert a known string value (don't use setTimestamp) then see that
+ * we get back the same value from getTimestamp
*/
- public void testSetTimestamp()
+ public void testGetTimestampWOTZ()
{
try
{
Statement stmt = con.createStatement();
- PreparedStatement pstmt = con.prepareStatement(JDBC2Tests.insertSQL("testtimestamp", "?"));
- pstmt.setTimestamp(1, getTimestamp(1950, 2, 7, 15, 0, 0, 0));
- assertEquals(1, pstmt.executeUpdate());
+ //Insert the three timestamp values in raw pg format
+ assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWOTZ_TABLE,"'" + TS1WOTZ_PGFORMAT + "'")));
+ assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWOTZ_TABLE,"'" + TS2WOTZ_PGFORMAT + "'")));
+ assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWOTZ_TABLE,"'" + TS3WOTZ_PGFORMAT + "'")));
+
+ // Fall through helper
+ timestampTestWOTZ();
+
+ assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE));
- pstmt.setTimestamp(1, getTimestamp(1970, 6, 2, 8, 13, 0, 0));
- assertEquals(1, pstmt.executeUpdate());
+ stmt.close();
+ }
+ catch (Exception ex)
+ {
+ fail(ex.getMessage());
+ }
+ }
- pstmt.setTimestamp(1, getTimestamp(1970, 6, 2, 8, 13, 0, 0));
- assertEquals(1, pstmt.executeUpdate());
+
+ /*
+ * Tests the timestamp methods in PreparedStatement on timestamp without time zone
+ * we insert a value using setTimestamp then see that
+ * we get back the same value from getTimestamp (which we know works as it was tested
+ * independently of setTimestamp
+ */
+ public void testSetTimestampWOTZ()
+ {
+ try
+ {
+ Statement stmt = con.createStatement();
+ PreparedStatement pstmt = con.prepareStatement(JDBC2Tests.insertSQL(TSWOTZ_TABLE, "?"));
+
+ pstmt.setTimestamp(1, TS1WOTZ);
+ assertEquals(1, pstmt.executeUpdate());
+
+ pstmt.setTimestamp(1, TS2WOTZ);
+ assertEquals(1, pstmt.executeUpdate());
+
+ pstmt.setTimestamp(1, TS3WOTZ);
+ assertEquals(1, pstmt.executeUpdate());
// Fall through helper
- timestampTest();
+ timestampTestWOTZ();
- assertEquals(3, stmt.executeUpdate("DELETE FROM testtimestamp"));
+ assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE));
pstmt.close();
stmt.close();
@@ -103,31 +169,64 @@ public class TimestampTest extends TestCase
}
/*
- * Helper for the TimeTests. It tests what should be in the db
+ * Helper for the TimestampTests. It tests what should be in the db
+ */
+ private void timestampTestWTZ() throws SQLException
+ {
+ Statement stmt = con.createStatement();
+ ResultSet rs;
+ java.sql.Timestamp t;
+
+ rs = stmt.executeQuery("select ts from " + TSWTZ_TABLE + " order by ts");
+ assertNotNull(rs);
+
+ assertTrue(rs.next());
+ t = rs.getTimestamp(1);
+ assertNotNull(t);
+ assertTrue(t.equals(TS1WTZ));
+
+ assertTrue(rs.next());
+ t = rs.getTimestamp(1);
+ assertNotNull(t);
+ assertTrue(t.equals(TS2WTZ));
+
+ assertTrue(rs.next());
+ t = rs.getTimestamp(1);
+ assertNotNull(t);
+ assertTrue(t.equals(TS3WTZ));
+
+ assertTrue(! rs.next()); // end of table. Fail if more entries exist.
+
+ rs.close();
+ stmt.close();
+ }
+
+ /*
+ * Helper for the TimestampTests. It tests what should be in the db
*/
- private void timestampTest() throws SQLException
+ private void timestampTestWOTZ() throws SQLException
{
Statement stmt = con.createStatement();
ResultSet rs;
java.sql.Timestamp t;
- rs = stmt.executeQuery(JDBC2Tests.selectSQL("testtimestamp", "ts"));
- assertNotNull(rs);
+ rs = stmt.executeQuery("select ts from " + TSWOTZ_TABLE + " order by ts");
+ assertNotNull(rs);
assertTrue(rs.next());
t = rs.getTimestamp(1);
- assertNotNull(t);
- assertTrue(t.equals(getTimestamp(1950, 2, 7, 15, 0, 0, 0)));
+ assertNotNull(t);
+ assertTrue(t.toString().equals(TS1WOTZ_JAVAFORMAT));
assertTrue(rs.next());
t = rs.getTimestamp(1);
- assertNotNull(t);
- assertTrue(t.equals(getTimestamp(1970, 6, 2, 8, 13, 0, 0)));
+ assertNotNull(t);
+ assertTrue(t.toString().equals(TS2WOTZ_JAVAFORMAT));
assertTrue(rs.next());
t = rs.getTimestamp(1);
- assertNotNull(t);
- assertTrue(t.equals(getTimestamp(1970, 6, 2, 8, 13, 0, 0)));
+ assertNotNull(t);
+ assertTrue(t.toString().equals(TS3WOTZ_JAVAFORMAT));
assertTrue(! rs.next()); // end of table. Fail if more entries exist.
@@ -135,14 +234,59 @@ public class TimestampTest extends TestCase
stmt.close();
}
- private java.sql.Timestamp getTimestamp(int y, int m, int d, int h, int mn, int se, int f)
+ private static java.sql.Timestamp getTimestamp(int y, int m, int d, int h, int mn, int se, int f, String tz)
{
- return java.sql.Timestamp.valueOf(JDBC2Tests.fix(y, 4) + "-" +
- JDBC2Tests.fix(m, 2) + "-" +
- JDBC2Tests.fix(d, 2) + " " +
- JDBC2Tests.fix(h, 2) + ":" +
- JDBC2Tests.fix(mn, 2) + ":" +
- JDBC2Tests.fix(se, 2) + "." +
- JDBC2Tests.fix(f, 9));
+ java.sql.Timestamp l_return = null;
+ java.text.DateFormat l_df;
+ try {
+ String l_ts;
+ l_ts = JDBC2Tests.fix(y, 4) + "-" +
+ JDBC2Tests.fix(m, 2) + "-" +
+ JDBC2Tests.fix(d, 2) + " " +
+ JDBC2Tests.fix(h, 2) + ":" +
+ JDBC2Tests.fix(mn, 2) + ":" +
+ JDBC2Tests.fix(se, 2) + " ";
+
+ if (tz == null) {
+ l_df = new java.text.SimpleDateFormat("y-M-d H:m:s");
+ } else {
+ l_ts = l_ts + tz;
+ l_df = new java.text.SimpleDateFormat("y-M-d H:m:s z");
+ }
+ java.util.Date l_date = l_df.parse(l_ts);
+ l_return = new java.sql.Timestamp(l_date.getTime());
+ l_return.setNanos(f);
+ } catch (Exception ex) {
+ fail(ex.getMessage());
+ }
+ return l_return;
}
+
+ private static final java.sql.Timestamp TS1WTZ = getTimestamp(1950, 2, 7, 15, 0, 0, 100000000, "PST");
+ private static final String TS1WTZ_PGFORMAT = "1950-02-07 15:00:00.1-08";
+
+ private static final java.sql.Timestamp TS2WTZ = getTimestamp(2000, 2, 7, 15, 0, 0, 120000000, "GMT");
+ private static final String TS2WTZ_PGFORMAT = "2000-02-07 15:00:00.12+00";
+
+ private static final java.sql.Timestamp TS3WTZ = getTimestamp(2000, 7, 7, 15, 0, 0, 123000000, "GMT");
+ private static final String TS3WTZ_PGFORMAT = "2000-07-07 15:00:00.123+00";
+
+
+ private static final java.sql.Timestamp TS1WOTZ = getTimestamp(1950, 2, 7, 15, 0, 0, 100000000, null);
+ private static final String TS1WOTZ_PGFORMAT = "1950-02-07 15:00:00.1";
+ private static final String TS1WOTZ_JAVAFORMAT = "1950-02-07 15:00:00.1";
+
+ private static final java.sql.Timestamp TS2WOTZ = getTimestamp(2000, 2, 7, 15, 0, 0, 120000000, null);
+ private static final String TS2WOTZ_PGFORMAT = "2000-02-07 15:00:00.12";
+ //there is probably a bug here in that this needs to be .1 instead of .12, but I couldn't find it now
+ private static final String TS2WOTZ_JAVAFORMAT = "2000-02-07 15:00:00.1";
+
+ private static final java.sql.Timestamp TS3WOTZ = getTimestamp(2000, 7, 7, 15, 0, 0, 123000000, null);
+ private static final String TS3WOTZ_PGFORMAT = "2000-07-07 15:00:00.123";
+ //there is probably a bug here in that this needs to be .12 instead of .123, but I couldn't find it now
+ private static final String TS3WOTZ_JAVAFORMAT = "2000-07-07 15:00:00.12";
+
+ private static final String TSWTZ_TABLE = "testtimestampwtz";
+ private static final String TSWOTZ_TABLE = "testtimestampwotz";
+
}
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java
index 722dd78398a..056e68eba05 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java
@@ -28,7 +28,6 @@ public class UpdateableResultTest extends TestCase
Connection con = JDBC2Tests.openDB();
JDBC2Tests.createTable(con, "updateable","id int primary key, name text, notselected text");
JDBC2Tests.createTable(con, "second","id1 int primary key, name1 text");
-
Statement st1 = con.createStatement();
boolean retVal = st1.execute( "insert into updateable ( id, name, notselected ) values (1, 'jake', 'avalue')" );
assert( retVal== false );
@@ -132,4 +131,4 @@ public class UpdateableResultTest extends TestCase
}
-} \ No newline at end of file
+}
diff --git a/src/interfaces/jdbc/org/postgresql/util/Serialize.java b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
index 80d10bc5410..f1f12520baa 100644
--- a/src/interfaces/jdbc/org/postgresql/util/Serialize.java
+++ b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
@@ -109,7 +109,7 @@ import java.sql.*;
public class Serialize
{
// This is the connection that the instance refers to
- protected org.postgresql.Connection conn;
+ protected Connection conn;
// This is the table name
protected String tableName;
@@ -124,7 +124,7 @@ public class Serialize
* This creates an instance that can be used to serialize or deserialize
* a Java object from a PostgreSQL table.
*/
- public Serialize(org.postgresql.Connection c, String type) throws SQLException
+ public Serialize(Connection c, String type) throws SQLException
{
try
{
@@ -142,7 +142,7 @@ public class Serialize
// Second check, the type must be a table
boolean status = false;
- ResultSet rs = conn.ExecSQL("select typname from pg_type,pg_class where typname=relname and typname='" + tableName + "'");
+ ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL("select typname from pg_type,pg_class where typname=relname and typname='" + tableName + "'");
if (rs != null)
{
if (rs.next())
@@ -164,7 +164,7 @@ public class Serialize
/*
* Constructor when Object is passed in
*/
- public Serialize(org.postgresql.Connection c, Object o) throws SQLException
+ public Serialize(Connection c, Object o) throws SQLException
{
this(c, o.getClass().getName());
}
@@ -172,7 +172,7 @@ public class Serialize
/*
* Constructor when Class is passed in
*/
- public Serialize(org.postgresql.Connection c, Class cls) throws SQLException
+ public Serialize(Connection c, Class cls) throws SQLException
{
this(c, cls.getName());
}
@@ -221,7 +221,7 @@ public class Serialize
sb.append(oid);
if (Driver.logDebug) Driver.debug("Serialize.fetch: " + sb.toString());
- ResultSet rs = conn.ExecSQL(sb.toString());
+ ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL(sb.toString());
if (rs != null)
{
@@ -390,7 +390,7 @@ public class Serialize
}
if (Driver.logDebug) Driver.debug("Serialize.store: " + sb.toString() );
- org.postgresql.ResultSet rs = (org.postgresql.ResultSet) conn.ExecSQL(sb.toString());
+ ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL(sb.toString());
// fetch the OID for returning
if (update)
@@ -403,7 +403,7 @@ public class Serialize
else
{
// new record inserted has new oid; rs should be not null
- long newOID = ((org.postgresql.ResultSet)rs).getLastOID();
+ long newOID = ((org.postgresql.jdbc1.AbstractJdbc1ResultSet)rs).getLastOID();
rs.close();
// update the java object's oid field if it has the oid field
if (hasOID)
@@ -472,7 +472,7 @@ public class Serialize
* @param o Object to base table on
* @exception SQLException on error
*/
- public static void create(org.postgresql.Connection con, Object o) throws SQLException
+ public static void create(Connection con, Object o) throws SQLException
{
create(con, o.getClass());
}
@@ -485,7 +485,7 @@ public class Serialize
* @param o Class to base table on
* @exception SQLException on error
*/
- public static void create(org.postgresql.Connection con, Class c) throws SQLException
+ public static void create(Connection con, Class c) throws SQLException
{
if (c.isInterface())
throw new PSQLException("postgresql.serial.interface");
@@ -493,7 +493,7 @@ public class Serialize
// See if the table exists
String tableName = toPostgreSQL(c.getName());
- ResultSet rs = con.ExecSQL("select relname from pg_class where relname = '" + tableName + "'");
+ ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL("select relname from pg_class where relname = '" + tableName + "'");
if ( rs.next() )
{
if (Driver.logDebug) Driver.debug("Serialize.create: table " + tableName + " exists, skipping");
@@ -549,7 +549,7 @@ public class Serialize
// Now create the table
if (Driver.logDebug) Driver.debug("Serialize.create: " + sb );
- con.ExecSQL(sb.toString());
+ ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL(sb.toString());
}
// This is used to translate between Java primitives and PostgreSQL types.