mirror of
https://github.com/postgres/postgres.git
synced 2025-07-09 22:41:56 +03:00
Second phase of restructuring to add jdbc3 support.
This commit is contained in:
@ -1,9 +1,14 @@
|
|||||||
package org.postgresql.jdbc1;
|
package org.postgresql.jdbc1;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.io.*;
|
||||||
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 $
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
import org.postgresql.largeobject.*;
|
||||||
|
import org.postgresql.util.*;
|
||||||
|
|
||||||
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.2 2002/07/24 22:08:39 barry Exp $
|
||||||
* This class defines methods of the jdbc1 specification. This class is
|
* This class defines methods of the jdbc1 specification. This class is
|
||||||
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
|
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
|
||||||
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
|
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
|
||||||
@ -34,6 +39,56 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
|||||||
private static final short BACKSLASH = 2;
|
private static final short BACKSLASH = 2;
|
||||||
private static final short ESC_TIMEDATE = 3;
|
private static final short ESC_TIMEDATE = 3;
|
||||||
|
|
||||||
|
// Some performance caches
|
||||||
|
private StringBuffer sbuf = new StringBuffer();
|
||||||
|
|
||||||
|
//Used by the preparedstatement style methods
|
||||||
|
protected String sql;
|
||||||
|
protected String[] templateStrings;
|
||||||
|
protected String[] inStrings;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractJdbc1Statement (AbstractJdbc1Connection connection)
|
||||||
|
{
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractJdbc1Statement (AbstractJdbc1Connection connection, String sql) throws SQLException
|
||||||
|
{
|
||||||
|
this.sql = sql;
|
||||||
|
this.connection = connection;
|
||||||
|
parseSqlStmt(); // this allows Callable stmt to override
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void parseSqlStmt () throws SQLException {
|
||||||
|
Vector v = new Vector();
|
||||||
|
boolean inQuotes = false;
|
||||||
|
int lastParmEnd = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < sql.length(); ++i)
|
||||||
|
{
|
||||||
|
int c = sql.charAt(i);
|
||||||
|
|
||||||
|
if (c == '\'')
|
||||||
|
inQuotes = !inQuotes;
|
||||||
|
if (c == '?' && !inQuotes)
|
||||||
|
{
|
||||||
|
v.addElement(sql.substring (lastParmEnd, i));
|
||||||
|
lastParmEnd = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v.addElement(sql.substring (lastParmEnd, sql.length()));
|
||||||
|
|
||||||
|
templateStrings = new String[v.size()];
|
||||||
|
inStrings = new String[v.size() - 1];
|
||||||
|
clearParameters();
|
||||||
|
|
||||||
|
for (i = 0 ; i < templateStrings.length; ++i)
|
||||||
|
templateStrings[i] = (String)v.elementAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute a SQL statement that retruns a single ResultSet
|
* Execute a SQL statement that retruns a single ResultSet
|
||||||
*
|
*
|
||||||
@ -51,6 +106,18 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A Prepared SQL query is executed and its ResultSet is returned
|
||||||
|
*
|
||||||
|
* @return a ResultSet that contains the data produced by the
|
||||||
|
* * query - never null
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public java.sql.ResultSet executeQuery() throws SQLException
|
||||||
|
{
|
||||||
|
return executeQuery(compileQuery());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition
|
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition
|
||||||
* SQL statements that return nothing such as SQL DDL statements
|
* SQL statements that return nothing such as SQL DDL statements
|
||||||
@ -68,6 +135,20 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
|||||||
return this.getUpdateCount();
|
return this.getUpdateCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition,
|
||||||
|
* SQL statements that return nothing such as SQL DDL statements can
|
||||||
|
* be executed.
|
||||||
|
*
|
||||||
|
* @return either the row count for INSERT, UPDATE or DELETE; or
|
||||||
|
* * 0 for SQL statements that return nothing.
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public int executeUpdate() throws SQLException
|
||||||
|
{
|
||||||
|
return executeUpdate(compileQuery());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute a SQL statement that may return multiple results. We
|
* Execute a SQL statement that may return multiple results. We
|
||||||
* don't have to worry about this since we do not support multiple
|
* don't have to worry about this since we do not support multiple
|
||||||
@ -101,6 +182,20 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
|||||||
return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet());
|
return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some prepared statements return multiple results; the execute method
|
||||||
|
* handles these complex statements as well as the simpler form of
|
||||||
|
* statements handled by executeQuery and executeUpdate
|
||||||
|
*
|
||||||
|
* @return true if the next result is a ResultSet; false if it is an
|
||||||
|
* * update count or there are no more results
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public boolean execute() throws SQLException
|
||||||
|
{
|
||||||
|
return execute(compileQuery());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setCursorName defines the SQL cursor name that will be used by
|
* setCursorName defines the SQL cursor name that will be used by
|
||||||
* subsequent execute methods. This name can then be used in SQL
|
* subsequent execute methods. This name can then be used in SQL
|
||||||
@ -466,6 +561,743 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
|||||||
return ((AbstractJdbc1ResultSet)result).getLastOID();
|
return ((AbstractJdbc1ResultSet)result).getLastOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to SQL NULL
|
||||||
|
*
|
||||||
|
* <p><B>Note:</B> You must specify the parameters SQL type (although
|
||||||
|
* PostgreSQL ignores it)
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1, etc...
|
||||||
|
* @param sqlType the SQL type code defined in java.sql.Types
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setNull(int parameterIndex, int sqlType) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, "null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java boolean value. The driver converts this
|
||||||
|
* to a SQL BIT value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setBoolean(int parameterIndex, boolean x) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, x ? "'t'" : "'f'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java byte value. The driver converts this to
|
||||||
|
* a SQL TINYINT value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setByte(int parameterIndex, byte x) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, Integer.toString(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java short value. The driver converts this
|
||||||
|
* to a SQL SMALLINT value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setShort(int parameterIndex, short x) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, Integer.toString(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java int value. The driver converts this to
|
||||||
|
* a SQL INTEGER value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setInt(int parameterIndex, int x) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, Integer.toString(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java long value. The driver converts this to
|
||||||
|
* a SQL BIGINT value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setLong(int parameterIndex, long x) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, Long.toString(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java float value. The driver converts this
|
||||||
|
* to a SQL FLOAT value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setFloat(int parameterIndex, float x) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, Float.toString(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java double value. The driver converts this
|
||||||
|
* to a SQL DOUBLE value when it sends it to the database
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setDouble(int parameterIndex, double x) throws SQLException
|
||||||
|
{
|
||||||
|
set(parameterIndex, Double.toString(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a java.lang.BigDecimal value. The driver
|
||||||
|
* converts this to a SQL NUMERIC value when it sends it to the
|
||||||
|
* database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
|
||||||
|
{
|
||||||
|
if (x == null)
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set(parameterIndex, x.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java String value. The driver converts this
|
||||||
|
* to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments
|
||||||
|
* size relative to the driver's limits on VARCHARs) when it sends it
|
||||||
|
* to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setString(int parameterIndex, String x) throws SQLException
|
||||||
|
{
|
||||||
|
// if the passed string is null, then set this column to null
|
||||||
|
if (x == null)
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// use the shared buffer object. Should never clash but this makes
|
||||||
|
// us thread safe!
|
||||||
|
synchronized (sbuf)
|
||||||
|
{
|
||||||
|
sbuf.setLength(0);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sbuf.append('\'');
|
||||||
|
for (i = 0 ; i < x.length() ; ++i)
|
||||||
|
{
|
||||||
|
char c = x.charAt(i);
|
||||||
|
if (c == '\\' || c == '\'')
|
||||||
|
sbuf.append((char)'\\');
|
||||||
|
sbuf.append(c);
|
||||||
|
}
|
||||||
|
sbuf.append('\'');
|
||||||
|
set(parameterIndex, sbuf.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a Java array of bytes. The driver converts this
|
||||||
|
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
|
||||||
|
* size relative to the driver's limits on VARBINARYs) when it sends
|
||||||
|
* it to the database.
|
||||||
|
*
|
||||||
|
* <p>Implementation note:
|
||||||
|
* <br>With org.postgresql, this creates a large object, and stores the
|
||||||
|
* objects oid in this column.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setBytes(int parameterIndex, byte x[]) throws SQLException
|
||||||
|
{
|
||||||
|
if (connection.haveMinimumCompatibleVersion("7.2"))
|
||||||
|
{
|
||||||
|
//Version 7.2 supports the bytea datatype for byte arrays
|
||||||
|
if (null == x)
|
||||||
|
{
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setString(parameterIndex, PGbytea.toPGString(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Version 7.1 and earlier support done as LargeObjects
|
||||||
|
LargeObjectManager lom = connection.getLargeObjectAPI();
|
||||||
|
int oid = lom.create();
|
||||||
|
LargeObject lob = lom.open(oid);
|
||||||
|
lob.write(x);
|
||||||
|
lob.close();
|
||||||
|
setInt(parameterIndex, oid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a java.sql.Date value. The driver converts this
|
||||||
|
* to a SQL DATE value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
|
||||||
|
{
|
||||||
|
if (null == x)
|
||||||
|
{
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set(parameterIndex, "'" + x.toString() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a java.sql.Time value. The driver converts
|
||||||
|
* this to a SQL TIME value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...));
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setTime(int parameterIndex, Time x) throws SQLException
|
||||||
|
{
|
||||||
|
if (null == x)
|
||||||
|
{
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set(parameterIndex, "'" + x.toString() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a java.sql.Timestamp value. The driver converts
|
||||||
|
* this to a SQL TIMESTAMP value when it sends it to the database.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
|
||||||
|
{
|
||||||
|
if (null == x)
|
||||||
|
{
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use the shared StringBuffer
|
||||||
|
synchronized (sbuf)
|
||||||
|
{
|
||||||
|
sbuf.setLength(0);
|
||||||
|
sbuf.append("'");
|
||||||
|
//format the timestamp
|
||||||
|
//we do our own formating so that we can get a format
|
||||||
|
//that works with both timestamp with time zone and
|
||||||
|
//timestamp without time zone datatypes.
|
||||||
|
//The format is '2002-01-01 23:59:59.123456-0130'
|
||||||
|
//we need to include the local time and timezone offset
|
||||||
|
//so that timestamp without time zone works correctly
|
||||||
|
int l_year = x.getYear() + 1900;
|
||||||
|
sbuf.append(l_year);
|
||||||
|
sbuf.append('-');
|
||||||
|
int l_month = x.getMonth() + 1;
|
||||||
|
if (l_month < 10) sbuf.append('0');
|
||||||
|
sbuf.append(l_month);
|
||||||
|
sbuf.append('-');
|
||||||
|
int l_day = x.getDate();
|
||||||
|
if (l_day < 10) sbuf.append('0');
|
||||||
|
sbuf.append(l_day);
|
||||||
|
sbuf.append(' ');
|
||||||
|
int l_hours = x.getHours();
|
||||||
|
if (l_hours < 10) sbuf.append('0');
|
||||||
|
sbuf.append(l_hours);
|
||||||
|
sbuf.append(':');
|
||||||
|
int l_minutes = x.getMinutes();
|
||||||
|
if (l_minutes < 10) sbuf.append('0');
|
||||||
|
sbuf.append(l_minutes);
|
||||||
|
sbuf.append(':');
|
||||||
|
int l_seconds = x.getSeconds();
|
||||||
|
if (l_seconds < 10) sbuf.append('0');
|
||||||
|
sbuf.append(l_seconds);
|
||||||
|
// Make decimal from nanos.
|
||||||
|
char[] l_decimal = {'0','0','0','0','0','0','0','0','0'};
|
||||||
|
char[] l_nanos = Integer.toString(x.getNanos()).toCharArray();
|
||||||
|
System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length);
|
||||||
|
sbuf.append('.');
|
||||||
|
if (connection.haveMinimumServerVersion("7.2")) {
|
||||||
|
sbuf.append(l_decimal,0,6);
|
||||||
|
} else {
|
||||||
|
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
|
||||||
|
sbuf.append(l_decimal,0,2);
|
||||||
|
}
|
||||||
|
//add timezone offset
|
||||||
|
int l_offset = -(x.getTimezoneOffset());
|
||||||
|
int l_houros = l_offset/60;
|
||||||
|
if (l_houros >= 0) {
|
||||||
|
sbuf.append('+');
|
||||||
|
} else {
|
||||||
|
sbuf.append('-');
|
||||||
|
}
|
||||||
|
if (l_houros > -10 && l_houros < 10) sbuf.append('0');
|
||||||
|
if (l_houros >= 0) {
|
||||||
|
sbuf.append(l_houros);
|
||||||
|
} else {
|
||||||
|
sbuf.append(-l_houros);
|
||||||
|
}
|
||||||
|
int l_minos = l_offset - (l_houros *60);
|
||||||
|
if (l_minos != 0) {
|
||||||
|
if (l_minos < 10) sbuf.append('0');
|
||||||
|
sbuf.append(l_minos);
|
||||||
|
}
|
||||||
|
sbuf.append("'");
|
||||||
|
set(parameterIndex, sbuf.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a very large ASCII value is input to a LONGVARCHAR parameter,
|
||||||
|
* it may be more practical to send it via a java.io.InputStream.
|
||||||
|
* JDBC will read the data from the stream as needed, until it reaches
|
||||||
|
* end-of-file. The JDBC driver will do any necessary conversion from
|
||||||
|
* ASCII to the database char format.
|
||||||
|
*
|
||||||
|
* <P><B>Note:</B> This stream object can either be a standard Java
|
||||||
|
* stream object or your own subclass that implements the standard
|
||||||
|
* interface.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @param length the number of bytes in the stream
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
|
||||||
|
{
|
||||||
|
if (connection.haveMinimumCompatibleVersion("7.2"))
|
||||||
|
{
|
||||||
|
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
|
||||||
|
//As the spec/javadoc for this method indicate this is to be used for
|
||||||
|
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
|
||||||
|
//long varchar datatype, but with toast all text datatypes are capable of
|
||||||
|
//handling very large values. Thus the implementation ends up calling
|
||||||
|
//setString() since there is no current way to stream the value to the server
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InputStreamReader l_inStream = new InputStreamReader(x, "ASCII");
|
||||||
|
char[] l_chars = new char[length];
|
||||||
|
int l_charsRead = l_inStream.read(l_chars, 0, length);
|
||||||
|
setString(parameterIndex, new String(l_chars, 0, l_charsRead));
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException l_uee)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", l_uee);
|
||||||
|
}
|
||||||
|
catch (IOException l_ioe)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", l_ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Version 7.1 supported only LargeObjects by treating everything
|
||||||
|
//as binary data
|
||||||
|
setBinaryStream(parameterIndex, x, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a very large Unicode value is input to a LONGVARCHAR parameter,
|
||||||
|
* it may be more practical to send it via a java.io.InputStream.
|
||||||
|
* JDBC will read the data from the stream as needed, until it reaches
|
||||||
|
* end-of-file. The JDBC driver will do any necessary conversion from
|
||||||
|
* UNICODE to the database char format.
|
||||||
|
*
|
||||||
|
* <P><B>Note:</B> This stream object can either be a standard Java
|
||||||
|
* stream object or your own subclass that implements the standard
|
||||||
|
* interface.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException
|
||||||
|
{
|
||||||
|
if (connection.haveMinimumCompatibleVersion("7.2"))
|
||||||
|
{
|
||||||
|
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
|
||||||
|
//As the spec/javadoc for this method indicate this is to be used for
|
||||||
|
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
|
||||||
|
//long varchar datatype, but with toast all text datatypes are capable of
|
||||||
|
//handling very large values. Thus the implementation ends up calling
|
||||||
|
//setString() since there is no current way to stream the value to the server
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InputStreamReader l_inStream = new InputStreamReader(x, "UTF-8");
|
||||||
|
char[] l_chars = new char[length];
|
||||||
|
int l_charsRead = l_inStream.read(l_chars, 0, length);
|
||||||
|
setString(parameterIndex, new String(l_chars, 0, l_charsRead));
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException l_uee)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", l_uee);
|
||||||
|
}
|
||||||
|
catch (IOException l_ioe)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", l_ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Version 7.1 supported only LargeObjects by treating everything
|
||||||
|
//as binary data
|
||||||
|
setBinaryStream(parameterIndex, x, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a very large binary value is input to a LONGVARBINARY parameter,
|
||||||
|
* it may be more practical to send it via a java.io.InputStream.
|
||||||
|
* JDBC will read the data from the stream as needed, until it reaches
|
||||||
|
* end-of-file.
|
||||||
|
*
|
||||||
|
* <P><B>Note:</B> This stream object can either be a standard Java
|
||||||
|
* stream object or your own subclass that implements the standard
|
||||||
|
* interface.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the parameter value
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
|
||||||
|
{
|
||||||
|
if (connection.haveMinimumCompatibleVersion("7.2"))
|
||||||
|
{
|
||||||
|
//Version 7.2 supports BinaryStream for for the 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
|
||||||
|
//setBytes() since there is no current way to stream the value to the server
|
||||||
|
byte[] l_bytes = new byte[length];
|
||||||
|
int l_bytesRead;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_bytesRead = x.read(l_bytes, 0, length);
|
||||||
|
}
|
||||||
|
catch (IOException l_ioe)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", l_ioe);
|
||||||
|
}
|
||||||
|
if (l_bytesRead == length)
|
||||||
|
{
|
||||||
|
setBytes(parameterIndex, l_bytes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//the stream contained less data than they said
|
||||||
|
byte[] l_bytes2 = new byte[l_bytesRead];
|
||||||
|
System.arraycopy(l_bytes, 0, l_bytes2, 0, l_bytesRead);
|
||||||
|
setBytes(parameterIndex, l_bytes2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Version 7.1 only supported streams for LargeObjects
|
||||||
|
//but the jdbc spec indicates that streams should be
|
||||||
|
//available for LONGVARBINARY instead
|
||||||
|
LargeObjectManager lom = connection.getLargeObjectAPI();
|
||||||
|
int oid = lom.create();
|
||||||
|
LargeObject lob = lom.open(oid);
|
||||||
|
OutputStream los = lob.getOutputStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// could be buffered, but then the OutputStream returned by LargeObject
|
||||||
|
// is buffered internally anyhow, so there would be no performance
|
||||||
|
// boost gained, if anything it would be worse!
|
||||||
|
int c = x.read();
|
||||||
|
int p = 0;
|
||||||
|
while (c > -1 && p < length)
|
||||||
|
{
|
||||||
|
los.write(c);
|
||||||
|
c = x.read();
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
los.close();
|
||||||
|
}
|
||||||
|
catch (IOException se)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", se);
|
||||||
|
}
|
||||||
|
// lob is closed by the stream so don't call lob.close()
|
||||||
|
setInt(parameterIndex, oid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In general, parameter values remain in force for repeated used of a
|
||||||
|
* Statement. Setting a parameter value automatically clears its
|
||||||
|
* previous value. However, in coms cases, it is useful to immediately
|
||||||
|
* release the resources used by the current parameter values; this
|
||||||
|
* can be done by calling clearParameters
|
||||||
|
*
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void clearParameters() throws SQLException
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; i < inStrings.length ; i++)
|
||||||
|
inStrings[i] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the value of a parameter using an object; use the java.lang
|
||||||
|
* equivalent objects for integral values.
|
||||||
|
*
|
||||||
|
* <P>The given Java object will be converted to the targetSqlType before
|
||||||
|
* being sent to the database.
|
||||||
|
*
|
||||||
|
* <P>note that this method may be used to pass database-specific
|
||||||
|
* abstract data types. This is done by using a Driver-specific
|
||||||
|
* Java type and using a targetSqlType of java.sql.Types.OTHER
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the object containing the input parameter value
|
||||||
|
* @param targetSqlType The SQL type to be send to the database
|
||||||
|
* @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC
|
||||||
|
* * types this is the number of digits after the decimal. For
|
||||||
|
* * all other types this value will be ignored.
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException
|
||||||
|
{
|
||||||
|
if (x == null)
|
||||||
|
{
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (targetSqlType)
|
||||||
|
{
|
||||||
|
case Types.TINYINT:
|
||||||
|
case Types.SMALLINT:
|
||||||
|
case Types.INTEGER:
|
||||||
|
case Types.BIGINT:
|
||||||
|
case Types.REAL:
|
||||||
|
case Types.FLOAT:
|
||||||
|
case Types.DOUBLE:
|
||||||
|
case Types.DECIMAL:
|
||||||
|
case Types.NUMERIC:
|
||||||
|
if (x instanceof Boolean)
|
||||||
|
set(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0");
|
||||||
|
else
|
||||||
|
set(parameterIndex, x.toString());
|
||||||
|
break;
|
||||||
|
case Types.CHAR:
|
||||||
|
case Types.VARCHAR:
|
||||||
|
case Types.LONGVARCHAR:
|
||||||
|
setString(parameterIndex, x.toString());
|
||||||
|
break;
|
||||||
|
case Types.DATE:
|
||||||
|
setDate(parameterIndex, (java.sql.Date)x);
|
||||||
|
break;
|
||||||
|
case Types.TIME:
|
||||||
|
setTime(parameterIndex, (Time)x);
|
||||||
|
break;
|
||||||
|
case Types.TIMESTAMP:
|
||||||
|
setTimestamp(parameterIndex, (Timestamp)x);
|
||||||
|
break;
|
||||||
|
case Types.BIT:
|
||||||
|
if (x instanceof Boolean)
|
||||||
|
{
|
||||||
|
set(parameterIndex, ((Boolean)x).booleanValue() ? "TRUE" : "FALSE");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.prep.type");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Types.BINARY:
|
||||||
|
case Types.VARBINARY:
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
break;
|
||||||
|
case Types.OTHER:
|
||||||
|
setString(parameterIndex, ((PGobject)x).getValue());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new PSQLException("postgresql.prep.type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
|
||||||
|
{
|
||||||
|
setObject(parameterIndex, x, targetSqlType, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This stores an Object into a parameter.
|
||||||
|
* <p>New for 6.4, if the object is not recognised, but it is
|
||||||
|
* Serializable, then the object is serialised using the
|
||||||
|
* org.postgresql.util.Serialize class.
|
||||||
|
*/
|
||||||
|
public void setObject(int parameterIndex, Object x) throws SQLException
|
||||||
|
{
|
||||||
|
if (x == null)
|
||||||
|
{
|
||||||
|
setNull(parameterIndex, Types.OTHER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x instanceof String)
|
||||||
|
setString(parameterIndex, (String)x);
|
||||||
|
else if (x instanceof BigDecimal)
|
||||||
|
setBigDecimal(parameterIndex, (BigDecimal)x);
|
||||||
|
else if (x instanceof Short)
|
||||||
|
setShort(parameterIndex, ((Short)x).shortValue());
|
||||||
|
else if (x instanceof Integer)
|
||||||
|
setInt(parameterIndex, ((Integer)x).intValue());
|
||||||
|
else if (x instanceof Long)
|
||||||
|
setLong(parameterIndex, ((Long)x).longValue());
|
||||||
|
else if (x instanceof Float)
|
||||||
|
setFloat(parameterIndex, ((Float)x).floatValue());
|
||||||
|
else if (x instanceof Double)
|
||||||
|
setDouble(parameterIndex, ((Double)x).doubleValue());
|
||||||
|
else if (x instanceof byte[])
|
||||||
|
setBytes(parameterIndex, (byte[])x);
|
||||||
|
else if (x instanceof java.sql.Date)
|
||||||
|
setDate(parameterIndex, (java.sql.Date)x);
|
||||||
|
else if (x instanceof Time)
|
||||||
|
setTime(parameterIndex, (Time)x);
|
||||||
|
else if (x instanceof Timestamp)
|
||||||
|
setTimestamp(parameterIndex, (Timestamp)x);
|
||||||
|
else if (x instanceof Boolean)
|
||||||
|
setBoolean(parameterIndex, ((Boolean)x).booleanValue());
|
||||||
|
else if (x instanceof PGobject)
|
||||||
|
setString(parameterIndex, ((PGobject)x).getValue());
|
||||||
|
else
|
||||||
|
// Try to store java object in database
|
||||||
|
setSerialize(parameterIndex, connection.storeObject(x), x.getClass().getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the SQL statement with the current template values
|
||||||
|
* substituted.
|
||||||
|
* NB: This is identical to compileQuery() except instead of throwing
|
||||||
|
* SQLException if a parameter is null, it places ? instead.
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
synchronized (sbuf)
|
||||||
|
{
|
||||||
|
sbuf.setLength(0);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; i < inStrings.length ; ++i)
|
||||||
|
{
|
||||||
|
if (inStrings[i] == null)
|
||||||
|
sbuf.append( '?' );
|
||||||
|
else
|
||||||
|
sbuf.append (templateStrings[i]);
|
||||||
|
sbuf.append (inStrings[i]);
|
||||||
|
}
|
||||||
|
sbuf.append(templateStrings[inStrings.length]);
|
||||||
|
return sbuf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are a lot of setXXX classes which all basically do
|
||||||
|
* the same thing. We need a method which actually does the
|
||||||
|
* set for us.
|
||||||
|
*
|
||||||
|
* @param paramIndex the index into the inString
|
||||||
|
* @param s a string to be stored
|
||||||
|
* @exception SQLException if something goes wrong
|
||||||
|
*/
|
||||||
|
protected void set(int paramIndex, String s) throws SQLException
|
||||||
|
{
|
||||||
|
if (paramIndex < 1 || paramIndex > inStrings.length)
|
||||||
|
throw new PSQLException("postgresql.prep.range");
|
||||||
|
inStrings[paramIndex - 1] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper - this compiles the SQL query from the various parameters
|
||||||
|
* This is identical to toString() except it throws an exception if a
|
||||||
|
* parameter is unused.
|
||||||
|
*/
|
||||||
|
protected synchronized String compileQuery()
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
sbuf.setLength(0);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; i < inStrings.length ; ++i)
|
||||||
|
{
|
||||||
|
if (inStrings[i] == null)
|
||||||
|
throw new PSQLException("postgresql.prep.param", new Integer(i + 1));
|
||||||
|
sbuf.append (templateStrings[i]).append (inStrings[i]);
|
||||||
|
}
|
||||||
|
sbuf.append(templateStrings[inStrings.length]);
|
||||||
|
return sbuf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a parameter to a tablerow-type oid reference.
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1...
|
||||||
|
* @param x the oid of the object from org.postgresql.util.Serialize.store
|
||||||
|
* @param classname the classname of the java object x
|
||||||
|
* @exception SQLException if a database access error occurs
|
||||||
|
*/
|
||||||
|
private void setSerialize(int parameterIndex, long x, String classname) throws SQLException
|
||||||
|
{
|
||||||
|
// converts . to _, toLowerCase, and ensures length<32
|
||||||
|
String tablename = Serialize.toPostgreSQL( classname );
|
||||||
|
DriverManager.println("setSerialize: setting " + x + "::" + tablename );
|
||||||
|
|
||||||
|
// OID reference to tablerow-type must be cast like: <oid>::<tablename>
|
||||||
|
// Note that postgres support for tablerow data types is incomplete/broken.
|
||||||
|
// This cannot be just a plain OID because then there would be ambiguity
|
||||||
|
// between when you want the oid itself and when you want the object
|
||||||
|
// an oid references.
|
||||||
|
set(parameterIndex, Long.toString(x) + "::" + tablename );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ import java.math.*;
|
|||||||
* @see ResultSet
|
* @see ResultSet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class CallableStatement extends PreparedStatement implements java.sql.CallableStatement
|
public class CallableStatement extends Jdbc1PreparedStatement implements java.sql.CallableStatement
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @exception SQLException on failure
|
* @exception SQLException on failure
|
||||||
|
@ -6,7 +6,7 @@ import java.sql.*;
|
|||||||
import org.postgresql.Field;
|
import org.postgresql.Field;
|
||||||
import org.postgresql.util.PSQLException;
|
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 $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.2 2002/07/24 22:08:40 barry Exp $
|
||||||
* This class implements the java.sql.Connection interface for JDBC1.
|
* This class implements the java.sql.Connection interface for JDBC1.
|
||||||
* However most of the implementation is really done in
|
* However most of the implementation is really done in
|
||||||
* org.postgresql.jdbc1.AbstractJdbc1Connection
|
* org.postgresql.jdbc1.AbstractJdbc1Connection
|
||||||
@ -21,7 +21,7 @@ public class Jdbc1Connection extends org.postgresql.jdbc1.AbstractJdbc1Connectio
|
|||||||
|
|
||||||
public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
|
public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
|
||||||
{
|
{
|
||||||
return new org.postgresql.jdbc1.PreparedStatement(this, sql);
|
return new org.postgresql.jdbc1.Jdbc1PreparedStatement(this, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
//BJL TODO - merge callable statement logic from jdbc2 to jdbc1
|
//BJL TODO - merge callable statement logic from jdbc2 to jdbc1
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package org.postgresql.jdbc1;
|
||||||
|
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class Jdbc1PreparedStatement extends AbstractJdbc1Statement implements PreparedStatement
|
||||||
|
{
|
||||||
|
|
||||||
|
public Jdbc1PreparedStatement(Jdbc1Connection connection, String sql) throws SQLException
|
||||||
|
{
|
||||||
|
super(connection, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,7 +3,7 @@ package org.postgresql.jdbc1;
|
|||||||
|
|
||||||
import java.sql.*;
|
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 $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.2 2002/07/24 22:08:40 barry Exp $
|
||||||
* This class implements the java.sql.Statement interface for JDBC1.
|
* This class implements the java.sql.Statement interface for JDBC1.
|
||||||
* However most of the implementation is really done in
|
* However most of the implementation is really done in
|
||||||
* org.postgresql.jdbc1.AbstractJdbc1Statement
|
* org.postgresql.jdbc1.AbstractJdbc1Statement
|
||||||
@ -13,7 +13,7 @@ public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement
|
|||||||
|
|
||||||
public Jdbc1Statement (Jdbc1Connection c)
|
public Jdbc1Statement (Jdbc1Connection c)
|
||||||
{
|
{
|
||||||
connection = c;
|
super(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,843 +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.math.*;
|
|
||||||
import java.sql.*;
|
|
||||||
import java.text.*;
|
|
||||||
import java.util.*;
|
|
||||||
import org.postgresql.largeobject.*;
|
|
||||||
import org.postgresql.util.*;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A SQL Statement is pre-compiled and stored in a PreparedStatement object.
|
|
||||||
* This object can then be used to efficiently execute this statement multiple
|
|
||||||
* times.
|
|
||||||
*
|
|
||||||
* <p><B>Note:</B> The setXXX methods for setting IN parameter values must
|
|
||||||
* specify types that are compatible with the defined SQL type of the input
|
|
||||||
* parameter. For instance, if the IN parameter has SQL type Integer, then
|
|
||||||
* setInt should be used.
|
|
||||||
*
|
|
||||||
* <p>If arbitrary parameter type conversions are required, then the setObject
|
|
||||||
* method should be used with a target SQL type.
|
|
||||||
*
|
|
||||||
* @see ResultSet
|
|
||||||
* @see java.sql.PreparedStatement
|
|
||||||
*/
|
|
||||||
public class PreparedStatement extends Jdbc1Statement implements java.sql.PreparedStatement
|
|
||||||
{
|
|
||||||
String sql;
|
|
||||||
String[] templateStrings;
|
|
||||||
String[] inStrings;
|
|
||||||
Jdbc1Connection connection;
|
|
||||||
|
|
||||||
// Some performance caches
|
|
||||||
private StringBuffer sbuf = new StringBuffer();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constructor for the PreparedStatement class.
|
|
||||||
* Split the SQL statement into segments - separated by the arguments.
|
|
||||||
* When we rebuild the thing with the arguments, we can substitute the
|
|
||||||
* args and join the whole thing together.
|
|
||||||
*
|
|
||||||
* @param conn the instanatiating connection
|
|
||||||
* @param sql the SQL statement with ? for IN markers
|
|
||||||
* @exception SQLException if something bad occurs
|
|
||||||
*/
|
|
||||||
public PreparedStatement(Jdbc1Connection connection, String sql) throws SQLException
|
|
||||||
{
|
|
||||||
super(connection);
|
|
||||||
|
|
||||||
Vector v = new Vector();
|
|
||||||
boolean inQuotes = false;
|
|
||||||
int lastParmEnd = 0, i;
|
|
||||||
|
|
||||||
this.sql = sql;
|
|
||||||
this.connection = connection;
|
|
||||||
for (i = 0; i < sql.length(); ++i)
|
|
||||||
{
|
|
||||||
int c = sql.charAt(i);
|
|
||||||
|
|
||||||
if (c == '\'')
|
|
||||||
inQuotes = !inQuotes;
|
|
||||||
if (c == '?' && !inQuotes)
|
|
||||||
{
|
|
||||||
v.addElement(sql.substring (lastParmEnd, i));
|
|
||||||
lastParmEnd = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v.addElement(sql.substring (lastParmEnd, sql.length()));
|
|
||||||
|
|
||||||
templateStrings = new String[v.size()];
|
|
||||||
inStrings = new String[v.size() - 1];
|
|
||||||
clearParameters();
|
|
||||||
|
|
||||||
for (i = 0 ; i < templateStrings.length; ++i)
|
|
||||||
templateStrings[i] = (String)v.elementAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A Prepared SQL query is executed and its ResultSet is returned
|
|
||||||
*
|
|
||||||
* @return a ResultSet that contains the data produced by the
|
|
||||||
* * query - never null
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public java.sql.ResultSet executeQuery() throws SQLException
|
|
||||||
{
|
|
||||||
StringBuffer s = new StringBuffer();
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0 ; i < inStrings.length ; ++i)
|
|
||||||
{
|
|
||||||
if (inStrings[i] == null)
|
|
||||||
throw new PSQLException("postgresql.prep.param", new Integer(i + 1));
|
|
||||||
s.append (templateStrings[i]);
|
|
||||||
s.append (inStrings[i]);
|
|
||||||
}
|
|
||||||
s.append(templateStrings[inStrings.length]);
|
|
||||||
return super.executeQuery(s.toString()); // in Statement class
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition,
|
|
||||||
* SQL statements that return nothing such as SQL DDL statements can
|
|
||||||
* be executed.
|
|
||||||
*
|
|
||||||
* @return either the row count for INSERT, UPDATE or DELETE; or
|
|
||||||
* * 0 for SQL statements that return nothing.
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public int executeUpdate() throws SQLException
|
|
||||||
{
|
|
||||||
StringBuffer s = new StringBuffer();
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0 ; i < inStrings.length ; ++i)
|
|
||||||
{
|
|
||||||
if (inStrings[i] == null)
|
|
||||||
throw new PSQLException("postgresql.prep.param", new Integer(i + 1));
|
|
||||||
s.append (templateStrings[i]);
|
|
||||||
s.append (inStrings[i]);
|
|
||||||
}
|
|
||||||
s.append(templateStrings[inStrings.length]);
|
|
||||||
return super.executeUpdate(s.toString()); // in Statement class
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to SQL NULL
|
|
||||||
*
|
|
||||||
* <p><B>Note:</B> You must specify the parameters SQL type (although
|
|
||||||
* PostgreSQL ignores it)
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1, etc...
|
|
||||||
* @param sqlType the SQL type code defined in java.sql.Types
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setNull(int parameterIndex, int sqlType) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, "null");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java boolean value. The driver converts this
|
|
||||||
* to a SQL BIT value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setBoolean(int parameterIndex, boolean x) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, x ? "'t'" : "'f'");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java byte value. The driver converts this to
|
|
||||||
* a SQL TINYINT value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setByte(int parameterIndex, byte x) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, Integer.toString(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java short value. The driver converts this
|
|
||||||
* to a SQL SMALLINT value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setShort(int parameterIndex, short x) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, Integer.toString(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java int value. The driver converts this to
|
|
||||||
* a SQL INTEGER value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setInt(int parameterIndex, int x) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, Integer.toString(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java long value. The driver converts this to
|
|
||||||
* a SQL BIGINT value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setLong(int parameterIndex, long x) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, Long.toString(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java float value. The driver converts this
|
|
||||||
* to a SQL FLOAT value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setFloat(int parameterIndex, float x) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, Float.toString(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java double value. The driver converts this
|
|
||||||
* to a SQL DOUBLE value when it sends it to the database
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setDouble(int parameterIndex, double x) throws SQLException
|
|
||||||
{
|
|
||||||
set(parameterIndex, Double.toString(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a java.lang.BigDecimal value. The driver
|
|
||||||
* converts this to a SQL NUMERIC value when it sends it to the
|
|
||||||
* database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
|
|
||||||
{
|
|
||||||
if (x == null)
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set(parameterIndex, x.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java String value. The driver converts this
|
|
||||||
* to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments
|
|
||||||
* size relative to the driver's limits on VARCHARs) when it sends it
|
|
||||||
* to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setString(int parameterIndex, String x) throws SQLException
|
|
||||||
{
|
|
||||||
// if the passed string is null, then set this column to null
|
|
||||||
if (x == null)
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StringBuffer b = new StringBuffer();
|
|
||||||
int i;
|
|
||||||
|
|
||||||
b.append('\'');
|
|
||||||
for (i = 0 ; i < x.length() ; ++i)
|
|
||||||
{
|
|
||||||
char c = x.charAt(i);
|
|
||||||
if (c == '\\' || c == '\'')
|
|
||||||
b.append((char)'\\');
|
|
||||||
b.append(c);
|
|
||||||
}
|
|
||||||
b.append('\'');
|
|
||||||
set(parameterIndex, b.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a Java array of bytes. The driver converts this
|
|
||||||
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
|
|
||||||
* size relative to the driver's limits on VARBINARYs) when it sends
|
|
||||||
* it to the database.
|
|
||||||
*
|
|
||||||
* <p>Implementation note:
|
|
||||||
* <br>With org.postgresql, this creates a large object, and stores the
|
|
||||||
* objects oid in this column.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setBytes(int parameterIndex, byte x[]) throws SQLException
|
|
||||||
{
|
|
||||||
if (connection.haveMinimumCompatibleVersion("7.2"))
|
|
||||||
{
|
|
||||||
//Version 7.2 supports the bytea datatype for byte arrays
|
|
||||||
if (null == x)
|
|
||||||
{
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setString(parameterIndex, PGbytea.toPGString(x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Version 7.1 and earlier support done as LargeObjects
|
|
||||||
LargeObjectManager lom = connection.getLargeObjectAPI();
|
|
||||||
int oid = lom.create();
|
|
||||||
LargeObject lob = lom.open(oid);
|
|
||||||
lob.write(x);
|
|
||||||
lob.close();
|
|
||||||
setInt(parameterIndex, oid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a java.sql.Date value. The driver converts this
|
|
||||||
* to a SQL DATE value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
|
|
||||||
{
|
|
||||||
if (null == x)
|
|
||||||
{
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set(parameterIndex, "'" + x.toString() + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a java.sql.Time value. The driver converts
|
|
||||||
* this to a SQL TIME value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...));
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setTime(int parameterIndex, Time x) throws SQLException
|
|
||||||
{
|
|
||||||
if (null == x)
|
|
||||||
{
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set(parameterIndex, "'" + x.toString() + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a parameter to a java.sql.Timestamp value. The driver converts
|
|
||||||
* this to a SQL TIMESTAMP value when it sends it to the database.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
|
|
||||||
{
|
|
||||||
if (null == x)
|
|
||||||
{
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Use the shared StringBuffer
|
|
||||||
synchronized (sbuf)
|
|
||||||
{
|
|
||||||
sbuf.setLength(0);
|
|
||||||
sbuf.append("'");
|
|
||||||
//format the timestamp
|
|
||||||
//we do our own formating so that we can get a format
|
|
||||||
//that works with both timestamp with time zone and
|
|
||||||
//timestamp without time zone datatypes.
|
|
||||||
//The format is '2002-01-01 23:59:59.123456-0130'
|
|
||||||
//we need to include the local time and timezone offset
|
|
||||||
//so that timestamp without time zone works correctly
|
|
||||||
int l_year = x.getYear() + 1900;
|
|
||||||
sbuf.append(l_year);
|
|
||||||
sbuf.append('-');
|
|
||||||
int l_month = x.getMonth() + 1;
|
|
||||||
if (l_month < 10) sbuf.append('0');
|
|
||||||
sbuf.append(l_month);
|
|
||||||
sbuf.append('-');
|
|
||||||
int l_day = x.getDate();
|
|
||||||
if (l_day < 10) sbuf.append('0');
|
|
||||||
sbuf.append(l_day);
|
|
||||||
sbuf.append(' ');
|
|
||||||
int l_hours = x.getHours();
|
|
||||||
if (l_hours < 10) sbuf.append('0');
|
|
||||||
sbuf.append(l_hours);
|
|
||||||
sbuf.append(':');
|
|
||||||
int l_minutes = x.getMinutes();
|
|
||||||
if (l_minutes < 10) sbuf.append('0');
|
|
||||||
sbuf.append(l_minutes);
|
|
||||||
sbuf.append(':');
|
|
||||||
int l_seconds = x.getSeconds();
|
|
||||||
if (l_seconds < 10) sbuf.append('0');
|
|
||||||
sbuf.append(l_seconds);
|
|
||||||
// Make decimal from nanos.
|
|
||||||
char[] l_decimal = {'0','0','0','0','0','0','0','0','0'};
|
|
||||||
char[] l_nanos = Integer.toString(x.getNanos()).toCharArray();
|
|
||||||
System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length);
|
|
||||||
sbuf.append('.');
|
|
||||||
if (connection.haveMinimumServerVersion("7.2")) {
|
|
||||||
sbuf.append(l_decimal,0,6);
|
|
||||||
} else {
|
|
||||||
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
|
|
||||||
sbuf.append(l_decimal,0,2);
|
|
||||||
}
|
|
||||||
//add timezone offset
|
|
||||||
int l_offset = -(x.getTimezoneOffset());
|
|
||||||
int l_houros = l_offset/60;
|
|
||||||
if (l_houros >= 0) {
|
|
||||||
sbuf.append('+');
|
|
||||||
} else {
|
|
||||||
sbuf.append('-');
|
|
||||||
}
|
|
||||||
if (l_houros > -10 && l_houros < 10) sbuf.append('0');
|
|
||||||
if (l_houros >= 0) {
|
|
||||||
sbuf.append(l_houros);
|
|
||||||
} else {
|
|
||||||
sbuf.append(-l_houros);
|
|
||||||
}
|
|
||||||
int l_minos = l_offset - (l_houros *60);
|
|
||||||
if (l_minos != 0) {
|
|
||||||
if (l_minos < 10) sbuf.append('0');
|
|
||||||
sbuf.append(l_minos);
|
|
||||||
}
|
|
||||||
sbuf.append("'");
|
|
||||||
set(parameterIndex, sbuf.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When a very large ASCII value is input to a LONGVARCHAR parameter,
|
|
||||||
* it may be more practical to send it via a java.io.InputStream.
|
|
||||||
* JDBC will read the data from the stream as needed, until it reaches
|
|
||||||
* end-of-file. The JDBC driver will do any necessary conversion from
|
|
||||||
* ASCII to the database char format.
|
|
||||||
*
|
|
||||||
* <P><B>Note:</B> This stream object can either be a standard Java
|
|
||||||
* stream object or your own subclass that implements the standard
|
|
||||||
* interface.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @param length the number of bytes in the stream
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
|
|
||||||
{
|
|
||||||
if (connection.haveMinimumCompatibleVersion("7.2"))
|
|
||||||
{
|
|
||||||
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
|
|
||||||
//As the spec/javadoc for this method indicate this is to be used for
|
|
||||||
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
|
|
||||||
//long varchar datatype, but with toast all text datatypes are capable of
|
|
||||||
//handling very large values. Thus the implementation ends up calling
|
|
||||||
//setString() since there is no current way to stream the value to the server
|
|
||||||
try
|
|
||||||
{
|
|
||||||
InputStreamReader l_inStream = new InputStreamReader(x, "ASCII");
|
|
||||||
char[] l_chars = new char[length];
|
|
||||||
int l_charsRead = l_inStream.read(l_chars, 0, length);
|
|
||||||
setString(parameterIndex, new String(l_chars, 0, l_charsRead));
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException l_uee)
|
|
||||||
{
|
|
||||||
throw new PSQLException("postgresql.unusual", l_uee);
|
|
||||||
}
|
|
||||||
catch (IOException l_ioe)
|
|
||||||
{
|
|
||||||
throw new PSQLException("postgresql.unusual", l_ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Version 7.1 supported only LargeObjects by treating everything
|
|
||||||
//as binary data
|
|
||||||
setBinaryStream(parameterIndex, x, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When a very large Unicode value is input to a LONGVARCHAR parameter,
|
|
||||||
* it may be more practical to send it via a java.io.InputStream.
|
|
||||||
* JDBC will read the data from the stream as needed, until it reaches
|
|
||||||
* end-of-file. The JDBC driver will do any necessary conversion from
|
|
||||||
* UNICODE to the database char format.
|
|
||||||
*
|
|
||||||
* <P><B>Note:</B> This stream object can either be a standard Java
|
|
||||||
* stream object or your own subclass that implements the standard
|
|
||||||
* interface.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException
|
|
||||||
{
|
|
||||||
if (connection.haveMinimumCompatibleVersion("7.2"))
|
|
||||||
{
|
|
||||||
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
|
|
||||||
//As the spec/javadoc for this method indicate this is to be used for
|
|
||||||
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
|
|
||||||
//long varchar datatype, but with toast all text datatypes are capable of
|
|
||||||
//handling very large values. Thus the implementation ends up calling
|
|
||||||
//setString() since there is no current way to stream the value to the server
|
|
||||||
try
|
|
||||||
{
|
|
||||||
InputStreamReader l_inStream = new InputStreamReader(x, "UTF-8");
|
|
||||||
char[] l_chars = new char[length];
|
|
||||||
int l_charsRead = l_inStream.read(l_chars, 0, length);
|
|
||||||
setString(parameterIndex, new String(l_chars, 0, l_charsRead));
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException l_uee)
|
|
||||||
{
|
|
||||||
throw new PSQLException("postgresql.unusual", l_uee);
|
|
||||||
}
|
|
||||||
catch (IOException l_ioe)
|
|
||||||
{
|
|
||||||
throw new PSQLException("postgresql.unusual", l_ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Version 7.1 supported only LargeObjects by treating everything
|
|
||||||
//as binary data
|
|
||||||
setBinaryStream(parameterIndex, x, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When a very large binary value is input to a LONGVARBINARY parameter,
|
|
||||||
* it may be more practical to send it via a java.io.InputStream.
|
|
||||||
* JDBC will read the data from the stream as needed, until it reaches
|
|
||||||
* end-of-file.
|
|
||||||
*
|
|
||||||
* <P><B>Note:</B> This stream object can either be a standard Java
|
|
||||||
* stream object or your own subclass that implements the standard
|
|
||||||
* interface.
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the parameter value
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
|
|
||||||
{
|
|
||||||
if (connection.haveMinimumCompatibleVersion("7.2"))
|
|
||||||
{
|
|
||||||
//Version 7.2 supports BinaryStream for for the 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
|
|
||||||
//setBytes() since there is no current way to stream the value to the server
|
|
||||||
byte[] l_bytes = new byte[length];
|
|
||||||
int l_bytesRead;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
l_bytesRead = x.read(l_bytes, 0, length);
|
|
||||||
}
|
|
||||||
catch (IOException l_ioe)
|
|
||||||
{
|
|
||||||
throw new PSQLException("postgresql.unusual", l_ioe);
|
|
||||||
}
|
|
||||||
if (l_bytesRead == length)
|
|
||||||
{
|
|
||||||
setBytes(parameterIndex, l_bytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//the stream contained less data than they said
|
|
||||||
byte[] l_bytes2 = new byte[l_bytesRead];
|
|
||||||
System.arraycopy(l_bytes, 0, l_bytes2, 0, l_bytesRead);
|
|
||||||
setBytes(parameterIndex, l_bytes2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Version 7.1 only supported streams for LargeObjects
|
|
||||||
//but the jdbc spec indicates that streams should be
|
|
||||||
//available for LONGVARBINARY instead
|
|
||||||
LargeObjectManager lom = connection.getLargeObjectAPI();
|
|
||||||
int oid = lom.create();
|
|
||||||
LargeObject lob = lom.open(oid);
|
|
||||||
OutputStream los = lob.getOutputStream();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// could be buffered, but then the OutputStream returned by LargeObject
|
|
||||||
// is buffered internally anyhow, so there would be no performance
|
|
||||||
// boost gained, if anything it would be worse!
|
|
||||||
int c = x.read();
|
|
||||||
int p = 0;
|
|
||||||
while (c > -1 && p < length)
|
|
||||||
{
|
|
||||||
los.write(c);
|
|
||||||
c = x.read();
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
los.close();
|
|
||||||
}
|
|
||||||
catch (IOException se)
|
|
||||||
{
|
|
||||||
throw new PSQLException("postgresql.unusual", se);
|
|
||||||
}
|
|
||||||
// lob is closed by the stream so don't call lob.close()
|
|
||||||
setInt(parameterIndex, oid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In general, parameter values remain in force for repeated used of a
|
|
||||||
* Statement. Setting a parameter value automatically clears its
|
|
||||||
* previous value. However, in coms cases, it is useful to immediately
|
|
||||||
* release the resources used by the current parameter values; this
|
|
||||||
* can be done by calling clearParameters
|
|
||||||
*
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void clearParameters() throws SQLException
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0 ; i < inStrings.length ; i++)
|
|
||||||
inStrings[i] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the value of a parameter using an object; use the java.lang
|
|
||||||
* equivalent objects for integral values.
|
|
||||||
*
|
|
||||||
* <P>The given Java object will be converted to the targetSqlType before
|
|
||||||
* being sent to the database.
|
|
||||||
*
|
|
||||||
* <P>note that this method may be used to pass database-specific
|
|
||||||
* abstract data types. This is done by using a Driver-specific
|
|
||||||
* Java type and using a targetSqlType of java.sql.Types.OTHER
|
|
||||||
*
|
|
||||||
* @param parameterIndex the first parameter is 1...
|
|
||||||
* @param x the object containing the input parameter value
|
|
||||||
* @param targetSqlType The SQL type to be send to the database
|
|
||||||
* @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC
|
|
||||||
* * types this is the number of digits after the decimal. For
|
|
||||||
* * all other types this value will be ignored.
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException
|
|
||||||
{
|
|
||||||
if (x == null)
|
|
||||||
{
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (targetSqlType)
|
|
||||||
{
|
|
||||||
case Types.TINYINT:
|
|
||||||
case Types.SMALLINT:
|
|
||||||
case Types.INTEGER:
|
|
||||||
case Types.BIGINT:
|
|
||||||
case Types.REAL:
|
|
||||||
case Types.FLOAT:
|
|
||||||
case Types.DOUBLE:
|
|
||||||
case Types.DECIMAL:
|
|
||||||
case Types.NUMERIC:
|
|
||||||
if (x instanceof Boolean)
|
|
||||||
set(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0");
|
|
||||||
else
|
|
||||||
set(parameterIndex, x.toString());
|
|
||||||
break;
|
|
||||||
case Types.CHAR:
|
|
||||||
case Types.VARCHAR:
|
|
||||||
case Types.LONGVARCHAR:
|
|
||||||
setString(parameterIndex, x.toString());
|
|
||||||
break;
|
|
||||||
case Types.DATE:
|
|
||||||
setDate(parameterIndex, (java.sql.Date)x);
|
|
||||||
break;
|
|
||||||
case Types.TIME:
|
|
||||||
setTime(parameterIndex, (Time)x);
|
|
||||||
break;
|
|
||||||
case Types.TIMESTAMP:
|
|
||||||
setTimestamp(parameterIndex, (Timestamp)x);
|
|
||||||
break;
|
|
||||||
case Types.BIT:
|
|
||||||
if (x instanceof Boolean)
|
|
||||||
{
|
|
||||||
set(parameterIndex, ((Boolean)x).booleanValue() ? "TRUE" : "FALSE");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new PSQLException("postgresql.prep.type");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Types.BINARY:
|
|
||||||
case Types.VARBINARY:
|
|
||||||
setObject(parameterIndex, x);
|
|
||||||
break;
|
|
||||||
case Types.OTHER:
|
|
||||||
setString(parameterIndex, ((PGobject)x).getValue());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new PSQLException("postgresql.prep.type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
|
|
||||||
{
|
|
||||||
setObject(parameterIndex, x, targetSqlType, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This stores an Object into a parameter.
|
|
||||||
* <p>New for 6.4, if the object is not recognised, but it is
|
|
||||||
* Serializable, then the object is serialised using the
|
|
||||||
* org.postgresql.util.Serialize class.
|
|
||||||
*/
|
|
||||||
public void setObject(int parameterIndex, Object x) throws SQLException
|
|
||||||
{
|
|
||||||
if (x == null)
|
|
||||||
{
|
|
||||||
setNull(parameterIndex, Types.OTHER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (x instanceof String)
|
|
||||||
setString(parameterIndex, (String)x);
|
|
||||||
else if (x instanceof BigDecimal)
|
|
||||||
setBigDecimal(parameterIndex, (BigDecimal)x);
|
|
||||||
else if (x instanceof Short)
|
|
||||||
setShort(parameterIndex, ((Short)x).shortValue());
|
|
||||||
else if (x instanceof Integer)
|
|
||||||
setInt(parameterIndex, ((Integer)x).intValue());
|
|
||||||
else if (x instanceof Long)
|
|
||||||
setLong(parameterIndex, ((Long)x).longValue());
|
|
||||||
else if (x instanceof Float)
|
|
||||||
setFloat(parameterIndex, ((Float)x).floatValue());
|
|
||||||
else if (x instanceof Double)
|
|
||||||
setDouble(parameterIndex, ((Double)x).doubleValue());
|
|
||||||
else if (x instanceof byte[])
|
|
||||||
setBytes(parameterIndex, (byte[])x);
|
|
||||||
else if (x instanceof java.sql.Date)
|
|
||||||
setDate(parameterIndex, (java.sql.Date)x);
|
|
||||||
else if (x instanceof Time)
|
|
||||||
setTime(parameterIndex, (Time)x);
|
|
||||||
else if (x instanceof Timestamp)
|
|
||||||
setTimestamp(parameterIndex, (Timestamp)x);
|
|
||||||
else if (x instanceof Boolean)
|
|
||||||
setBoolean(parameterIndex, ((Boolean)x).booleanValue());
|
|
||||||
else if (x instanceof PGobject)
|
|
||||||
setString(parameterIndex, ((PGobject)x).getValue());
|
|
||||||
else
|
|
||||||
setLong(parameterIndex, connection.storeObject(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some prepared statements return multiple results; the execute method
|
|
||||||
* handles these complex statements as well as the simpler form of
|
|
||||||
* statements handled by executeQuery and executeUpdate
|
|
||||||
*
|
|
||||||
* @return true if the next result is a ResultSet; false if it is an
|
|
||||||
* * update count or there are no more results
|
|
||||||
* @exception SQLException if a database access error occurs
|
|
||||||
*/
|
|
||||||
public boolean execute() throws SQLException
|
|
||||||
{
|
|
||||||
StringBuffer s = new StringBuffer();
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0 ; i < inStrings.length ; ++i)
|
|
||||||
{
|
|
||||||
if (inStrings[i] == null)
|
|
||||||
throw new PSQLException("postgresql.prep.param", new Integer(i + 1));
|
|
||||||
s.append (templateStrings[i]);
|
|
||||||
s.append (inStrings[i]);
|
|
||||||
}
|
|
||||||
s.append(templateStrings[inStrings.length]);
|
|
||||||
return super.execute(s.toString()); // in Statement class
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the SQL statement with the current template values
|
|
||||||
* substituted.
|
|
||||||
*/
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuffer s = new StringBuffer();
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0 ; i < inStrings.length ; ++i)
|
|
||||||
{
|
|
||||||
if (inStrings[i] == null)
|
|
||||||
s.append( '?' );
|
|
||||||
else
|
|
||||||
s.append (templateStrings[i]);
|
|
||||||
s.append (inStrings[i]);
|
|
||||||
}
|
|
||||||
s.append(templateStrings[inStrings.length]);
|
|
||||||
return s.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// **************************************************************
|
|
||||||
// END OF PUBLIC INTERFACE
|
|
||||||
// **************************************************************
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are a lot of setXXX classes which all basically do
|
|
||||||
* the same thing. We need a method which actually does the
|
|
||||||
* set for us.
|
|
||||||
*
|
|
||||||
* @param paramIndex the index into the inString
|
|
||||||
* @param s a string to be stored
|
|
||||||
* @exception SQLException if something goes wrong
|
|
||||||
*/
|
|
||||||
private void set(int paramIndex, String s) throws SQLException
|
|
||||||
{
|
|
||||||
if (paramIndex < 1 || paramIndex > inStrings.length)
|
|
||||||
throw new PSQLException("postgresql.prep.range");
|
|
||||||
inStrings[paramIndex - 1] = s;
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,14 +13,14 @@ import org.postgresql.largeobject.*;
|
|||||||
import org.postgresql.util.PGbytea;
|
import org.postgresql.util.PGbytea;
|
||||||
import org.postgresql.util.PSQLException;
|
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 $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.2 2002/07/24 22:08:42 barry Exp $
|
||||||
* This class defines methods of the jdbc2 specification. This class extends
|
* This class defines methods of the jdbc2 specification. This class extends
|
||||||
* org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1
|
* org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1
|
||||||
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet
|
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet
|
||||||
*/
|
*/
|
||||||
public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet
|
public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet
|
||||||
{
|
{
|
||||||
protected Jdbc2Statement statement;
|
protected Statement statement;
|
||||||
|
|
||||||
protected String sqlQuery=null;
|
protected String sqlQuery=null;
|
||||||
|
|
||||||
@ -373,7 +373,7 @@ public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This one needs some thought, as not all ResultSets come from a statement
|
// This one needs some thought, as not all ResultSets come from a statement
|
||||||
public java.sql.Statement getStatement() throws SQLException
|
public Statement getStatement() throws SQLException
|
||||||
{
|
{
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
@ -740,7 +740,7 @@ public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1Re
|
|||||||
* It's used currently by getStatement() but may also with the new core
|
* It's used currently by getStatement() but may also with the new core
|
||||||
* package.
|
* package.
|
||||||
*/
|
*/
|
||||||
public void setStatement(Jdbc2Statement statement)
|
public void setStatement(Statement statement)
|
||||||
{
|
{
|
||||||
this.statement = statement;
|
this.statement = statement;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package org.postgresql.jdbc2;
|
package org.postgresql.jdbc2;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
import org.postgresql.largeobject.*;
|
||||||
import org.postgresql.util.PSQLException;
|
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 $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.2 2002/07/24 22:08:42 barry Exp $
|
||||||
* This class defines methods of the jdbc2 specification. This class extends
|
* This class defines methods of the jdbc2 specification. This class extends
|
||||||
* org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1
|
* org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1
|
||||||
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement
|
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement
|
||||||
@ -17,6 +19,18 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
|
|||||||
protected int resultsettype; // the resultset type to return
|
protected int resultsettype; // the resultset type to return
|
||||||
protected int concurrency; // is it updateable or not?
|
protected int concurrency; // is it updateable or not?
|
||||||
|
|
||||||
|
public AbstractJdbc2Statement (AbstractJdbc2Connection c)
|
||||||
|
{
|
||||||
|
super(c);
|
||||||
|
resultsettype = java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
|
||||||
|
concurrency = java.sql.ResultSet.CONCUR_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractJdbc2Statement(AbstractJdbc2Connection connection, String sql) throws SQLException
|
||||||
|
{
|
||||||
|
super(connection, sql);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute a SQL statement that may return multiple results. We
|
* Execute a SQL statement that may return multiple results. We
|
||||||
* don't have to worry about this since we do not support multiple
|
* don't have to worry about this since we do not support multiple
|
||||||
@ -31,10 +45,9 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
|
|||||||
public boolean execute(String sql) throws SQLException
|
public boolean execute(String sql) throws SQLException
|
||||||
{
|
{
|
||||||
boolean l_return = super.execute(sql);
|
boolean l_return = super.execute(sql);
|
||||||
|
|
||||||
//Now do the jdbc2 specific stuff
|
//Now do the jdbc2 specific stuff
|
||||||
//required for ResultSet.getStatement() to work
|
//required for ResultSet.getStatement() to work
|
||||||
((AbstractJdbc2ResultSet)result).setStatement((Jdbc2Statement)this);
|
((AbstractJdbc2ResultSet)result).setStatement((Statement)this);
|
||||||
|
|
||||||
// Added this so that the Updateable resultset knows the query that gave this
|
// Added this so that the Updateable resultset knows the query that gave this
|
||||||
((AbstractJdbc2ResultSet)result).setSQLQuery(sql);
|
((AbstractJdbc2ResultSet)result).setSQLQuery(sql);
|
||||||
@ -139,4 +152,183 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
|
|||||||
resultsettype = value;
|
resultsettype = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addBatch() throws SQLException
|
||||||
|
{
|
||||||
|
addBatch(compileQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.sql.ResultSetMetaData getMetaData() throws SQLException
|
||||||
|
{
|
||||||
|
java.sql.ResultSet rs = getResultSet();
|
||||||
|
if (rs != null)
|
||||||
|
return rs.getMetaData();
|
||||||
|
|
||||||
|
// Does anyone really know what this method does?
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArray(int i, java.sql.Array x) throws SQLException
|
||||||
|
{
|
||||||
|
setString(i, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlob(int i, Blob x) throws SQLException
|
||||||
|
{
|
||||||
|
InputStream l_inStream = x.getBinaryStream();
|
||||||
|
int l_length = (int) x.length();
|
||||||
|
LargeObjectManager lom = connection.getLargeObjectAPI();
|
||||||
|
int oid = lom.create();
|
||||||
|
LargeObject lob = lom.open(oid);
|
||||||
|
OutputStream los = lob.getOutputStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// could be buffered, but then the OutputStream returned by LargeObject
|
||||||
|
// is buffered internally anyhow, so there would be no performance
|
||||||
|
// boost gained, if anything it would be worse!
|
||||||
|
int c = l_inStream.read();
|
||||||
|
int p = 0;
|
||||||
|
while (c > -1 && p < l_length)
|
||||||
|
{
|
||||||
|
los.write(c);
|
||||||
|
c = l_inStream.read();
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
los.close();
|
||||||
|
}
|
||||||
|
catch (IOException se)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", se);
|
||||||
|
}
|
||||||
|
// lob is closed by the stream so don't call lob.close()
|
||||||
|
setInt(i, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharacterStream(int i, java.io.Reader x, int length) throws SQLException
|
||||||
|
{
|
||||||
|
if (connection.haveMinimumCompatibleVersion("7.2"))
|
||||||
|
{
|
||||||
|
//Version 7.2 supports CharacterStream for for 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 varchar datatype, but with toast all the text datatypes are capable of
|
||||||
|
//handling very large values. Thus the implementation ends up calling
|
||||||
|
//setString() since there is no current way to stream the value to the server
|
||||||
|
char[] l_chars = new char[length];
|
||||||
|
int l_charsRead;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_charsRead = x.read(l_chars, 0, length);
|
||||||
|
}
|
||||||
|
catch (IOException l_ioe)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", l_ioe);
|
||||||
|
}
|
||||||
|
setString(i, new String(l_chars, 0, l_charsRead));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Version 7.1 only supported streams for LargeObjects
|
||||||
|
//but the jdbc spec indicates that streams should be
|
||||||
|
//available for LONGVARCHAR instead
|
||||||
|
LargeObjectManager lom = connection.getLargeObjectAPI();
|
||||||
|
int oid = lom.create();
|
||||||
|
LargeObject lob = lom.open(oid);
|
||||||
|
OutputStream los = lob.getOutputStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// could be buffered, but then the OutputStream returned by LargeObject
|
||||||
|
// is buffered internally anyhow, so there would be no performance
|
||||||
|
// boost gained, if anything it would be worse!
|
||||||
|
int c = x.read();
|
||||||
|
int p = 0;
|
||||||
|
while (c > -1 && p < length)
|
||||||
|
{
|
||||||
|
los.write(c);
|
||||||
|
c = x.read();
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
los.close();
|
||||||
|
}
|
||||||
|
catch (IOException se)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", se);
|
||||||
|
}
|
||||||
|
// lob is closed by the stream so don't call lob.close()
|
||||||
|
setInt(i, oid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClob(int i, Clob x) throws SQLException
|
||||||
|
{
|
||||||
|
InputStream l_inStream = x.getAsciiStream();
|
||||||
|
int l_length = (int) x.length();
|
||||||
|
LargeObjectManager lom = connection.getLargeObjectAPI();
|
||||||
|
int oid = lom.create();
|
||||||
|
LargeObject lob = lom.open(oid);
|
||||||
|
OutputStream los = lob.getOutputStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// could be buffered, but then the OutputStream returned by LargeObject
|
||||||
|
// is buffered internally anyhow, so there would be no performance
|
||||||
|
// boost gained, if anything it would be worse!
|
||||||
|
int c = l_inStream.read();
|
||||||
|
int p = 0;
|
||||||
|
while (c > -1 && p < l_length)
|
||||||
|
{
|
||||||
|
los.write(c);
|
||||||
|
c = l_inStream.read();
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
los.close();
|
||||||
|
}
|
||||||
|
catch (IOException se)
|
||||||
|
{
|
||||||
|
throw new PSQLException("postgresql.unusual", se);
|
||||||
|
}
|
||||||
|
// lob is closed by the stream so don't call lob.close()
|
||||||
|
setInt(i, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNull(int i, int t, String s) throws SQLException
|
||||||
|
{
|
||||||
|
setNull(i, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRef(int i, Ref x) throws SQLException
|
||||||
|
{
|
||||||
|
throw org.postgresql.Driver.notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(int i, java.sql.Date d, java.util.Calendar cal) throws SQLException
|
||||||
|
{
|
||||||
|
if (cal == null)
|
||||||
|
setDate(i, d);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cal.setTime(d);
|
||||||
|
setDate(i, new java.sql.Date(cal.getTime().getTime()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(int i, Time t, java.util.Calendar cal) throws SQLException
|
||||||
|
{
|
||||||
|
if (cal == null)
|
||||||
|
setTime(i, t);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cal.setTime(t);
|
||||||
|
setTime(i, new java.sql.Time(cal.getTime().getTime()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(int i, Timestamp t, java.util.Calendar cal) throws SQLException
|
||||||
|
{
|
||||||
|
if (cal == null)
|
||||||
|
setTimestamp(i, t);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cal.setTime(t);
|
||||||
|
setTimestamp(i, new java.sql.Timestamp(cal.getTime().getTime()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ import org.postgresql.util.*;
|
|||||||
* @author Paul Bethe (implementer)
|
* @author Paul Bethe (implementer)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement implements java.sql.CallableStatement
|
public class CallableStatement extends org.postgresql.jdbc2.Jdbc2PreparedStatement implements java.sql.CallableStatement
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @exception SQLException on failure
|
* @exception SQLException on failure
|
||||||
|
@ -5,7 +5,7 @@ import java.sql.*;
|
|||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import org.postgresql.Field;
|
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 $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.2 2002/07/24 22:08:42 barry Exp $
|
||||||
* This class implements the java.sql.Connection interface for JDBC2.
|
* This class implements the java.sql.Connection interface for JDBC2.
|
||||||
* However most of the implementation is really done in
|
* However most of the implementation is really done in
|
||||||
* org.postgresql.jdbc2.AbstractJdbc2Connection or one of it's parents
|
* org.postgresql.jdbc2.AbstractJdbc2Connection or one of it's parents
|
||||||
@ -24,7 +24,7 @@ public class Jdbc2Connection extends org.postgresql.jdbc2.AbstractJdbc2Connectio
|
|||||||
|
|
||||||
public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
|
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);
|
Jdbc2PreparedStatement s = new Jdbc2PreparedStatement(this, sql);
|
||||||
s.setResultSetType(resultSetType);
|
s.setResultSetType(resultSetType);
|
||||||
s.setResultSetConcurrency(resultSetConcurrency);
|
s.setResultSetConcurrency(resultSetConcurrency);
|
||||||
return s;
|
return s;
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package org.postgresql.jdbc2;
|
||||||
|
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class Jdbc2PreparedStatement extends AbstractJdbc2Statement implements java.sql.PreparedStatement
|
||||||
|
{
|
||||||
|
|
||||||
|
public Jdbc2PreparedStatement(Jdbc2Connection connection, String sql) throws SQLException
|
||||||
|
{
|
||||||
|
super(connection, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ package org.postgresql.jdbc2;
|
|||||||
|
|
||||||
import java.sql.*;
|
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 $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.2 2002/07/24 22:08:43 barry Exp $
|
||||||
* This class implements the java.sql.Statement interface for JDBC2.
|
* This class implements the java.sql.Statement interface for JDBC2.
|
||||||
* However most of the implementation is really done in
|
* However most of the implementation is really done in
|
||||||
* org.postgresql.jdbc2.AbstractJdbc2Statement or one of it's parents
|
* org.postgresql.jdbc2.AbstractJdbc2Statement or one of it's parents
|
||||||
@ -13,9 +13,7 @@ public class Jdbc2Statement extends org.postgresql.jdbc2.AbstractJdbc2Statement
|
|||||||
|
|
||||||
public Jdbc2Statement (Jdbc2Connection c)
|
public Jdbc2Statement (Jdbc2Connection c)
|
||||||
{
|
{
|
||||||
connection = c;
|
super(c);
|
||||||
resultsettype = java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
|
|
||||||
concurrency = java.sql.ResultSet.CONCUR_READ_ONLY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user