summaryrefslogtreecommitdiff
path: root/src/interfaces/jdbc/org/postgresql/jdbc2
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/jdbc/org/postgresql/jdbc2')
-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
14 files changed, 1265 insertions, 2570 deletions
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 0000000000..8faefad65f
--- /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 0000000000..50c5d942bb
--- /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 0000000000..3d6f6553ce
--- /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 7cc842ec36..2105802d66 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 4aa0348325..9d37bf04bc 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 9ab3cced8e..0000000000
--- 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 3cc224e6e8..77415d051d 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 0000000000..cfbb3486ec
--- /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 0000000000..7200cf549a
--- /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 0000000000..31cec93821
--- /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 5638a2692d..21aba8d9ee 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 f5489f4e97..0000000000
--- 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 a00025ff72..0000000000
--- 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 9ff8be4080..6f6f67d839 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++ )