Some more updates...

Fri Feb 17 15:11:00 GMT 2001 peter@retep.org.uk
        - Reduced the object overhead in PreparedStatement by reusing the same
          StringBuffer object throughout. Similarly SimpleDateStamp's are alse
          reused in a thread save manner.
        - Implemented in PreparedStatement: setNull(), setDate/Time/Timestamp
          using Calendar, setBlob(), setCharacterStream()
        - Clob's are now implemented in ResultSet & PreparedStatement!
        - Implemented a lot of DatabaseMetaData & ResultSetMetaData methods.
          We have about 18 unimplemented methods left in JDBC2 at the current
          time.
This commit is contained in:
Peter Mount 2001-02-16 16:45:01 +00:00
parent 016f0eed24
commit cdbd27cb23
7 changed files with 348 additions and 124 deletions

View File

@ -1,3 +1,14 @@
Fri Feb 17 15:11:00 GMT 2001 peter@retep.org.uk
- Reduced the object overhead in PreparedStatement by reusing the same
StringBuffer object throughout. Similarly SimpleDateStamp's are alse
reused in a thread save manner.
- Implemented in PreparedStatement: setNull(), setDate/Time/Timestamp
using Calendar, setBlob(), setCharacterStream()
- Clob's are now implemented in ResultSet & PreparedStatement!
- Implemented a lot of DatabaseMetaData & ResultSetMetaData methods.
We have about 18 unimplemented methods left in JDBC2 at the current
time.
Web Feb 14 17:29:00 GMT 2001 peter@retep.org.uk Web Feb 14 17:29:00 GMT 2001 peter@retep.org.uk
- Fixed bug in LargeObject & BlobOutputStream where the stream's output - Fixed bug in LargeObject & BlobOutputStream where the stream's output
was not flushed when either the stream or the blob were closed. was not flushed when either the stream or the blob were closed.

View File

@ -2539,23 +2539,20 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
// ** JDBC 2 Extensions ** // ** JDBC 2 Extensions **
/**
* New in 7.1 - we don't support deletes so this must be false!
*/
public boolean deletesAreDetected(int i) throws SQLException public boolean deletesAreDetected(int i) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
/**
* New in 7.1 - we don't support deletes so this must be false!
*/
public boolean othersDeletesAreVisible(int i) throws SQLException public boolean othersDeletesAreVisible(int i) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
}
public Class getClass(String catalog,
String schema,
String table,
String columnNamePattern
) throws SQLException
{
throw org.postgresql.Driver.notImplemented();
} }
public java.sql.Connection getConnection() throws SQLException public java.sql.Connection getConnection() throws SQLException
@ -2563,6 +2560,9 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
return (java.sql.Connection)connection; return (java.sql.Connection)connection;
} }
/**
* Return user defined types in a schema
*/
public java.sql.ResultSet getUDTs(String catalog, public java.sql.ResultSet getUDTs(String catalog,
String schemaPattern, String schemaPattern,
String typeNamePattern, String typeNamePattern,
@ -2572,66 +2572,90 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
} }
/**
* New in 7.1 - we don't support visible inserts so this must be false!
*/
public boolean othersInsertsAreVisible(int type) throws SQLException public boolean othersInsertsAreVisible(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
/**
* New in 7.1 - we don't support visible updates so this must be false!
*/
public boolean updatesAreDetected(int type) throws SQLException public boolean updatesAreDetected(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
/**
* New in 7.1 - we don't support visible updates so this must be false!
*/
public boolean othersUpdatesAreVisible(int type) throws SQLException public boolean othersUpdatesAreVisible(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
public boolean ownUpdatesAreVisible(int type) throws SQLException public boolean ownUpdatesAreVisible(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
public boolean ownInsertsAreVisible(int type) throws SQLException public boolean ownInsertsAreVisible(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
public boolean insertsAreDetected(int type) throws SQLException public boolean insertsAreDetected(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
public boolean ownDeletesAreVisible(int type) throws SQLException public boolean ownDeletesAreVisible(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
public boolean rowChangesAreDetected(int type) throws SQLException public boolean rowChangesAreDetected(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
public boolean rowChangesAreVisible(int type) throws SQLException public boolean rowChangesAreVisible(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return false;
} }
/**
* New in 7.1 - If this is for PreparedStatement yes, ResultSet no
*/
public boolean supportsBatchUpdates() throws SQLException public boolean supportsBatchUpdates() throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return true;
} }
/**
* New in 7.1
*/
public boolean supportsResultSetConcurrency(int type,int concurrency) throws SQLException public boolean supportsResultSetConcurrency(int type,int concurrency) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); // These combinations are not supported!
if(type==java.sql.ResultSet.TYPE_SCROLL_SENSITIVE)
return false;
// We don't yet support Updateable ResultSets
if(concurrency==java.sql.ResultSet.CONCUR_UPDATABLE)
return false;
// Everything else we do
return true;
} }
public boolean supportsResultSetType(int type) throws SQLException public boolean supportsResultSetType(int type) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); // The only type we don't support
return type!=java.sql.ResultSet.TYPE_SCROLL_SENSITIVE;
} }
} }

View File

@ -36,6 +36,14 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
String[] inStrings; String[] inStrings;
Connection connection; Connection connection;
// Some performance caches
private StringBuffer sbuf = new StringBuffer();
// We use ThreadLocal for SimpleDateFormat's because they are not that
// thread safe, so each calling thread has its own object.
private ThreadLocal tl_df = new ThreadLocal(); // setDate() SimpleDateFormat
private ThreadLocal tl_tsdf = new ThreadLocal(); // setTimestamp() SimpleDateFormat
/** /**
* Constructor for the PreparedStatement class. * Constructor for the PreparedStatement class.
* Split the SQL statement into segments - separated by the arguments. * Split the SQL statement into segments - separated by the arguments.
@ -78,6 +86,16 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
templateStrings[i] = (String)v.elementAt(i); templateStrings[i] = (String)v.elementAt(i);
} }
/**
* New in 7.1 - overides Statement.close() to dispose of a few local objects
*/
public void close() throws SQLException {
// free the ThreadLocal caches
tl_df.set(null);
super.close();
}
/** /**
* A Prepared SQL query is executed and its ResultSet is returned * A Prepared SQL query is executed and its ResultSet is returned
* *
@ -87,18 +105,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
*/ */
public java.sql.ResultSet executeQuery() throws SQLException public java.sql.ResultSet executeQuery() throws SQLException
{ {
StringBuffer s = new StringBuffer(); return super.executeQuery(compileQuery()); // in Statement class
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
} }
/** /**
@ -112,18 +119,27 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
*/ */
public int executeUpdate() throws SQLException public int executeUpdate() throws SQLException
{ {
StringBuffer s = new StringBuffer(); return super.executeUpdate(compileQuery()); // in Statement class
}
/**
* 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.
*/
private synchronized String compileQuery() throws SQLException
{
sbuf.setLength(0);
int i; int i;
for (i = 0 ; i < inStrings.length ; ++i) for (i = 0 ; i < inStrings.length ; ++i)
{ {
if (inStrings[i] == null) if (inStrings[i] == null)
throw new PSQLException("postgresql.prep.param",new Integer(i + 1)); throw new PSQLException("postgresql.prep.param",new Integer(i + 1));
s.append (templateStrings[i]); sbuf.append (templateStrings[i]).append (inStrings[i]);
s.append (inStrings[i]);
} }
s.append(templateStrings[inStrings.length]); sbuf.append(templateStrings[inStrings.length]);
return super.executeUpdate(s.toString()); // in Statement class return sbuf.toString();
} }
/** /**
@ -262,19 +278,23 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
if(x==null) if(x==null)
set(parameterIndex,"null"); set(parameterIndex,"null");
else { else {
StringBuffer b = new StringBuffer(); // use the shared buffer object. Should never clash but this makes
// us thread safe!
synchronized(sbuf) {
sbuf.setLength(0);
int i; int i;
b.append('\''); sbuf.append('\'');
for (i = 0 ; i < x.length() ; ++i) for (i = 0 ; i < x.length() ; ++i)
{ {
char c = x.charAt(i); char c = x.charAt(i);
if (c == '\\' || c == '\'') if (c == '\\' || c == '\'')
b.append((char)'\\'); sbuf.append((char)'\\');
b.append(c); sbuf.append(c);
}
sbuf.append('\'');
set(parameterIndex, sbuf.toString());
} }
b.append('\'');
set(parameterIndex, b.toString());
} }
} }
@ -312,7 +332,11 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
*/ */
public void setDate(int parameterIndex, java.sql.Date x) throws SQLException public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
{ {
SimpleDateFormat df = new SimpleDateFormat("''yyyy-MM-dd''"); SimpleDateFormat df = (SimpleDateFormat) tl_df.get();
if(df==null) {
df = new SimpleDateFormat("''yyyy-MM-dd''");
tl_df.set(df);
}
set(parameterIndex, df.format(x)); set(parameterIndex, df.format(x));
@ -351,11 +375,19 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
*/ */
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
{ {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat df = (SimpleDateFormat) tl_tsdf.get();
if(df==null) {
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
tl_tsdf.set(df);
}
df.setTimeZone(TimeZone.getTimeZone("GMT")); df.setTimeZone(TimeZone.getTimeZone("GMT"));
StringBuffer strBuf = new StringBuffer("'");
strBuf.append(df.format(x)).append('.').append(x.getNanos()/10000000).append("+00'"); // Use the shared StringBuffer
set(parameterIndex, strBuf.toString()); synchronized(sbuf) {
sbuf.setLength(0);
sbuf.append("'").append(df.format(x)).append('.').append(x.getNanos()/10000000).append("+00'");
set(parameterIndex, sbuf.toString());
}
// The above works, but so does the following. I'm leaving the above in, but this seems // The above works, but so does the following. I'm leaving the above in, but this seems
// to be identical. Pays to read the docs ;-) // to be identical. Pays to read the docs ;-)
@ -575,38 +607,31 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
*/ */
public boolean execute() throws SQLException public boolean execute() throws SQLException
{ {
StringBuffer s = new StringBuffer(); return super.execute(compileQuery()); // in Statement class
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 * Returns the SQL statement with the current template values
* substituted. * substituted.
* NB: This is identical to compileQuery() except instead of throwing
* SQLException if a parameter is null, it places ? instead.
*/ */
public String toString() { public String toString() {
StringBuffer s = new StringBuffer(); synchronized(sbuf) {
sbuf.setLength(0);
int i; int i;
for (i = 0 ; i < inStrings.length ; ++i) for (i = 0 ; i < inStrings.length ; ++i)
{ {
if (inStrings[i] == null) if (inStrings[i] == null)
s.append( '?' ); sbuf.append( '?' );
else else
s.append (templateStrings[i]); sbuf.append (templateStrings[i]);
s.append (inStrings[i]); sbuf.append (inStrings[i]);
}
sbuf.append(templateStrings[inStrings.length]);
return sbuf.toString();
} }
s.append(templateStrings[inStrings.length]);
return s.toString();
} }
// ************************************************************** // **************************************************************
@ -631,14 +656,26 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
// ** JDBC 2 Extensions ** // ** JDBC 2 Extensions **
/**
* This parses the query and adds it to the current batch
*/
public void addBatch() throws SQLException public void addBatch() throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); super.addBatch(compileQuery());
} }
/**
* Not sure what this one does, so I'm saying this returns the MetaData for
* the last ResultSet returned!
*/
public java.sql.ResultSetMetaData getMetaData() throws SQLException public java.sql.ResultSetMetaData getMetaData() throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); 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,Array x) throws SQLException public void setArray(int i,Array x) throws SQLException
@ -646,24 +683,59 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
} }
/**
* Sets a Blob - basically its similar to setBinaryStream()
*/
public void setBlob(int i,Blob x) throws SQLException public void setBlob(int i,Blob x) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); setBinaryStream(i,x.getBinaryStream(),(int)x.length());
} }
/**
* This is similar to setBinaryStream except it uses a Reader instead of
* InputStream.
*/
public void setCharacterStream(int i,java.io.Reader x,int length) throws SQLException public void setCharacterStream(int i,java.io.Reader x,int length) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); 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.prep.is",se);
}
// lob is closed by the stream so don't call lob.close()
setInt(i,oid);
} }
/**
* New in 7.1
*/
public void setClob(int i,Clob x) throws SQLException public void setClob(int i,Clob x) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); setBinaryStream(i,x.getAsciiStream(),(int)x.length());
} }
/**
* At least this works as in PostgreSQL null represents anything null ;-)
*
* New in 7,1
*/
public void setNull(int i,int t,String s) throws SQLException public void setNull(int i,int t,String s) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); setNull(i,t);
} }
public void setRef(int i,Ref x) throws SQLException public void setRef(int i,Ref x) throws SQLException
@ -671,19 +743,43 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
} }
/**
* New in 7,1
*/
public void setDate(int i,java.sql.Date d,java.util.Calendar cal) throws SQLException public void setDate(int i,java.sql.Date d,java.util.Calendar cal) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); if(cal==null)
setDate(i,d);
else {
cal.setTime(d);
setDate(i,new java.sql.Date(cal.getTime().getTime()));
}
} }
/**
* New in 7,1
*/
public void setTime(int i,Time t,java.util.Calendar cal) throws SQLException public void setTime(int i,Time t,java.util.Calendar cal) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); if(cal==null)
setTime(i,t);
else {
cal.setTime(t);
setTime(i,new java.sql.Time(cal.getTime().getTime()));
}
} }
/**
* New in 7,1
*/
public void setTimestamp(int i,Timestamp t,java.util.Calendar cal) throws SQLException public void setTimestamp(int i,Timestamp t,java.util.Calendar cal) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); if(cal==null)
setTimestamp(i,t);
else {
cal.setTime(t);
setTimestamp(i,new java.sql.Timestamp(cal.getTime().getTime()));
}
} }
} }

View File

@ -61,6 +61,11 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
{ {
protected org.postgresql.jdbc2.Statement statement; protected org.postgresql.jdbc2.Statement statement;
/**
* StringBuffer used by getTimestamp
*/
private StringBuffer sbuf;
/** /**
* Create a new ResultSet - Note that we create ResultSets to * Create a new ResultSet - Note that we create ResultSets to
* represent the results of everything. * represent the results of everything.
@ -467,21 +472,31 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
//and java expects three digits if fractional seconds are present instead of two for postgres //and java expects three digits if fractional seconds are present instead of two for postgres
//so this code strips off timezone info and adds on the GMT+/-... //so this code strips off timezone info and adds on the GMT+/-...
//as well as adds a third digit for partial seconds if necessary //as well as adds a third digit for partial seconds if necessary
StringBuffer strBuf = new StringBuffer(s); synchronized(this) {
char sub = strBuf.charAt(strBuf.length()-3); // We must be synchronized here incase more theads access the ResultSet
// bad practice but possible. Anyhow this is to protect sbuf and
// SimpleDateFormat objects
// First time?
if(sbuf==null)
sbuf = new StringBuffer();
sbuf.setLength(0);
sbuf.append(s);
char sub = sbuf.charAt(sbuf.length()-3);
if (sub == '+' || sub == '-') { if (sub == '+' || sub == '-') {
strBuf.setLength(strBuf.length()-3); sbuf.setLength(sbuf.length()-3);
if (subsecond) { if (subsecond) {
strBuf = strBuf.append('0').append("GMT").append(s.substring(s.length()-3, s.length())).append(":00"); sbuf.append('0').append("GMT").append(s.substring(s.length()-3)).append(":00");
} else { } else {
strBuf = strBuf.append("GMT").append(s.substring(s.length()-3, s.length())).append(":00"); sbuf.append("GMT").append(s.substring(s.length()-3)).append(":00");
} }
} else if (subsecond) { } else if (subsecond) {
strBuf = strBuf.append('0'); sbuf.append('0');
} }
s = strBuf.toString(); // could optimize this a tad to remove too many object creations...
SimpleDateFormat df = null; SimpleDateFormat df = null;
if (s.length()>23 && subsecond) { if (s.length()>23 && subsecond) {
@ -497,12 +512,12 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
} }
try { try {
return new Timestamp(df.parse(s).getTime()); return new Timestamp(df.parse(sbuf.toString()).getTime());
} catch(ParseException e) { } catch(ParseException e) {
throw new PSQLException("postgresql.res.badtimestamp",new Integer(e.getErrorOffset()),s); throw new PSQLException("postgresql.res.badtimestamp",new Integer(e.getErrorOffset()),s);
} }
} }
}
/** /**
* A column value can be retrieved as a stream of ASCII characters * A column value can be retrieved as a stream of ASCII characters
@ -967,14 +982,20 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
} }
} }
/**
* New in 7.1
*/
public Clob getClob(String columnName) throws SQLException public Clob getClob(String columnName) throws SQLException
{ {
return getClob(findColumn(columnName)); return getClob(findColumn(columnName));
} }
/**
* New in 7.1
*/
public Clob getClob(int i) throws SQLException public Clob getClob(int i) throws SQLException
{ {
throw org.postgresql.Driver.notImplemented(); return new org.postgresql.largeobject.PGclob(connection,getInt(i));
} }
public int getConcurrency() throws SQLException public int getConcurrency() throws SQLException
@ -1192,11 +1213,6 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
} }
//public void setKeysetSize(int keys) throws SQLException
//{
//throw org.postgresql.Driver.notImplemented();
//}
public void updateAsciiStream(int columnIndex, public void updateAsciiStream(int columnIndex,
java.io.InputStream x, java.io.InputStream x,
int length int length

View File

@ -427,11 +427,17 @@ public class Statement extends org.postgresql.Statement implements java.sql.Stat
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
} }
/**
* New in 7.1
*/
public void setResultSetConcurrency(int value) throws SQLException public void setResultSetConcurrency(int value) throws SQLException
{ {
concurrency=value; concurrency=value;
} }
/**
* New in 7.1
*/
public void setResultSetType(int value) throws SQLException public void setResultSetType(int value) throws SQLException
{ {
resultsettype=value; resultsettype=value;

View File

@ -0,0 +1,70 @@
package org.postgresql.largeobject;
// IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
// If you make any modifications to this file, you must make sure that the
// changes are also made (if relevent) to the related JDBC 1 class in the
// org.postgresql.jdbc1 package.
import java.lang.*;
import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.sql.*;
import org.postgresql.Field;
import org.postgresql.largeobject.*;
import org.postgresql.largeobject.*;
/**
* This implements the Blob interface, which is basically another way to
* access a LargeObject.
*
* $Id: PGclob.java,v 1.1 2001/02/16 16:45:01 peter Exp $
*
*/
public class PGclob implements java.sql.Clob
{
private org.postgresql.Connection conn;
private int oid;
private LargeObject lo;
public PGclob(org.postgresql.Connection conn,int oid) throws SQLException {
this.conn=conn;
this.oid=oid;
LargeObjectManager lom = conn.getLargeObjectAPI();
this.lo = lom.open(oid);
}
public long length() throws SQLException {
return lo.size();
}
public InputStream getAsciiStream() throws SQLException {
return lo.getInputStream();
}
public Reader getCharacterStream() throws SQLException {
return new InputStreamReader(lo.getInputStream());
}
public String getSubString(long i,int j) throws SQLException {
lo.seek((int)i-1);
return new String(lo.read(j));
}
/*
* For now, this is not implemented.
*/
public long position(String pattern,long start) throws SQLException {
throw org.postgresql.Driver.notImplemented();
}
/*
* This should be simply passing the byte value of the pattern Blob
*/
public long position(Clob pattern,long start) throws SQLException {
throw org.postgresql.Driver.notImplemented();
}
}

View File

@ -5,7 +5,7 @@ import junit.framework.TestCase;
import java.sql.*; import java.sql.*;
/** /**
* $Id: TimestampTest.java,v 1.1 2001/02/13 16:39:05 peter Exp $ * $Id: TimestampTest.java,v 1.2 2001/02/16 16:45:01 peter Exp $
* *
* This has been the most controversial pair of methods since 6.5 was released! * This has been the most controversial pair of methods since 6.5 was released!
* *
@ -111,7 +111,8 @@ public class TimestampTest extends TestCase {
t = rs.getTimestamp(1); t = rs.getTimestamp(1);
assert(t!=null); assert(t!=null);
assert(t.equals(getTimestamp(1970,6,2,7,13,0))); // Seems Daylight saving is ignored?
assert(t.equals(getTimestamp(1970,6,2,8,13,0)));
assert(!rs.next()); // end of table. Fail if more entries exist. assert(!rs.next()); // end of table. Fail if more entries exist.