mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Initial restructuring to add jdbc3 support. There was a significant amount
of duplicated code between the jdbc1 and jdbc2. This checkin restructures the code so that the duplication is removed so that the jdbc3 support can be added without adding yet another copy of everything. Also many classes were renamed to avoid confusion with multiple different objects having the same name. The timestamp tests were also updated to add support for testing timestamp without time zone in addition to timestamp with time zone Modified Files: jdbc/Makefile jdbc/build.xml jdbc/example/ImageViewer.java jdbc/example/basic.java jdbc/example/blobtest.java jdbc/example/threadsafe.java jdbc/org/postgresql/Driver.java.in jdbc/org/postgresql/Field.java jdbc/org/postgresql/core/QueryExecutor.java jdbc/org/postgresql/fastpath/Fastpath.java jdbc/org/postgresql/jdbc1/CallableStatement.java jdbc/org/postgresql/jdbc1/DatabaseMetaData.java jdbc/org/postgresql/jdbc1/PreparedStatement.java jdbc/org/postgresql/jdbc2/Array.java jdbc/org/postgresql/jdbc2/CallableStatement.java jdbc/org/postgresql/jdbc2/DatabaseMetaData.java jdbc/org/postgresql/jdbc2/PreparedStatement.java jdbc/org/postgresql/jdbc2/UpdateableResultSet.java jdbc/org/postgresql/largeobject/LargeObjectManager.java jdbc/org/postgresql/largeobject/PGblob.java jdbc/org/postgresql/largeobject/PGclob.java jdbc/org/postgresql/test/jdbc2/BlobTest.java jdbc/org/postgresql/test/jdbc2/ConnectionTest.java jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java jdbc/org/postgresql/test/jdbc2/TimestampTest.java jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java jdbc/org/postgresql/util/Serialize.java Added Files: jdbc/org/postgresql/PGConnection.java jdbc/org/postgresql/PGStatement.java jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java jdbc/org/postgresql/jdbc1/Jdbc1Connection.java jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java jdbc/org/postgresql/jdbc1/Jdbc1Statement.java jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java jdbc/org/postgresql/jdbc2/Jdbc2Connection.java jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java jdbc/org/postgresql/jdbc2/Jdbc2Statement.java Removed Files: jdbc/org/postgresql/Connection.java jdbc/org/postgresql/ResultSet.java jdbc/org/postgresql/Statement.java jdbc/org/postgresql/jdbc1/Connection.java jdbc/org/postgresql/jdbc1/ResultSet.java jdbc/org/postgresql/jdbc1/Statement.java jdbc/org/postgresql/jdbc2/Connection.java jdbc/org/postgresql/jdbc2/ResultSet.java jdbc/org/postgresql/jdbc2/Statement.java
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,957 @@
|
||||
package org.postgresql.jdbc1;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Vector;
|
||||
import org.postgresql.Field;
|
||||
import org.postgresql.core.Encoding;
|
||||
import org.postgresql.largeobject.*;
|
||||
import org.postgresql.util.PGbytea;
|
||||
import org.postgresql.util.PSQLException;
|
||||
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.1 2002/07/23 03:59:55 barry Exp $
|
||||
* This class defines methods of the jdbc1 specification. This class is
|
||||
* extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2
|
||||
* methods. The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet
|
||||
*/
|
||||
public abstract class AbstractJdbc1ResultSet
|
||||
{
|
||||
|
||||
protected Vector rows; // The results
|
||||
protected Field fields[]; // The field descriptions
|
||||
protected String status; // Status of the result
|
||||
protected boolean binaryCursor = false; // is the data binary or Strings
|
||||
protected int updateCount; // How many rows did we get back?
|
||||
protected long insertOID; // The oid of an inserted row
|
||||
protected int current_row; // Our pointer to where we are at
|
||||
protected byte[][] this_row; // the current row result
|
||||
protected org.postgresql.PGConnection connection; // the connection which we returned from
|
||||
protected SQLWarning warnings = null; // The warning chain
|
||||
protected boolean wasNullFlag = false; // the flag for wasNull()
|
||||
|
||||
// We can chain multiple resultSets together - this points to
|
||||
// next resultSet in the chain.
|
||||
protected ResultSet next = null;
|
||||
|
||||
protected StringBuffer sbuf = null;
|
||||
public byte[][] rowBuffer=null;
|
||||
|
||||
|
||||
public AbstractJdbc1ResultSet(org.postgresql.PGConnection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
|
||||
{
|
||||
this.connection = conn;
|
||||
this.fields = fields;
|
||||
this.rows = tuples;
|
||||
this.status = status;
|
||||
this.updateCount = updateCount;
|
||||
this.insertOID = insertOID;
|
||||
this.this_row = null;
|
||||
this.current_row = -1;
|
||||
this.binaryCursor = binaryCursor;
|
||||
}
|
||||
|
||||
|
||||
public boolean next() throws SQLException
|
||||
{
|
||||
if (rows == null)
|
||||
throw new PSQLException("postgresql.con.closed");
|
||||
|
||||
if (++current_row >= rows.size())
|
||||
return false;
|
||||
|
||||
this_row = (byte [][])rows.elementAt(current_row);
|
||||
|
||||
rowBuffer=new byte[this_row.length][];
|
||||
System.arraycopy(this_row,0,rowBuffer,0,this_row.length);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void close() throws SQLException
|
||||
{
|
||||
//release resources held (memory for tuples)
|
||||
if (rows != null)
|
||||
{
|
||||
rows = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean wasNull() throws SQLException
|
||||
{
|
||||
return wasNullFlag;
|
||||
}
|
||||
|
||||
public String getString(int columnIndex) throws SQLException
|
||||
{
|
||||
checkResultSet( columnIndex );
|
||||
wasNullFlag = (this_row[columnIndex - 1] == null);
|
||||
if (wasNullFlag)
|
||||
return null;
|
||||
|
||||
Encoding encoding = connection.getEncoding();
|
||||
return encoding.decode(this_row[columnIndex - 1]);
|
||||
}
|
||||
|
||||
public boolean getBoolean(int columnIndex) throws SQLException
|
||||
{
|
||||
return toBoolean( getString(columnIndex) );
|
||||
}
|
||||
|
||||
|
||||
public byte getByte(int columnIndex) throws SQLException
|
||||
{
|
||||
String s = getString(columnIndex);
|
||||
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Byte.parseByte(s);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException("postgresql.res.badbyte", s);
|
||||
}
|
||||
}
|
||||
return 0; // SQL NULL
|
||||
}
|
||||
|
||||
public short getShort(int columnIndex) throws SQLException
|
||||
{
|
||||
String s = getFixedString(columnIndex);
|
||||
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Short.parseShort(s);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException("postgresql.res.badshort", s);
|
||||
}
|
||||
}
|
||||
return 0; // SQL NULL
|
||||
}
|
||||
|
||||
public int getInt(int columnIndex) throws SQLException
|
||||
{
|
||||
return toInt( getFixedString(columnIndex) );
|
||||
}
|
||||
|
||||
public long getLong(int columnIndex) throws SQLException
|
||||
{
|
||||
return toLong( getFixedString(columnIndex) );
|
||||
}
|
||||
|
||||
public float getFloat(int columnIndex) throws SQLException
|
||||
{
|
||||
return toFloat( getFixedString(columnIndex) );
|
||||
}
|
||||
|
||||
public double getDouble(int columnIndex) throws SQLException
|
||||
{
|
||||
return toDouble( getFixedString(columnIndex) );
|
||||
}
|
||||
|
||||
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException
|
||||
{
|
||||
return toBigDecimal( getFixedString(columnIndex), scale );
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the value of a column in the current row as a Java byte array.
|
||||
*
|
||||
* <p>In normal use, the bytes represent the raw values returned by the
|
||||
* backend. However, if the column is an OID, then it is assumed to
|
||||
* refer to a Large Object, and that object is returned as a byte array.
|
||||
*
|
||||
* <p><b>Be warned</b> If the large object is huge, then you may run out
|
||||
* of memory.
|
||||
*
|
||||
* @param columnIndex the first column is 1, the second is 2, ...
|
||||
* @return the column value; if the value is SQL NULL, the result
|
||||
* is null
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public byte[] getBytes(int columnIndex) throws SQLException
|
||||
{
|
||||
checkResultSet( columnIndex );
|
||||
wasNullFlag = (this_row[columnIndex - 1] == null);
|
||||
if (!wasNullFlag)
|
||||
{
|
||||
if (binaryCursor)
|
||||
{
|
||||
//If the data is already binary then just return it
|
||||
return this_row[columnIndex - 1];
|
||||
}
|
||||
else if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
|
||||
{
|
||||
//Version 7.2 supports the bytea datatype for byte arrays
|
||||
if (fields[columnIndex - 1].getPGType().equals("bytea"))
|
||||
{
|
||||
return PGbytea.toBytes(this_row[columnIndex - 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this_row[columnIndex - 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Version 7.1 and earlier supports LargeObjects for byte arrays
|
||||
// Handle OID's as BLOBS
|
||||
if ( fields[columnIndex - 1].getOID() == 26)
|
||||
{
|
||||
LargeObjectManager lom = connection.getLargeObjectAPI();
|
||||
LargeObject lob = lom.open(getInt(columnIndex));
|
||||
byte buf[] = lob.read(lob.size());
|
||||
lob.close();
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this_row[columnIndex - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public java.sql.Date getDate(int columnIndex) throws SQLException
|
||||
{
|
||||
return toDate( getString(columnIndex) );
|
||||
}
|
||||
|
||||
public Time getTime(int columnIndex) throws SQLException
|
||||
{
|
||||
return toTime( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex-1].getPGType() );
|
||||
}
|
||||
|
||||
public Timestamp getTimestamp(int columnIndex) throws SQLException
|
||||
{
|
||||
return toTimestamp( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex-1].getPGType() );
|
||||
}
|
||||
|
||||
public InputStream getAsciiStream(int columnIndex) throws SQLException
|
||||
{
|
||||
checkResultSet( columnIndex );
|
||||
wasNullFlag = (this_row[columnIndex - 1] == null);
|
||||
if (wasNullFlag)
|
||||
return null;
|
||||
|
||||
if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
|
||||
{
|
||||
//Version 7.2 supports AsciiStream for all the PG text types
|
||||
//As the spec/javadoc for this method indicate this is to be used for
|
||||
//large text values (i.e. LONGVARCHAR) PG doesn't have a separate
|
||||
//long string datatype, but with toast the text datatype is capable of
|
||||
//handling very large values. Thus the implementation ends up calling
|
||||
//getString() since there is no current way to stream the value from the server
|
||||
try
|
||||
{
|
||||
return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII"));
|
||||
}
|
||||
catch (UnsupportedEncodingException l_uee)
|
||||
{
|
||||
throw new PSQLException("postgresql.unusual", l_uee);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In 7.1 Handle as BLOBS so return the LargeObject input stream
|
||||
return getBinaryStream(columnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getUnicodeStream(int columnIndex) throws SQLException
|
||||
{
|
||||
checkResultSet( columnIndex );
|
||||
wasNullFlag = (this_row[columnIndex - 1] == null);
|
||||
if (wasNullFlag)
|
||||
return null;
|
||||
|
||||
if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
|
||||
{
|
||||
//Version 7.2 supports AsciiStream for all the PG text types
|
||||
//As the spec/javadoc for this method indicate this is to be used for
|
||||
//large text values (i.e. LONGVARCHAR) PG doesn't have a separate
|
||||
//long string datatype, but with toast the text datatype is capable of
|
||||
//handling very large values. Thus the implementation ends up calling
|
||||
//getString() since there is no current way to stream the value from the server
|
||||
try
|
||||
{
|
||||
return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException l_uee)
|
||||
{
|
||||
throw new PSQLException("postgresql.unusual", l_uee);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In 7.1 Handle as BLOBS so return the LargeObject input stream
|
||||
return getBinaryStream(columnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getBinaryStream(int columnIndex) throws SQLException
|
||||
{
|
||||
checkResultSet( columnIndex );
|
||||
wasNullFlag = (this_row[columnIndex - 1] == null);
|
||||
if (wasNullFlag)
|
||||
return null;
|
||||
|
||||
if (((AbstractJdbc1Connection)connection).haveMinimumCompatibleVersion("7.2"))
|
||||
{
|
||||
//Version 7.2 supports BinaryStream for all PG bytea type
|
||||
//As the spec/javadoc for this method indicate this is to be used for
|
||||
//large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
|
||||
//long binary datatype, but with toast the bytea datatype is capable of
|
||||
//handling very large values. Thus the implementation ends up calling
|
||||
//getBytes() since there is no current way to stream the value from the server
|
||||
byte b[] = getBytes(columnIndex);
|
||||
if (b != null)
|
||||
return new ByteArrayInputStream(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
// In 7.1 Handle as BLOBS so return the LargeObject input stream
|
||||
if ( fields[columnIndex - 1].getOID() == 26)
|
||||
{
|
||||
LargeObjectManager lom = connection.getLargeObjectAPI();
|
||||
LargeObject lob = lom.open(getInt(columnIndex));
|
||||
return lob.getInputStream();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getString(String columnName) throws SQLException
|
||||
{
|
||||
return getString(findColumn(columnName));
|
||||
}
|
||||
|
||||
public boolean getBoolean(String columnName) throws SQLException
|
||||
{
|
||||
return getBoolean(findColumn(columnName));
|
||||
}
|
||||
|
||||
public byte getByte(String columnName) throws SQLException
|
||||
{
|
||||
|
||||
return getByte(findColumn(columnName));
|
||||
}
|
||||
|
||||
public short getShort(String columnName) throws SQLException
|
||||
{
|
||||
return getShort(findColumn(columnName));
|
||||
}
|
||||
|
||||
public int getInt(String columnName) throws SQLException
|
||||
{
|
||||
return getInt(findColumn(columnName));
|
||||
}
|
||||
|
||||
public long getLong(String columnName) throws SQLException
|
||||
{
|
||||
return getLong(findColumn(columnName));
|
||||
}
|
||||
|
||||
public float getFloat(String columnName) throws SQLException
|
||||
{
|
||||
return getFloat(findColumn(columnName));
|
||||
}
|
||||
|
||||
public double getDouble(String columnName) throws SQLException
|
||||
{
|
||||
return getDouble(findColumn(columnName));
|
||||
}
|
||||
|
||||
public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException
|
||||
{
|
||||
return getBigDecimal(findColumn(columnName), scale);
|
||||
}
|
||||
|
||||
public byte[] getBytes(String columnName) throws SQLException
|
||||
{
|
||||
return getBytes(findColumn(columnName));
|
||||
}
|
||||
|
||||
public java.sql.Date getDate(String columnName) throws SQLException
|
||||
{
|
||||
return getDate(findColumn(columnName));
|
||||
}
|
||||
|
||||
public Time getTime(String columnName) throws SQLException
|
||||
{
|
||||
return getTime(findColumn(columnName));
|
||||
}
|
||||
|
||||
public Timestamp getTimestamp(String columnName) throws SQLException
|
||||
{
|
||||
return getTimestamp(findColumn(columnName));
|
||||
}
|
||||
|
||||
public InputStream getAsciiStream(String columnName) throws SQLException
|
||||
{
|
||||
return getAsciiStream(findColumn(columnName));
|
||||
}
|
||||
|
||||
public InputStream getUnicodeStream(String columnName) throws SQLException
|
||||
{
|
||||
return getUnicodeStream(findColumn(columnName));
|
||||
}
|
||||
|
||||
public InputStream getBinaryStream(String columnName) throws SQLException
|
||||
{
|
||||
return getBinaryStream(findColumn(columnName));
|
||||
}
|
||||
|
||||
public SQLWarning getWarnings() throws SQLException
|
||||
{
|
||||
return warnings;
|
||||
}
|
||||
|
||||
public void clearWarnings() throws SQLException
|
||||
{
|
||||
warnings = null;
|
||||
}
|
||||
|
||||
public void addWarnings(SQLWarning warnings) {
|
||||
if ( this.warnings != null )
|
||||
this.warnings.setNextWarning(warnings);
|
||||
else
|
||||
this.warnings = warnings;
|
||||
}
|
||||
|
||||
public String getCursorName() throws SQLException
|
||||
{
|
||||
return ((AbstractJdbc1Connection)connection).getCursorName();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the value of a column in the current row as a Java object
|
||||
*
|
||||
* <p>This method will return the value of the given column as a
|
||||
* Java object. The type of the Java object will be the default
|
||||
* Java Object type corresponding to the column's SQL type, following
|
||||
* the mapping specified in the JDBC specification.
|
||||
*
|
||||
* <p>This method may also be used to read database specific abstract
|
||||
* data types.
|
||||
*
|
||||
* @param columnIndex the first column is 1, the second is 2...
|
||||
* @return a Object holding the column value
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public Object getObject(int columnIndex) throws SQLException
|
||||
{
|
||||
Field field;
|
||||
|
||||
if (columnIndex < 1 || columnIndex > fields.length)
|
||||
throw new PSQLException("postgresql.res.colrange");
|
||||
field = fields[columnIndex - 1];
|
||||
|
||||
// some fields can be null, mainly from those returned by MetaData methods
|
||||
if (field == null)
|
||||
{
|
||||
wasNullFlag = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (field.getSQLType())
|
||||
{
|
||||
case Types.BIT:
|
||||
return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE;
|
||||
case Types.SMALLINT:
|
||||
return new Short(getShort(columnIndex));
|
||||
case Types.INTEGER:
|
||||
return new Integer(getInt(columnIndex));
|
||||
case Types.BIGINT:
|
||||
return new Long(getLong(columnIndex));
|
||||
case Types.NUMERIC:
|
||||
return getBigDecimal
|
||||
(columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff));
|
||||
case Types.REAL:
|
||||
return new Float(getFloat(columnIndex));
|
||||
case Types.DOUBLE:
|
||||
return new Double(getDouble(columnIndex));
|
||||
case Types.CHAR:
|
||||
case Types.VARCHAR:
|
||||
return getString(columnIndex);
|
||||
case Types.DATE:
|
||||
return getDate(columnIndex);
|
||||
case Types.TIME:
|
||||
return getTime(columnIndex);
|
||||
case Types.TIMESTAMP:
|
||||
return getTimestamp(columnIndex);
|
||||
case Types.BINARY:
|
||||
case Types.VARBINARY:
|
||||
return getBytes(columnIndex);
|
||||
default:
|
||||
String type = field.getPGType();
|
||||
// if the backend doesn't know the type then coerce to String
|
||||
if (type.equals("unknown"))
|
||||
{
|
||||
return getString(columnIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return connection.getObject(field.getPGType(), getString(columnIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object getObject(String columnName) throws SQLException
|
||||
{
|
||||
return getObject(findColumn(columnName));
|
||||
}
|
||||
|
||||
/*
|
||||
* Map a ResultSet column name to a ResultSet column index
|
||||
*/
|
||||
public int findColumn(String columnName) throws SQLException
|
||||
{
|
||||
int i;
|
||||
|
||||
final int flen = fields.length;
|
||||
for (i = 0 ; i < flen; ++i)
|
||||
if (fields[i].getName().equalsIgnoreCase(columnName))
|
||||
return (i + 1);
|
||||
throw new PSQLException ("postgresql.res.colname", columnName);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We at times need to know if the resultSet we are working
|
||||
* with is the result of an UPDATE, DELETE or INSERT (in which
|
||||
* case, we only have a row count), or of a SELECT operation
|
||||
* (in which case, we have multiple fields) - this routine
|
||||
* tells us.
|
||||
*/
|
||||
public boolean reallyResultSet()
|
||||
{
|
||||
return (fields != null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since ResultSets can be chained, we need some method of
|
||||
* finding the next one in the chain. The method getNext()
|
||||
* returns the next one in the chain.
|
||||
*
|
||||
* @return the next ResultSet, or null if there are none
|
||||
*/
|
||||
public java.sql.ResultSet getNext()
|
||||
{
|
||||
return (java.sql.ResultSet)next;
|
||||
}
|
||||
|
||||
/*
|
||||
* This following method allows us to add a ResultSet object
|
||||
* to the end of the current chain.
|
||||
*/
|
||||
public void append(AbstractJdbc1ResultSet r)
|
||||
{
|
||||
if (next == null)
|
||||
next = (java.sql.ResultSet)r;
|
||||
else
|
||||
((AbstractJdbc1ResultSet)next).append(r);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are just a place holder for results, we still need
|
||||
* to get an updateCount. This method returns it.
|
||||
*/
|
||||
public int getResultCount()
|
||||
{
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* We also need to provide a couple of auxiliary functions for
|
||||
* the implementation of the ResultMetaData functions. In
|
||||
* particular, we need to know the number of rows and the
|
||||
* number of columns. Rows are also known as Tuples
|
||||
*/
|
||||
public int getTupleCount()
|
||||
{
|
||||
return rows.size();
|
||||
}
|
||||
|
||||
/*
|
||||
* getColumnCount returns the number of columns
|
||||
*/
|
||||
public int getColumnCount()
|
||||
{
|
||||
return fields.length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the status message from the backend.<p>
|
||||
* It is used internally by the driver.
|
||||
*/
|
||||
public String getStatusString()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the OID of a field.<p>
|
||||
* It is used internally by the driver.
|
||||
*/
|
||||
public int getColumnOID(int field)
|
||||
{
|
||||
return fields[field -1].getOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the OID of the last inserted row. Deprecated in 7.2 because
|
||||
* range for OID values is greater than java signed int.
|
||||
* @deprecated Replaced by getLastOID() in 7.2
|
||||
*/
|
||||
public int getInsertedOID()
|
||||
{
|
||||
return (int) getLastOID();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns the OID of the last inserted row
|
||||
* @since 7.2
|
||||
*/
|
||||
public long getLastOID()
|
||||
{
|
||||
return insertOID;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used to fix get*() methods on Money fields. It should only be
|
||||
* used by those methods!
|
||||
*
|
||||
* It converts ($##.##) to -##.## and $##.## to ##.##
|
||||
*/
|
||||
public String getFixedString(int col) throws SQLException
|
||||
{
|
||||
String s = getString(col);
|
||||
|
||||
// Handle SQL Null
|
||||
wasNullFlag = (this_row[col - 1] == null);
|
||||
if (wasNullFlag)
|
||||
return null;
|
||||
|
||||
// Handle Money
|
||||
if (s.charAt(0) == '(')
|
||||
{
|
||||
s = "-" + org.postgresql.util.PGtokenizer.removePara(s).substring(1);
|
||||
}
|
||||
if (s.charAt(0) == '$')
|
||||
{
|
||||
s = s.substring(1);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
protected void checkResultSet( int column ) throws SQLException
|
||||
{
|
||||
if ( this_row == null ) throw new PSQLException("postgresql.res.nextrequired");
|
||||
if ( column < 1 || column > fields.length ) throw new PSQLException("postgresql.res.colrange" );
|
||||
}
|
||||
|
||||
//----------------- Formatting Methods -------------------
|
||||
|
||||
public static boolean toBoolean(String s)
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
int c = s.charAt(0);
|
||||
return ((c == 't') || (c == 'T') || (c == '1'));
|
||||
}
|
||||
return false; // SQL NULL
|
||||
}
|
||||
|
||||
public static int toInt(String s) throws SQLException
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException ("postgresql.res.badint", s);
|
||||
}
|
||||
}
|
||||
return 0; // SQL NULL
|
||||
}
|
||||
|
||||
public static long toLong(String s) throws SQLException
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Long.parseLong(s);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException ("postgresql.res.badlong", s);
|
||||
}
|
||||
}
|
||||
return 0; // SQL NULL
|
||||
}
|
||||
|
||||
public static BigDecimal toBigDecimal(String s, int scale) throws SQLException
|
||||
{
|
||||
BigDecimal val;
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
val = new BigDecimal(s);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException ("postgresql.res.badbigdec", s);
|
||||
}
|
||||
if (scale == -1)
|
||||
return val;
|
||||
try
|
||||
{
|
||||
return val.setScale(scale);
|
||||
}
|
||||
catch (ArithmeticException e)
|
||||
{
|
||||
throw new PSQLException ("postgresql.res.badbigdec", s);
|
||||
}
|
||||
}
|
||||
return null; // SQL NULL
|
||||
}
|
||||
|
||||
public static float toFloat(String s) throws SQLException
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Float.valueOf(s).floatValue();
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException ("postgresql.res.badfloat", s);
|
||||
}
|
||||
}
|
||||
return 0; // SQL NULL
|
||||
}
|
||||
|
||||
public static double toDouble(String s) throws SQLException
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Double.valueOf(s).doubleValue();
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException ("postgresql.res.baddouble", s);
|
||||
}
|
||||
}
|
||||
return 0; // SQL NULL
|
||||
}
|
||||
|
||||
public static java.sql.Date toDate(String s) throws SQLException
|
||||
{
|
||||
if (s == null)
|
||||
return null;
|
||||
// length == 10: SQL Date
|
||||
// length > 10: SQL Timestamp, assumes PGDATESTYLE=ISO
|
||||
try
|
||||
{
|
||||
return java.sql.Date.valueOf((s.length() == 10) ? s : s.substring(0, 10));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException("postgresql.res.baddate", s);
|
||||
}
|
||||
}
|
||||
|
||||
public static Time toTime(String s, java.sql.ResultSet resultSet, String pgDataType) throws SQLException
|
||||
{
|
||||
if (s == null)
|
||||
return null; // SQL NULL
|
||||
try
|
||||
{
|
||||
if (s.length() == 8) {
|
||||
//value is a time value
|
||||
return java.sql.Time.valueOf(s);
|
||||
} else if (s.indexOf(".") == 8) {
|
||||
//value is a time value with fractional seconds
|
||||
java.sql.Time l_time = java.sql.Time.valueOf(s.substring(0,8));
|
||||
String l_strMillis = s.substring(9);
|
||||
if (l_strMillis.length() > 3)
|
||||
l_strMillis = l_strMillis.substring(0,3);
|
||||
int l_millis = Integer.parseInt(l_strMillis);
|
||||
if (l_millis < 10) {
|
||||
l_millis = l_millis * 100;
|
||||
} else if (l_millis < 100) {
|
||||
l_millis = l_millis * 10;
|
||||
}
|
||||
return new java.sql.Time(l_time.getTime() + l_millis);
|
||||
} else {
|
||||
//value is a timestamp
|
||||
return new java.sql.Time(toTimestamp(s, resultSet, pgDataType).getTime());
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new PSQLException("postgresql.res.badtime", s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and return a timestamp representing its value.
|
||||
*
|
||||
* The driver is set to return ISO date formated strings. We modify this
|
||||
* string from the ISO format to a format that Java can understand. Java
|
||||
* expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
|
||||
* Java also expects fractional seconds to 3 places where postgres
|
||||
* will give, none, 2 or 6 depending on the time and postgres version.
|
||||
* From version 7.2 postgres returns fractional seconds to 6 places.
|
||||
* If available, we drop the last 3 digits.
|
||||
*
|
||||
* @param s The ISO formated date string to parse.
|
||||
* @param resultSet The ResultSet this date is part of.
|
||||
*
|
||||
* @return null if s is null or a timestamp of the parsed string s.
|
||||
*
|
||||
* @throws SQLException if there is a problem parsing s.
|
||||
**/
|
||||
public static Timestamp toTimestamp(String s, java.sql.ResultSet resultSet, String pgDataType)
|
||||
throws SQLException
|
||||
{
|
||||
AbstractJdbc1ResultSet rs = (AbstractJdbc1ResultSet)resultSet;
|
||||
if (s == null)
|
||||
return null;
|
||||
|
||||
// We must be synchronized here incase more theads access the ResultSet
|
||||
// bad practice but possible. Anyhow this is to protect sbuf and
|
||||
// SimpleDateFormat objects
|
||||
synchronized (rs)
|
||||
{
|
||||
SimpleDateFormat df = null;
|
||||
if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug("the data from the DB is "+s);
|
||||
|
||||
// If first time, create the buffer, otherwise clear it.
|
||||
if (rs.sbuf == null)
|
||||
rs.sbuf = new StringBuffer();
|
||||
else
|
||||
rs.sbuf.setLength(0);
|
||||
|
||||
// Copy s into sbuf for parsing.
|
||||
rs.sbuf.append(s);
|
||||
int slen = s.length();
|
||||
|
||||
if (slen > 19)
|
||||
{
|
||||
// The len of the ISO string to the second value is 19 chars. If
|
||||
// greater then 19, there may be tz info and perhaps fractional
|
||||
// second info which we need to change to java to read it.
|
||||
|
||||
// cut the copy to second value "2001-12-07 16:29:22"
|
||||
int i = 19;
|
||||
rs.sbuf.setLength(i);
|
||||
|
||||
char c = s.charAt(i++);
|
||||
if (c == '.')
|
||||
{
|
||||
// Found a fractional value. Append up to 3 digits including
|
||||
// the leading '.'
|
||||
do
|
||||
{
|
||||
if (i < 24)
|
||||
rs.sbuf.append(c);
|
||||
c = s.charAt(i++);
|
||||
} while (i < slen && Character.isDigit(c));
|
||||
|
||||
// If there wasn't at least 3 digits we should add some zeros
|
||||
// to make up the 3 digits we tell java to expect.
|
||||
for (int j = i; j < 24; j++)
|
||||
rs.sbuf.append('0');
|
||||
}
|
||||
else
|
||||
{
|
||||
// No fractional seconds, lets add some.
|
||||
rs.sbuf.append(".000");
|
||||
}
|
||||
|
||||
if (i < slen)
|
||||
{
|
||||
// prepend the GMT part and then add the remaining bit of
|
||||
// the string.
|
||||
rs.sbuf.append(" GMT");
|
||||
rs.sbuf.append(c);
|
||||
rs.sbuf.append(s.substring(i, slen));
|
||||
|
||||
// Lastly, if the tz part doesn't specify the :MM part then
|
||||
// we add ":00" for java.
|
||||
if (slen - i < 5)
|
||||
rs.sbuf.append(":00");
|
||||
|
||||
// we'll use this dateformat string to parse the result.
|
||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just found fractional seconds but no timezone.
|
||||
//If timestamptz then we use GMT, else local timezone
|
||||
if (pgDataType.equals("timestamptz")) {
|
||||
rs.sbuf.append(" GMT");
|
||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
|
||||
} else {
|
||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (slen == 19)
|
||||
{
|
||||
// No tz or fractional second info.
|
||||
//If timestamptz then we use GMT, else local timezone
|
||||
if (pgDataType.equals("timestamptz")) {
|
||||
rs.sbuf.append(" GMT");
|
||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||
} else {
|
||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We must just have a date. This case is
|
||||
// needed if this method is called on a date
|
||||
// column
|
||||
df = new SimpleDateFormat("yyyy-MM-dd");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// All that's left is to parse the string and return the ts.
|
||||
if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug( "" + df.parse(rs.sbuf.toString()).getTime() );
|
||||
|
||||
return new Timestamp(df.parse(rs.sbuf.toString()).getTime());
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new PSQLException("postgresql.res.badtimestamp", new Integer(e.getErrorOffset()), s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,471 @@
|
||||
package org.postgresql.jdbc1;
|
||||
|
||||
import java.sql.*;
|
||||
import org.postgresql.util.PSQLException;
|
||||
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.1 2002/07/23 03:59:55 barry Exp $
|
||||
* This class defines methods of the jdbc1 specification. This class is
|
||||
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
|
||||
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
|
||||
*/
|
||||
public abstract class AbstractJdbc1Statement implements org.postgresql.PGStatement
|
||||
{
|
||||
|
||||
// The connection who created us
|
||||
protected AbstractJdbc1Connection connection;
|
||||
|
||||
/** The warnings chain. */
|
||||
protected SQLWarning warnings = null;
|
||||
|
||||
/** Maximum number of rows to return, 0 = unlimited */
|
||||
protected int maxrows = 0;
|
||||
|
||||
/** Timeout (in seconds) for a query (not used) */
|
||||
protected int timeout = 0;
|
||||
|
||||
protected boolean escapeProcessing = true;
|
||||
|
||||
/** The current results */
|
||||
protected java.sql.ResultSet result = null;
|
||||
|
||||
// Static variables for parsing SQL when escapeProcessing is true.
|
||||
private static final short IN_SQLCODE = 0;
|
||||
private static final short IN_STRING = 1;
|
||||
private static final short BACKSLASH = 2;
|
||||
private static final short ESC_TIMEDATE = 3;
|
||||
|
||||
/*
|
||||
* Execute a SQL statement that retruns a single ResultSet
|
||||
*
|
||||
* @param sql typically a static SQL SELECT statement
|
||||
* @return a ResulSet that contains the data produced by the query
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public java.sql.ResultSet executeQuery(String sql) throws SQLException
|
||||
{
|
||||
this.execute(sql);
|
||||
while (result != null && !((AbstractJdbc1ResultSet)result).reallyResultSet())
|
||||
result = ((AbstractJdbc1ResultSet)result).getNext();
|
||||
if (result == null)
|
||||
throw new PSQLException("postgresql.stat.noresult");
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition
|
||||
* SQL statements that return nothing such as SQL DDL statements
|
||||
* can be executed
|
||||
*
|
||||
* @param sql a SQL statement
|
||||
* @return either a row count, or 0 for SQL commands
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public int executeUpdate(String sql) throws SQLException
|
||||
{
|
||||
this.execute(sql);
|
||||
if (((AbstractJdbc1ResultSet)result).reallyResultSet())
|
||||
throw new PSQLException("postgresql.stat.result");
|
||||
return this.getUpdateCount();
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a SQL statement that may return multiple results. We
|
||||
* don't have to worry about this since we do not support multiple
|
||||
* ResultSets. You can use getResultSet or getUpdateCount to
|
||||
* retrieve the result.
|
||||
*
|
||||
* @param sql any SQL statement
|
||||
* @return true if the next result is a ResulSet, false if it is
|
||||
* an update count or there are no more results
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public boolean execute(String sql) throws SQLException
|
||||
{
|
||||
if (escapeProcessing)
|
||||
sql = escapeSQL(sql);
|
||||
|
||||
// New in 7.1, if we have a previous resultset then force it to close
|
||||
// This brings us nearer to compliance, and helps memory management.
|
||||
// Internal stuff will call ExecSQL directly, bypassing this.
|
||||
if (result != null)
|
||||
{
|
||||
java.sql.ResultSet rs = getResultSet();
|
||||
if (rs != null)
|
||||
rs.close();
|
||||
}
|
||||
|
||||
|
||||
// New in 7.1, pass Statement so that ExecSQL can customise to it
|
||||
result = ((AbstractJdbc1Connection)connection).ExecSQL(sql, (java.sql.Statement)this);
|
||||
|
||||
return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet());
|
||||
}
|
||||
|
||||
/*
|
||||
* setCursorName defines the SQL cursor name that will be used by
|
||||
* subsequent execute methods. This name can then be used in SQL
|
||||
* positioned update/delete statements to identify the current row
|
||||
* in the ResultSet generated by this statement. If a database
|
||||
* doesn't support positioned update/delete, this method is a
|
||||
* no-op.
|
||||
*
|
||||
* <p><B>Note:</B> By definition, positioned update/delete execution
|
||||
* must be done by a different Statement than the one which
|
||||
* generated the ResultSet being used for positioning. Also, cursor
|
||||
* names must be unique within a Connection.
|
||||
*
|
||||
* <p>We throw an additional constriction. There can only be one
|
||||
* cursor active at any one time.
|
||||
*
|
||||
* @param name the new cursor name
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public void setCursorName(String name) throws SQLException
|
||||
{
|
||||
((AbstractJdbc1Connection)connection).setCursorName(name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getUpdateCount returns the current result as an update count,
|
||||
* if the result is a ResultSet or there are no more results, -1
|
||||
* is returned. It should only be called once per result.
|
||||
*
|
||||
* @return the current result as an update count.
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public int getUpdateCount() throws SQLException
|
||||
{
|
||||
if (result == null)
|
||||
return -1;
|
||||
if (((AbstractJdbc1ResultSet)result).reallyResultSet())
|
||||
return -1;
|
||||
return ((AbstractJdbc1ResultSet)result).getResultCount();
|
||||
}
|
||||
|
||||
/*
|
||||
* getMoreResults moves to a Statement's next result. If it returns
|
||||
* true, this result is a ResulSet.
|
||||
*
|
||||
* @return true if the next ResultSet is valid
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public boolean getMoreResults() throws SQLException
|
||||
{
|
||||
result = ((AbstractJdbc1ResultSet)result).getNext();
|
||||
return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Returns the status message from the current Result.<p>
|
||||
* This is used internally by the driver.
|
||||
*
|
||||
* @return status message from backend
|
||||
*/
|
||||
public String getResultStatusString()
|
||||
{
|
||||
if (result == null)
|
||||
return null;
|
||||
return ((AbstractJdbc1ResultSet)result).getStatusString();
|
||||
}
|
||||
|
||||
/*
|
||||
* The maxRows limit is set to limit the number of rows that
|
||||
* any ResultSet can contain. If the limit is exceeded, the
|
||||
* excess rows are silently dropped.
|
||||
*
|
||||
* @return the current maximum row limit; zero means unlimited
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public int getMaxRows() throws SQLException
|
||||
{
|
||||
return maxrows;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the maximum number of rows
|
||||
*
|
||||
* @param max the new max rows limit; zero means unlimited
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @see getMaxRows
|
||||
*/
|
||||
public void setMaxRows(int max) throws SQLException
|
||||
{
|
||||
maxrows = max;
|
||||
}
|
||||
|
||||
/*
|
||||
* If escape scanning is on (the default), the driver will do escape
|
||||
* substitution before sending the SQL to the database.
|
||||
*
|
||||
* @param enable true to enable; false to disable
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public void setEscapeProcessing(boolean enable) throws SQLException
|
||||
{
|
||||
escapeProcessing = enable;
|
||||
}
|
||||
|
||||
/*
|
||||
* The queryTimeout limit is the number of seconds the driver
|
||||
* will wait for a Statement to execute. If the limit is
|
||||
* exceeded, a SQLException is thrown.
|
||||
*
|
||||
* @return the current query timeout limit in seconds; 0 = unlimited
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public int getQueryTimeout() throws SQLException
|
||||
{
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the queryTimeout limit
|
||||
*
|
||||
* @param seconds - the new query timeout limit in seconds
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public void setQueryTimeout(int seconds) throws SQLException
|
||||
{
|
||||
timeout = seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a warning to the warning chain.
|
||||
* @param msg message to add
|
||||
*/
|
||||
public void addWarning(String msg)
|
||||
{
|
||||
if (warnings != null)
|
||||
warnings.setNextWarning(new SQLWarning(msg));
|
||||
else
|
||||
warnings = new SQLWarning(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* The first warning reported by calls on this Statement is
|
||||
* returned. A Statement's execute methods clear its SQLWarning
|
||||
* chain. Subsequent Statement warnings will be chained to this
|
||||
* SQLWarning.
|
||||
*
|
||||
* <p>The Warning chain is automatically cleared each time a statement
|
||||
* is (re)executed.
|
||||
*
|
||||
* <p><B>Note:</B> If you are processing a ResultSet then any warnings
|
||||
* associated with ResultSet reads will be chained on the ResultSet
|
||||
* object.
|
||||
*
|
||||
* @return the first SQLWarning on null
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public SQLWarning getWarnings() throws SQLException
|
||||
{
|
||||
return warnings;
|
||||
}
|
||||
|
||||
/*
|
||||
* The maxFieldSize limit (in bytes) is the maximum amount of
|
||||
* data returned for any column value; it only applies to
|
||||
* BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR
|
||||
* columns. If the limit is exceeded, the excess data is silently
|
||||
* discarded.
|
||||
*
|
||||
* @return the current max column size limit; zero means unlimited
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public int getMaxFieldSize() throws SQLException
|
||||
{
|
||||
return 8192; // We cannot change this
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the maxFieldSize - NOT! - We throw an SQLException just
|
||||
* to inform them to stop doing this.
|
||||
*
|
||||
* @param max the new max column size limit; zero means unlimited
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public void setMaxFieldSize(int max) throws SQLException
|
||||
{
|
||||
throw new PSQLException("postgresql.stat.maxfieldsize");
|
||||
}
|
||||
|
||||
/*
|
||||
* After this call, getWarnings returns null until a new warning
|
||||
* is reported for this Statement.
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public void clearWarnings() throws SQLException
|
||||
{
|
||||
warnings = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel can be used by one thread to cancel a statement that
|
||||
* is being executed by another thread.
|
||||
* <p>
|
||||
* Not implemented, this method is a no-op.
|
||||
*
|
||||
* @exception SQLException only because thats the spec.
|
||||
*/
|
||||
public void cancel() throws SQLException
|
||||
{
|
||||
throw new PSQLException("postgresql.unimplemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* getResultSet returns the current result as a ResultSet. It
|
||||
* should only be called once per result.
|
||||
*
|
||||
* @return the current result set; null if there are no more
|
||||
* @exception SQLException if a database access error occurs (why?)
|
||||
*/
|
||||
public java.sql.ResultSet getResultSet() throws SQLException
|
||||
{
|
||||
if (result != null && ((AbstractJdbc1ResultSet) result).reallyResultSet())
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* In many cases, it is desirable to immediately release a
|
||||
* Statement's 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 Statement is automatically closed when it is
|
||||
* garbage collected. When a Statement is closed, its current
|
||||
* ResultSet, if one exists, is also closed.
|
||||
*
|
||||
* @exception SQLException if a database access error occurs (why?)
|
||||
*/
|
||||
public void close() throws SQLException
|
||||
{
|
||||
// Force the ResultSet to close
|
||||
java.sql.ResultSet rs = getResultSet();
|
||||
if (rs != null)
|
||||
rs.close();
|
||||
|
||||
// Disasociate it from us (For Garbage Collection)
|
||||
result = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Filter the SQL string of Java SQL Escape clauses.
|
||||
*
|
||||
* Currently implemented Escape clauses are those mentioned in 11.3
|
||||
* in the specification. Basically we look through the sql string for
|
||||
* {d xxx}, {t xxx} or {ts xxx} in non-string sql code. When we find
|
||||
* them, we just strip the escape part leaving only the xxx part.
|
||||
* So, something like "select * from x where d={d '2001-10-09'}" would
|
||||
* return "select * from x where d= '2001-10-09'".
|
||||
*/
|
||||
protected static String escapeSQL(String sql)
|
||||
{
|
||||
// Since escape codes can only appear in SQL CODE, we keep track
|
||||
// of if we enter a string or not.
|
||||
StringBuffer newsql = new StringBuffer();
|
||||
short state = IN_SQLCODE;
|
||||
|
||||
int i = -1;
|
||||
int len = sql.length();
|
||||
while (++i < len)
|
||||
{
|
||||
char c = sql.charAt(i);
|
||||
switch (state)
|
||||
{
|
||||
case IN_SQLCODE:
|
||||
if (c == '\'') // start of a string?
|
||||
state = IN_STRING;
|
||||
else if (c == '{') // start of an escape code?
|
||||
if (i + 1 < len)
|
||||
{
|
||||
char next = sql.charAt(i + 1);
|
||||
if (next == 'd')
|
||||
{
|
||||
state = ESC_TIMEDATE;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
else if (next == 't')
|
||||
{
|
||||
state = ESC_TIMEDATE;
|
||||
i += (i + 2 < len && sql.charAt(i + 2) == 's') ? 2 : 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newsql.append(c);
|
||||
break;
|
||||
|
||||
case IN_STRING:
|
||||
if (c == '\'') // end of string?
|
||||
state = IN_SQLCODE;
|
||||
else if (c == '\\') // a backslash?
|
||||
state = BACKSLASH;
|
||||
|
||||
newsql.append(c);
|
||||
break;
|
||||
|
||||
case BACKSLASH:
|
||||
state = IN_STRING;
|
||||
|
||||
newsql.append(c);
|
||||
break;
|
||||
|
||||
case ESC_TIMEDATE:
|
||||
if (c == '}')
|
||||
state = IN_SQLCODE; // end of escape code.
|
||||
else
|
||||
newsql.append(c);
|
||||
break;
|
||||
} // end switch
|
||||
}
|
||||
|
||||
return newsql.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* The following methods are postgres extensions and are defined
|
||||
* in the interface org.postgresql.Statement
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns the Last inserted/updated oid. Deprecated in 7.2 because
|
||||
* range of OID values is greater than a java signed int.
|
||||
* @deprecated Replaced by getLastOID in 7.2
|
||||
*/
|
||||
public int getInsertedOID() throws SQLException
|
||||
{
|
||||
if (result == null)
|
||||
return 0;
|
||||
return (int)((AbstractJdbc1ResultSet)result).getLastOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the Last inserted/updated oid.
|
||||
* @return OID of last insert
|
||||
* @since 7.2
|
||||
*/
|
||||
public long getLastOID() throws SQLException
|
||||
{
|
||||
if (result == null)
|
||||
return 0;
|
||||
return ((AbstractJdbc1ResultSet)result).getLastOID();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -44,7 +44,7 @@ public class CallableStatement extends PreparedStatement implements java.sql.Cal
|
||||
/*
|
||||
* @exception SQLException on failure
|
||||
*/
|
||||
CallableStatement(Connection c, String q) throws SQLException
|
||||
CallableStatement(Jdbc1Connection c, String q) throws SQLException
|
||||
{
|
||||
super(c, q);
|
||||
}
|
||||
|
@ -1,214 +0,0 @@
|
||||
package org.postgresql.jdbc1;
|
||||
|
||||
// IMPORTANT NOTE: This file implements the JDBC 1 version of the driver.
|
||||
// If you make any modifications to this file, you must make sure that the
|
||||
// changes are also made (if relevent) to the related JDBC 2 class in the
|
||||
// org.postgresql.jdbc2 package.
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.sql.*;
|
||||
import org.postgresql.Field;
|
||||
import org.postgresql.fastpath.*;
|
||||
import org.postgresql.largeobject.*;
|
||||
import org.postgresql.util.*;
|
||||
|
||||
/*
|
||||
* $Id: Connection.java,v 1.15 2002/01/15 06:55:13 barry Exp $
|
||||
*
|
||||
* A Connection represents a session with a specific database. Within the
|
||||
* context of a Connection, SQL statements are executed and results are
|
||||
* returned.
|
||||
*
|
||||
* <P>A Connection's database is able to provide information describing
|
||||
* its tables, its supported SQL grammar, its stored procedures, the
|
||||
* capabilities of this connection, etc. This information is obtained
|
||||
* with the getMetaData method.
|
||||
*
|
||||
* <p><B>Note:</B> By default, the Connection automatically commits changes
|
||||
* after executing each statement. If auto-commit has been disabled, an
|
||||
* explicit commit must be done or database changes will not be saved.
|
||||
*
|
||||
* @see java.sql.Connection
|
||||
*/
|
||||
public class Connection extends org.postgresql.Connection implements java.sql.Connection
|
||||
{
|
||||
// This is a cache of the DatabaseMetaData instance for this connection
|
||||
protected DatabaseMetaData metadata;
|
||||
|
||||
/*
|
||||
* SQL statements without parameters are normally executed using
|
||||
* Statement objects. If the same SQL statement is executed many
|
||||
* times, it is more efficient to use a PreparedStatement
|
||||
*
|
||||
* @return a new Statement object
|
||||
* @exception SQLException passed through from the constructor
|
||||
*/
|
||||
public java.sql.Statement createStatement() throws SQLException
|
||||
{
|
||||
return new Statement(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* A SQL statement with or without IN parameters can be pre-compiled
|
||||
* and stored in a PreparedStatement object. This object can then
|
||||
* be used to efficiently execute this statement multiple times.
|
||||
*
|
||||
* <B>Note:</B> This method is optimized for handling parametric
|
||||
* SQL statements that benefit from precompilation if the drivers
|
||||
* supports precompilation. PostgreSQL does not support precompilation.
|
||||
* In this case, the statement is not sent to the database until the
|
||||
* PreparedStatement is executed. This has no direct effect on users;
|
||||
* however it does affect which method throws certain SQLExceptions
|
||||
*
|
||||
* @param sql a SQL statement that may contain one or more '?' IN
|
||||
* parameter placeholders
|
||||
* @return a new PreparedStatement object containing the pre-compiled
|
||||
* statement.
|
||||
* @exception SQLException if a database access error occurs.
|
||||
*/
|
||||
public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
|
||||
{
|
||||
return new PreparedStatement(this, sql);
|
||||
}
|
||||
|
||||
/*
|
||||
* A SQL stored procedure call statement is handled by creating a
|
||||
* CallableStatement for it. The CallableStatement provides methods
|
||||
* for setting up its IN and OUT parameters and methods for executing
|
||||
* it.
|
||||
*
|
||||
* <B>Note:</B> This method is optimised for handling stored procedure
|
||||
* call statements. Some drivers may send the call statement to the
|
||||
* database when the prepareCall is done; others may wait until the
|
||||
* CallableStatement is executed. This has no direct effect on users;
|
||||
* however, it does affect which method throws certain SQLExceptions
|
||||
*
|
||||
* @param sql a SQL statement that may contain one or more '?' parameter
|
||||
* placeholders. Typically this statement is a JDBC function call
|
||||
* escape string.
|
||||
* @return a new CallableStatement object containing the pre-compiled
|
||||
* SQL statement
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public java.sql.CallableStatement prepareCall(String sql) throws SQLException
|
||||
{
|
||||
throw new PSQLException("postgresql.con.call");
|
||||
// return new CallableStatement(this, sql);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests to see if a Connection is closed
|
||||
*
|
||||
* @return the status of the connection
|
||||
* @exception SQLException (why?)
|
||||
*/
|
||||
public boolean isClosed() throws SQLException
|
||||
{
|
||||
return (pg_stream == null);
|
||||
}
|
||||
|
||||
/*
|
||||
* A connection's database is able to provide information describing
|
||||
* its tables, its supported SQL grammar, its stored procedures, the
|
||||
* capabilities of this connection, etc. This information is made
|
||||
* available through a DatabaseMetaData object.
|
||||
*
|
||||
* @return a DatabaseMetaData object for this connection
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public java.sql.DatabaseMetaData getMetaData() throws SQLException
|
||||
{
|
||||
if (metadata == null)
|
||||
metadata = new DatabaseMetaData(this);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/*
|
||||
* This overides the method in org.postgresql.Connection and returns a
|
||||
* ResultSet.
|
||||
*/
|
||||
public java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
|
||||
{
|
||||
// in jdbc1 stat is ignored.
|
||||
return new org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
|
||||
}
|
||||
|
||||
|
||||
/* An implementation of the abstract method in the parent class.
|
||||
* This implemetation uses the jdbc1Types array to support the jdbc1
|
||||
* datatypes. Basically jdbc1 and jdbc2 are the same, except that
|
||||
* jdbc2 adds the Array types.
|
||||
*/
|
||||
public int getSQLType(String pgTypeName)
|
||||
{
|
||||
int sqlType = Types.OTHER; // default value
|
||||
for (int i = 0;i < jdbc1Types.length;i++)
|
||||
{
|
||||
if (pgTypeName.equals(jdbc1Types[i]))
|
||||
{
|
||||
sqlType = jdbc1Typei[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sqlType;
|
||||
}
|
||||
|
||||
/*
|
||||
* This table holds the org.postgresql names for the types supported.
|
||||
* Any types that map to Types.OTHER (eg POINT) don't go into this table.
|
||||
* They default automatically to Types.OTHER
|
||||
*
|
||||
* Note: This must be in the same order as below.
|
||||
*
|
||||
* Tip: keep these grouped together by the Types. value
|
||||
*/
|
||||
private static final String jdbc1Types[] = {
|
||||
"int2",
|
||||
"int4", "oid",
|
||||
"int8",
|
||||
"cash", "money",
|
||||
"numeric",
|
||||
"float4",
|
||||
"float8",
|
||||
"bpchar", "char", "char2", "char4", "char8", "char16",
|
||||
"varchar", "text", "name", "filename",
|
||||
"bytea",
|
||||
"bool",
|
||||
"date",
|
||||
"time",
|
||||
"abstime", "timestamp", "timestamptz"
|
||||
};
|
||||
|
||||
/*
|
||||
* This table holds the JDBC type for each entry above.
|
||||
*
|
||||
* Note: This must be in the same order as above
|
||||
*
|
||||
* Tip: keep these grouped together by the Types. value
|
||||
*/
|
||||
private static final int jdbc1Typei[] = {
|
||||
Types.SMALLINT,
|
||||
Types.INTEGER, Types.INTEGER,
|
||||
Types.BIGINT,
|
||||
Types.DOUBLE, Types.DOUBLE,
|
||||
Types.NUMERIC,
|
||||
Types.REAL,
|
||||
Types.DOUBLE,
|
||||
Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR,
|
||||
Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
|
||||
Types.BINARY,
|
||||
Types.BIT,
|
||||
Types.DATE,
|
||||
Types.TIME,
|
||||
Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ***********************************************************************
|
||||
|
@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException;
|
||||
/*
|
||||
* This class provides information about the database as a whole.
|
||||
*
|
||||
* $Id: DatabaseMetaData.java,v 1.47 2002/06/20 16:00:44 momjian Exp $
|
||||
* $Id: DatabaseMetaData.java,v 1.48 2002/07/23 03:59:55 barry Exp $
|
||||
*
|
||||
* <p>Many of the methods here return lists of information in ResultSets. You
|
||||
* can use the normal ResultSet methods such as getString and getInt to
|
||||
@ -37,7 +37,7 @@ import org.postgresql.util.PSQLException;
|
||||
*/
|
||||
public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
{
|
||||
Connection connection; // The connection association
|
||||
Jdbc1Connection connection; // The connection association
|
||||
|
||||
// These define various OID's. Hopefully they will stay constant.
|
||||
static final int iVarcharOid = 1043; // OID for varchar
|
||||
@ -46,7 +46,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
static final int iInt4Oid = 23; // OID for int4
|
||||
static final int VARHDRSZ = 4; // length for int4
|
||||
|
||||
public DatabaseMetaData(Connection conn)
|
||||
public DatabaseMetaData(Jdbc1Connection conn)
|
||||
{
|
||||
this.connection = conn;
|
||||
}
|
||||
@ -196,7 +196,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
*/
|
||||
public String getDriverVersion() throws SQLException
|
||||
{
|
||||
return connection.this_driver.getVersion();
|
||||
return connection.getDriver().getVersion();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -206,7 +206,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
*/
|
||||
public int getDriverMajorVersion()
|
||||
{
|
||||
return connection.this_driver.getMajorVersion();
|
||||
return connection.getDriver().getMajorVersion();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -216,7 +216,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
*/
|
||||
public int getDriverMinorVersion()
|
||||
{
|
||||
return connection.this_driver.getMinorVersion();
|
||||
return connection.getDriver().getMinorVersion();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1549,7 +1549,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
|
||||
v.addElement(tuple);
|
||||
}
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1627,7 +1627,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
|
||||
// add query loop here
|
||||
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1721,7 +1721,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
|
||||
byte remarks[] = null;
|
||||
|
||||
if (((org.postgresql.ResultSet)dr).getTupleCount() == 1)
|
||||
if (((AbstractJdbc1ResultSet)dr).getTupleCount() == 1)
|
||||
{
|
||||
dr.next();
|
||||
remarks = dr.getBytes(1);
|
||||
@ -1762,7 +1762,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
v.addElement(tuple);
|
||||
}
|
||||
r.close();
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
// This array contains the valid values for the types argument
|
||||
@ -1809,7 +1809,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
f[0] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32);
|
||||
tuple[0] = "".getBytes();
|
||||
v.addElement(tuple);
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1854,7 +1854,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
tuple[0] = getTableTypes[i][0].getBytes();
|
||||
v.addElement(tuple);
|
||||
}
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2050,7 +2050,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
}
|
||||
r.close();
|
||||
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2113,7 +2113,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
//v.addElement(tuple);
|
||||
}
|
||||
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2203,7 +2203,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
f[6] = new Field(connection, "DECIMAL_DIGITS", iInt2Oid, 2);
|
||||
f[7] = new Field(connection, "PSEUDO_COLUMN", iInt2Oid, 2);
|
||||
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2413,7 +2413,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
while (hasMore);
|
||||
}
|
||||
|
||||
return new ResultSet(connection, f, tuples, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, tuples, "OK", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2692,7 +2692,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
v.addElement(tuple);
|
||||
}
|
||||
rs.close();
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
throw new PSQLException("postgresql.metadata.unavailable");
|
||||
@ -2832,7 +2832,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
}
|
||||
}
|
||||
|
||||
return new ResultSet(connection, f, v, "OK", 1);
|
||||
return new Jdbc1ResultSet(connection, f, v, "OK", 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package org.postgresql.jdbc1;
|
||||
|
||||
|
||||
import java.util.Vector;
|
||||
import java.sql.*;
|
||||
import org.postgresql.Field;
|
||||
import org.postgresql.util.PSQLException;
|
||||
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.1 2002/07/23 03:59:55 barry Exp $
|
||||
* This class implements the java.sql.Connection interface for JDBC1.
|
||||
* However most of the implementation is really done in
|
||||
* org.postgresql.jdbc1.AbstractJdbc1Connection
|
||||
*/
|
||||
public class Jdbc1Connection extends org.postgresql.jdbc1.AbstractJdbc1Connection implements java.sql.Connection
|
||||
{
|
||||
|
||||
public java.sql.Statement createStatement() throws SQLException
|
||||
{
|
||||
return new org.postgresql.jdbc1.Jdbc1Statement(this);
|
||||
}
|
||||
|
||||
public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
|
||||
{
|
||||
return new org.postgresql.jdbc1.PreparedStatement(this, sql);
|
||||
}
|
||||
|
||||
//BJL TODO - merge callable statement logic from jdbc2 to jdbc1
|
||||
public java.sql.CallableStatement prepareCall(String sql) throws SQLException
|
||||
{
|
||||
throw new PSQLException("postgresql.con.call");
|
||||
}
|
||||
|
||||
public java.sql.DatabaseMetaData getMetaData() throws SQLException
|
||||
{
|
||||
if (metadata == null)
|
||||
metadata = new org.postgresql.jdbc1.DatabaseMetaData(this);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public java.sql.ResultSet getResultSet(java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
|
||||
{
|
||||
return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
32
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java
Normal file
32
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java
Normal file
@ -0,0 +1,32 @@
|
||||
package org.postgresql.jdbc1;
|
||||
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Vector;
|
||||
import org.postgresql.Field;
|
||||
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1ResultSet.java,v 1.1 2002/07/23 03:59:55 barry Exp $
|
||||
* This class implements the java.sql.ResultSet interface for JDBC1.
|
||||
* However most of the implementation is really done in
|
||||
* org.postgresql.jdbc1.AbstractJdbc1ResultSet
|
||||
*/
|
||||
public class Jdbc1ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet implements java.sql.ResultSet
|
||||
{
|
||||
|
||||
public Jdbc1ResultSet(Jdbc1Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
|
||||
{
|
||||
super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
|
||||
}
|
||||
|
||||
public Jdbc1ResultSet(Jdbc1Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
|
||||
{
|
||||
super(conn, fields, tuples, status, updateCount, 0, false);
|
||||
}
|
||||
|
||||
public java.sql.ResultSetMetaData getMetaData() throws SQLException
|
||||
{
|
||||
return new ResultSetMetaData(rows, fields);
|
||||
}
|
||||
|
||||
}
|
||||
|
19
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
Normal file
19
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.postgresql.jdbc1;
|
||||
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.1 2002/07/23 03:59:55 barry Exp $
|
||||
* This class implements the java.sql.Statement interface for JDBC1.
|
||||
* However most of the implementation is really done in
|
||||
* org.postgresql.jdbc1.AbstractJdbc1Statement
|
||||
*/
|
||||
public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement implements java.sql.Statement
|
||||
{
|
||||
|
||||
public Jdbc1Statement (Jdbc1Connection c)
|
||||
{
|
||||
connection = c;
|
||||
}
|
||||
|
||||
}
|
@ -29,12 +29,12 @@ import org.postgresql.util.*;
|
||||
* @see ResultSet
|
||||
* @see java.sql.PreparedStatement
|
||||
*/
|
||||
public class PreparedStatement extends Statement implements java.sql.PreparedStatement
|
||||
public class PreparedStatement extends Jdbc1Statement implements java.sql.PreparedStatement
|
||||
{
|
||||
String sql;
|
||||
String[] templateStrings;
|
||||
String[] inStrings;
|
||||
Connection connection;
|
||||
Jdbc1Connection connection;
|
||||
|
||||
// Some performance caches
|
||||
private StringBuffer sbuf = new StringBuffer();
|
||||
@ -49,7 +49,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
|
||||
* @param sql the SQL statement with ? for IN markers
|
||||
* @exception SQLException if something bad occurs
|
||||
*/
|
||||
public PreparedStatement(Connection connection, String sql) throws SQLException
|
||||
public PreparedStatement(Jdbc1Connection connection, String sql) throws SQLException
|
||||
{
|
||||
super(connection);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,144 +0,0 @@
|
||||
package org.postgresql.jdbc1;
|
||||
|
||||
// IMPORTANT NOTE: This file implements the JDBC 1 version of the driver.
|
||||
// If you make any modifications to this file, you must make sure that the
|
||||
// changes are also made (if relevent) to the related JDBC 2 class in the
|
||||
// org.postgresql.jdbc2 package.
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
import org.postgresql.util.PSQLException;
|
||||
|
||||
/*
|
||||
* A Statement object is used for executing a static SQL statement and
|
||||
* obtaining the results produced by it.
|
||||
*
|
||||
* <p>Only one ResultSet per Statement can be open at any point in time.
|
||||
* Therefore, if the reading of one ResultSet is interleaved with the
|
||||
* reading of another, each must have been generated by different
|
||||
* Statements. All statement execute methods implicitly close a
|
||||
* statement's current ResultSet if an open one exists.
|
||||
*
|
||||
* @see java.sql.Statement
|
||||
* @see ResultSet
|
||||
*/
|
||||
public class Statement extends org.postgresql.Statement implements java.sql.Statement
|
||||
{
|
||||
private Connection connection; // The connection who created us
|
||||
|
||||
/*
|
||||
* Constructor for a Statement. It simply sets the connection
|
||||
* that created us.
|
||||
*
|
||||
* @param c the Connection instantation that creates us
|
||||
*/
|
||||
public Statement (Connection c)
|
||||
{
|
||||
connection = c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a SQL statement that retruns a single ResultSet
|
||||
*
|
||||
* @param sql typically a static SQL SELECT statement
|
||||
* @return a ResulSet that contains the data produced by the query
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public java.sql.ResultSet executeQuery(String sql) throws SQLException
|
||||
{
|
||||
this.execute(sql);
|
||||
while (result != null && !((org.postgresql.ResultSet)result).reallyResultSet())
|
||||
result = ((org.postgresql.ResultSet)result).getNext();
|
||||
if (result == null)
|
||||
throw new PSQLException("postgresql.stat.noresult");
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition
|
||||
* SQL statements that return nothing such as SQL DDL statements
|
||||
* can be executed
|
||||
*
|
||||
* @param sql a SQL statement
|
||||
* @return either a row count, or 0 for SQL commands
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public int executeUpdate(String sql) throws SQLException
|
||||
{
|
||||
this.execute(sql);
|
||||
return this.getUpdateCount();
|
||||
}
|
||||
|
||||
/*
|
||||
* setCursorName defines the SQL cursor name that will be used by
|
||||
* subsequent execute methods. This name can then be used in SQL
|
||||
* positioned update/delete statements to identify the current row
|
||||
* in the ResultSet generated by this statement. If a database
|
||||
* doesn't support positioned update/delete, this method is a
|
||||
* no-op.
|
||||
*
|
||||
* <p><B>Note:</B> By definition, positioned update/delete execution
|
||||
* must be done by a different Statement than the one which
|
||||
* generated the ResultSet being used for positioning. Also, cursor
|
||||
* names must be unique within a Connection.
|
||||
*
|
||||
* <p>We throw an additional constriction. There can only be one
|
||||
* cursor active at any one time.
|
||||
*
|
||||
* @param name the new cursor name
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public void setCursorName(String name) throws SQLException
|
||||
{
|
||||
connection.setCursorName(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a SQL statement that may return multiple results. We
|
||||
* don't have to worry about this since we do not support multiple
|
||||
* ResultSets. You can use getResultSet or getUpdateCount to
|
||||
* retrieve the result.
|
||||
*
|
||||
* @param sql any SQL statement
|
||||
* @return true if the next result is a ResulSet, false if it is
|
||||
* an update count or there are no more results
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public boolean execute(String sql) throws SQLException
|
||||
{
|
||||
if (escapeProcessing)
|
||||
sql = escapeSQL(sql);
|
||||
result = connection.ExecSQL(sql);
|
||||
return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
|
||||
}
|
||||
|
||||
/*
|
||||
* getUpdateCount returns the current result as an update count,
|
||||
* if the result is a ResultSet or there are no more results, -1
|
||||
* is returned. It should only be called once per result.
|
||||
*
|
||||
* @return the current result as an update count.
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public int getUpdateCount() throws SQLException
|
||||
{
|
||||
if (result == null)
|
||||
return -1;
|
||||
if (((org.postgresql.ResultSet)result).reallyResultSet())
|
||||
return -1;
|
||||
return ((org.postgresql.ResultSet)result).getResultCount();
|
||||
}
|
||||
|
||||
/*
|
||||
* getMoreResults moves to a Statement's next result. If it returns
|
||||
* true, this result is a ResulSet.
|
||||
*
|
||||
* @return true if the next ResultSet is valid
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public boolean getMoreResults() throws SQLException
|
||||
{
|
||||
result = ((org.postgresql.ResultSet)result).getNext();
|
||||
return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user