You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2010/12/22 16:02:58 UTC
svn commit: r1051937 - in /db/derby/code/trunk/java:
client/org/apache/derby/client/am/ client/org/apache/derby/client/net/
engine/org/apache/derby/impl/jdbc/
testing/org/apache/derbyTesting/functionTests/tests/jdbc4/
Author: rhillegas
Date: Wed Dec 22 15:02:57 2010
New Revision: 1051937
URL: http://svn.apache.org/viewvc?rev=1051937&view=rev
Log:
DERBY-4869: JDBC 4.1: Add new getObject() overloads to ResultSet implementations.
Modified:
db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet40.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet40.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=1051937&r1=1051936&r2=1051937&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Wed Dec 22 15:02:57 2010
@@ -1938,7 +1938,7 @@ public abstract class ResultSet implemen
}
// An untraced version of findColumn()
- private final int findColumnX(String columnName, String operation) throws SqlException {
+ protected final int findColumnX(String columnName, String operation) throws SqlException {
checkForClosedResultSet(operation);
return resultSetMetaData_.findColumnX(columnName);
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet40.java?rev=1051937&r1=1051936&r2=1051937&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet40.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet40.java Wed Dec 22 15:02:57 2010
@@ -23,10 +23,17 @@ package org.apache.derby.client.net;
import java.io.InputStream;
import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
import java.sql.NClob;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.SQLFeatureNotSupportedException;
import org.apache.derby.client.am.SQLExceptionFactory;
import org.apache.derby.iapi.sql.ResultSet;
import org.apache.derby.client.am.Cursor;
@@ -245,4 +252,72 @@ public class NetResultSet40 extends NetR
throws SQLException {
throw SQLExceptionFactory.notImplemented("updateNClob(String,Reader,long)");
}
+
+ ////////////////////////////////////////////////////////////////////
+ //
+ // INTRODUCED BY JDBC 4.1 IN JAVA 7
+ //
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Retrieve the column as an object of the desired type.
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T getObject( int columnIndex, Class<T> type )
+ throws SQLException
+ {
+ // closeCloseFilterInputStream() should be called by all of the
+ // more specific methods to which we forward this call
+
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceEntry(this, "getObject", columnIndex );
+ }
+
+ if ( type == null )
+ {
+ throw new SQLException( "NULL", SQLState.LANG_DATA_TYPE_GET_MISMATCH );
+ }
+
+ Exception ex = null;
+
+ try {
+ if ( String.class.equals( type ) ) { return (T) getString( columnIndex ); }
+ else if ( BigDecimal.class.equals( type ) ) { return (T) getBigDecimal( columnIndex ); }
+ else if ( Boolean.class.equals( type ) ) { return (T) Boolean.valueOf( getBoolean(columnIndex ) ); }
+ else if ( Byte.class.equals( type ) ) { return (T) Byte.valueOf( getByte( columnIndex ) ); }
+ else if ( Short.class.equals( type ) ) { return (T) Short.valueOf( getShort( columnIndex ) ); }
+ else if ( Integer.class.equals( type ) ) { return (T) Integer.valueOf( getInt( columnIndex ) ); }
+ else if ( Long.class.equals( type ) ) { return (T) Long.valueOf( getLong( columnIndex ) ); }
+ else if ( Float.class.equals( type ) ) { return (T) Float.valueOf( getFloat( columnIndex ) ); }
+ else if ( Double.class.equals( type ) ) { return (T) Double.valueOf( getDouble( columnIndex ) ); }
+ else if ( Date.class.equals( type ) ) { return (T) getDate( columnIndex ); }
+ else if ( Time.class.equals( type ) ) { return (T) getTime( columnIndex ); }
+ else if ( Timestamp.class.equals( type ) ) { return (T) getTimestamp( columnIndex ); }
+ else if ( Blob.class.equals( type ) ) { return (T) getBlob( columnIndex ); }
+ else if ( Clob.class.equals( type ) ) { return (T) getClob( columnIndex ); }
+ else if ( type.isArray() && type.getComponentType().equals( byte.class ) ) { return (T) getBytes( columnIndex ); }
+ else { return (T) getObject( columnIndex ); }
+ }
+ catch (ClassCastException e) {}
+
+ throw new SQLException( type.getName(), SQLState.LANG_DATA_TYPE_GET_MISMATCH, ex );
+ }
+
+ public <T> T getObject( String columnName, Class<T> type )
+ throws SQLException
+ {
+ try
+ {
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceEntry(this, "getObject", columnName);
+ }
+ return getObject( findColumnX(columnName, "getObject"), type );
+ }
+ catch ( SqlException se )
+ {
+ throw se.getSQLException();
+ }
+ }
+
+
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet40.java?rev=1051937&r1=1051936&r2=1051937&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet40.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet40.java Wed Dec 22 15:02:57 2010
@@ -24,11 +24,18 @@ package org.apache.derby.impl.jdbc;
import org.apache.derby.iapi.sql.ResultSet;
import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
import java.sql.NClob;
import java.sql.RowId;
import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
import org.apache.derby.iapi.reference.SQLState;
@@ -233,4 +240,59 @@ public class EmbedResultSet40 extends or
throws SQLException{
throw Util.notImplemented();
}
+
+ ////////////////////////////////////////////////////////////////////
+ //
+ // INTRODUCED BY JDBC 4.1 IN JAVA 7
+ //
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Retrieve the column as an object of the desired type.
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T getObject( int columnIndex, Class<T> type )
+ throws SQLException
+ {
+ checkIfClosed("getObject");
+
+ if ( type == null )
+ {
+ throw new SQLException( "NULL", SQLState.LANG_DATA_TYPE_GET_MISMATCH );
+ }
+
+ Exception ex = null;
+
+ try {
+ if ( String.class.equals( type ) ) { return (T) getString( columnIndex ); }
+ else if ( BigDecimal.class.equals( type ) ) { return (T) getBigDecimal( columnIndex ); }
+ else if ( Boolean.class.equals( type ) ) { return (T) Boolean.valueOf( getBoolean(columnIndex ) ); }
+ else if ( Byte.class.equals( type ) ) { return (T) Byte.valueOf( getByte( columnIndex ) ); }
+ else if ( Short.class.equals( type ) ) { return (T) Short.valueOf( getShort( columnIndex ) ); }
+ else if ( Integer.class.equals( type ) ) { return (T) Integer.valueOf( getInt( columnIndex ) ); }
+ else if ( Long.class.equals( type ) ) { return (T) Long.valueOf( getLong( columnIndex ) ); }
+ else if ( Float.class.equals( type ) ) { return (T) Float.valueOf( getFloat( columnIndex ) ); }
+ else if ( Double.class.equals( type ) ) { return (T) Double.valueOf( getDouble( columnIndex ) ); }
+ else if ( Date.class.equals( type ) ) { return (T) getDate( columnIndex ); }
+ else if ( Time.class.equals( type ) ) { return (T) getTime( columnIndex ); }
+ else if ( Timestamp.class.equals( type ) ) { return (T) getTimestamp( columnIndex ); }
+ else if ( Blob.class.equals( type ) ) { return (T) getBlob( columnIndex ); }
+ else if ( Clob.class.equals( type ) ) { return (T) getClob( columnIndex ); }
+ else if ( type.isArray() && type.getComponentType().equals( byte.class ) ) { return (T) getBytes( columnIndex ); }
+ else { return (T) getObject( columnIndex ); }
+ }
+ catch (ClassCastException e) { ex = e; }
+
+ throw new SQLException( type.getName(), SQLState.LANG_DATA_TYPE_GET_MISMATCH, ex );
+ }
+
+ public <T> T getObject( String columnName, Class<T> type )
+ throws SQLException
+ {
+ checkIfClosed("getObject");
+
+ return getObject( findColumn( columnName ), type );
+ }
+
+
}
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java?rev=1051937&r1=1051936&r2=1051937&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java Wed Dec 22 15:02:57 2010
@@ -21,6 +21,7 @@
package org.apache.derbyTesting.functionTests.tests.jdbc4;
+import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
@@ -29,9 +30,12 @@ import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Blob;
import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLException;
-import java.sql.NClob;
+import java.sql.Time;
+import java.sql.Timestamp;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringReader;
@@ -46,20 +50,64 @@ import junit.framework.Test;
import junit.framework.TestSuite;
import junit.extensions.TestSetup;
+import org.apache.derby.impl.jdbc.EmbedResultSet40;
+import org.apache.derby.client.net.NetResultSet40;
+
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
import org.apache.derbyTesting.junit.BaseJDBCTestSetup;
import org.apache.derbyTesting.junit.TestConfiguration;
/**
- * Tests of JDBC4 features in ResultSet.
+ * Tests of JDBC4 and JDBC4.1 features in ResultSet.
*
* Some utility methods have been introduced for the updateXXX test-methods.
* This test also makes use of a TestSetup wrapper to perform one-time
* setup and teardown for the whole suite.
*/
public class ResultSetTest
- extends BaseJDBCTestCase {
+ extends BaseJDBCTestCase
+{
+ //
+ // Wrapper class for testing JDBC 4.1 functionality.
+ //
+ // This wrapper can be removed after Java 7 goes GA and we are allowed
+ // to use the Java 7 compiler to build derbyTesting.jar.
+ //
+ public static final class Wrapper41
+ {
+ private EmbedResultSet40 _embedded;
+ private NetResultSet40 _netclient;
+
+ public Wrapper41( ResultSet rs ) throws Exception
+ {
+ if ( rs instanceof EmbedResultSet40 ) { _embedded = (EmbedResultSet40) rs; }
+ else if ( rs instanceof NetResultSet40 ) { _netclient = (NetResultSet40) rs; }
+ else { throw nothingWrapped(); }
+ }
+
+ public <T> T getObject( int columnIndex, Class<T> type ) throws SQLException
+ {
+ if ( _embedded != null ) { return _embedded.getObject( columnIndex, type ); }
+ else if ( _netclient != null ) { return _netclient.getObject( columnIndex, type ); }
+ else { throw nothingWrapped(); }
+ }
+ public <T> T getObject( String columnName, Class<T> type )
+ throws SQLException
+ {
+ if ( _embedded != null ) { return _embedded.getObject( columnName, type ); }
+ else if ( _netclient != null ) { return _netclient.getObject( columnName, type ); }
+ else { throw nothingWrapped(); }
+ }
+
+ private SQLException nothingWrapped() { return new SQLException( "Nothing wrapped!" ); }
+ }
+
+ private static final String UNSUPPORTED_COERCION = "22005";
+ private static final String BAD_FORMAT = "22018";
+ private static final String BAD_DATETIME = "22007";
+
+ private static final String VARIABLE_STRING = "XXXXX";
private static final byte[] BYTES1 = {
0x65, 0x66, 0x67, 0x68, 0x69,
@@ -89,6 +137,8 @@ public class ResultSetTest
/** Default row identifier used by the tests. */
private int key = -1;
+ private Class byteArrayClass;
+
/**
* Create test with given name.
*
@@ -1968,5 +2018,644 @@ public class ResultSetTest
rs.close();
stmt.executeUpdate("DROP TABLE T1368");
}
+
+ /**
+ * Test the JDBC 4.1 extensions.
+ */
+ public void testJDBC4_1() throws Exception
+ {
+ Connection conn = getConnection();
+ PreparedStatement ps = prepareStatement
+ (
+ conn,
+ "create function makeBlob( a varchar( 32670 ) ) returns blob\n" +
+ "language java parameter style java no sql deterministic\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.AnsiSignatures.blob_Blob_String'\n"
+ );
+ ps.execute();
+ ps.close();
+
+ vetDataTypeCount( conn );
+
+ ps = prepareStatement
+ (
+ conn,
+ "create table allTypes\n" +
+ "(\n" +
+ " bigintCol bigint,\n" +
+ " blobCol blob,\n" +
+ " booleanCol boolean,\n" +
+ " charCol char(1),\n" +
+ " charForBitDataCol char(1) for bit data,\n" +
+ " clobCol clob,\n" +
+ " dateCol date,\n" +
+ " doubleCol double,\n" +
+ " floatCol float,\n" +
+ " intCol int,\n" +
+ " longVarcharCol long varchar,\n" +
+ " longVarcharForBitDataCol long varchar for bit data,\n" +
+ " numericCol numeric,\n" +
+ " realCol real,\n" +
+ " smallintCol smallint,\n" +
+ " timeCol time,\n" +
+ " timestampCol timestamp,\n" +
+ " varcharCol varchar( 2 ),\n" +
+ " varcharForBitDataCol varchar( 2 ) for bit data\n" +
+ ")\n"
+ );
+ ps.execute();
+ ps.close();
+
+ ps = prepareStatement
+ (
+ conn,
+ "insert into allTypes\n" +
+ "(\n" +
+ " bigintCol,\n" +
+ " blobCol,\n" +
+ " booleanCol,\n" +
+ " charCol,\n" +
+ " charForBitDataCol,\n" +
+ " clobCol,\n" +
+ " dateCol,\n" +
+ " doubleCol,\n" +
+ " floatCol,\n" +
+ " intCol,\n" +
+ " longVarcharCol,\n" +
+ " longVarcharForBitDataCol,\n" +
+ " numericCol,\n" +
+ " realCol,\n" +
+ " smallintCol,\n" +
+ " timeCol,\n" +
+ " timestampCol,\n" +
+ " varcharCol,\n" +
+ " varcharForBitDataCol\n" +
+ ")\n" +
+ "values\n" +
+ "(\n" +
+ " 1,\n" +
+ " makeBlob( 'abc' ),\n" +
+ " true,\n" +
+ " 'a',\n" +
+ " X'DE',\n" +
+ " 'abc',\n" +
+ " date('1994-02-23'),\n" +
+ " 1.0,\n" +
+ " 1.0,\n" +
+ " 1,\n" +
+ " 'a',\n" +
+ " X'DE',\n" +
+ " 1.0,\n" +
+ " 1.0,\n" +
+ " 1,\n" +
+ " time('15:09:02'),\n" +
+ " timestamp('1962-09-23 03:23:34.234'),\n" +
+ " 'a',\n" +
+ " X'DE'\n" +
+ ")\n"
+ );
+ ps.executeUpdate();
+ ps.close();
+
+ ps = prepareStatement( conn, "select * from allTypes" );
+ ResultSet rs = ps.executeQuery();
+ rs.next();
+ examineJDBC4_1extensions( rs );
+ rs.close();
+ ps.close();
+
+ ps = prepareStatement( conn, "drop table allTypes" );
+ ps.execute();
+ ps.close();
+ ps = prepareStatement( conn, "drop function makeBlob" );
+ ps.execute();
+ ps.close();
+ }
+ private void vetDataTypeCount( Connection conn ) throws Exception
+ {
+ ResultSet rs = conn.getMetaData().getTypeInfo();
+ int actualTypeCount = 0;
+ while ( rs.next() ) { actualTypeCount++; }
+ rs.close();
+
+ //
+ // If this assertion fails, that means that another data type has been added
+ // to Derby. You need to add that datatype to the allTypes table created
+ // by testJDBC4_1() and you need to add a verification case to examineJDBC4_1extensions().
+ //
+ assertEquals( 22, actualTypeCount );
+ }
+ private void examineJDBC4_1extensions( ResultSet rs ) throws Exception
+ {
+ Wrapper41 wrapper = new Wrapper41( rs );
+
+ println( "Vetting a " + rs.getClass().getName() );
+
+ byteArrayClass = Class.forName( "[B" );
+
+ vetWrappedNull( wrapper );
+ vetWrappedInteger( wrapper, 1, "BIGINTCOL" );
+ vetWrappedBlob( wrapper );
+ vetWrappedBoolean( wrapper );
+ vetWrappedString( wrapper, 4, "CHARCOL" );
+ vetWrappedBinary( wrapper, 5, "CHARFORBITDATACOL" );
+ vetWrappedClob( wrapper );
+ vetWrappedDate( wrapper );
+ vetWrappedFloatingPoint( wrapper, 8, "DOUBLECOL" );
+ vetWrappedFloatingPoint( wrapper, 9, "FLOATCOL" );
+ vetWrappedInteger( wrapper, 10, "INTCOL" );
+ vetWrappedString( wrapper, 11, "LONGVARCHARCOL" );
+ vetWrappedBinary( wrapper, 12, "LONGVARCHARFORBITDATACOL" );
+ vetWrappedInteger( wrapper, 13, "NUMERICCOL" );
+ vetWrappedFloatingPoint( wrapper, 14, "REALCOL" );
+ vetWrappedInteger( wrapper, 15, "SMALLINTCOL" );
+ vetWrappedTime( wrapper );
+ vetWrappedTimestamp( wrapper );
+ vetWrappedString( wrapper, 18, "VARCHARCOL" );
+ vetWrappedBinary( wrapper, 19, "VARCHARFORBITDATACOL" );
+ }
+ private void vetWrappedNull( Wrapper41 wrapper ) throws Exception
+ {
+ try {
+ wrapper.getObject( 1, (Class) null );
+ fail( "Did not expect to get a result for a null class type." );
+ }
+ catch (SQLException e)
+ {
+ assertSQLState( "Null type", UNSUPPORTED_COERCION, e );
+ }
+ try {
+ wrapper.getObject( "BIGINTCOL", (Class) null );
+ fail( "Did not expect to get a result for a null class type." );
+ }
+ catch (SQLException e)
+ {
+ assertSQLState( "Null type", UNSUPPORTED_COERCION, e );
+ }
+ }
+ private void vetWrappedInteger( Wrapper41 wrapper, int colID, String colName ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "1",
+ new Class[] { String.class, BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class, Number.class, Object.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "1.0",
+ new Class[] { Float.class, Double.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "true",
+ new Class[] { Boolean.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ colID,
+ colName,
+ new Class[] { Date.class, Time.class, Timestamp.class, Blob.class, Clob.class, byteArrayClass, getClass() }
+ );
+ }
+ private void vetWrappedBlob( Wrapper41 wrapper ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ 2,
+ "BLOBCOL",
+ "abc",
+ new Class[] { Blob.class, Object.class, byteArrayClass, String.class, }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ 2,
+ "BLOBCOL",
+ new Class[]
+ {
+ BigDecimal.class, Boolean.class,
+ Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
+ Date.class, Time.class, Timestamp.class
+ }
+ );
+
+ //
+ // We don't try to get a Clob value because we have already gotten a LOB value.
+ // Trying to open another LOB stream raises an error. Using a random class type
+ // also takes us down that code path, so we don't verify against getClass() either.
+ //
+ }
+ private void vetWrappedBoolean( Wrapper41 wrapper ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ 3,
+ "BOOLEANCOL",
+ "true",
+ new Class[] { String.class, Boolean.class, Object.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ 3,
+ "BOOLEANCOL",
+ "1",
+ new Class[] { BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ 3,
+ "BOOLEANCOL",
+ "1.0",
+ new Class[] { Float.class, Double.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ 3,
+ "BOOLEANCOL",
+ new Class[] { Date.class, Time.class, Timestamp.class, Blob.class, Clob.class, byteArrayClass, getClass() }
+ );
+ }
+ private void vetWrappedString( Wrapper41 wrapper, int colID, String colName ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "a",
+ new Class[] { String.class, Object.class }
+ );
+
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "true",
+ new Class[] { Boolean.class }
+ );
+
+ vetCoercionError
+ (
+ wrapper,
+ colID,
+ colName,
+ new Class[]
+ {
+ BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class,
+ Float.class, Double.class,
+ },
+ BAD_FORMAT
+ );
+
+ vetCoercionError
+ (
+ wrapper,
+ colID,
+ colName,
+ new Class[]
+ {
+ Date.class, Time.class, Timestamp.class
+ },
+ BAD_DATETIME
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ colID,
+ colName,
+ new Class[]
+ {
+ Blob.class, Clob.class, byteArrayClass, getClass()
+ }
+ );
+ }
+ private void vetWrappedBinary( Wrapper41 wrapper, int colID, String colName ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "de",
+ new Class[] { String.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "\ufffd",
+ new Class[] { byteArrayClass, Object.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ colID,
+ colName,
+ new Class[]
+ {
+ Boolean.class, BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class,
+ Float.class, Double.class,
+ Date.class, Time.class, Timestamp.class, Blob.class, Clob.class, getClass()
+ }
+ );
+ }
+ private void vetWrappedClob( Wrapper41 wrapper ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ 6,
+ "CLOBCOL",
+ "abc",
+ new Class[] { String.class, Clob.class, Object.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ 6,
+ "CLOBCOL",
+ new Class[]
+ {
+ Boolean.class,
+ BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class,
+ Float.class, Double.class,
+ Date.class, Time.class, Timestamp.class,
+ byteArrayClass
+ }
+ );
+
+ //
+ // We don't test getting a BLOB because we are only allowed one attempt
+ // to get a LOB from the column. Using a random class type
+ // also takes us down that code path, so we don't verify against getClass() either.
+ //
+ }
+ private void vetWrappedDate( Wrapper41 wrapper ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ 7,
+ "DATECOL",
+ "1994-02-23",
+ new Class[] { String.class, Date.class, Object.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ 7,
+ "DATECOL",
+ "1994-02-23 00:00:00.0",
+ new Class[] { Timestamp.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ 7,
+ "DATECOL",
+ new Class[]
+ {
+ Boolean.class,
+ BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class,
+ Float.class, Double.class,
+ Time.class,
+ Blob.class, Clob.class, byteArrayClass, getClass()
+ }
+ );
+ }
+ private void vetWrappedFloatingPoint( Wrapper41 wrapper, int colID, String colName ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "1.0",
+ new Class[] { String.class, Float.class, Double.class, BigDecimal.class, Number.class, Object.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "1",
+ new Class[] { Byte.class, Short.class, Integer.class, Long.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ colID,
+ colName,
+ "true",
+ new Class[] { Boolean.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ colID,
+ colName,
+ new Class[] { Date.class, Time.class, Timestamp.class, Blob.class, Clob.class, byteArrayClass, getClass() }
+ );
+ }
+ private void vetWrappedTime( Wrapper41 wrapper ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ 16,
+ "TIMECOL",
+ "15:09:02",
+ new Class[] { String.class, Time.class, Object.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ 16,
+ "TIMECOL",
+ VARIABLE_STRING,
+ new Class[] { Timestamp.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ 16,
+ "TIMECOL",
+ new Class[]
+ {
+ Boolean.class,
+ BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class,
+ Float.class, Double.class,
+ Date.class,
+ Blob.class, Clob.class, byteArrayClass, getClass()
+ }
+ );
+ }
+ private void vetWrappedTimestamp( Wrapper41 wrapper ) throws Exception
+ {
+ vetWrapperOK
+ (
+ wrapper,
+ 17,
+ "TIMESTAMPCOL",
+ "1962-09-23 03:23:34.234",
+ new Class[] { String.class, Timestamp.class, Object.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ 17,
+ "TIMESTAMPCOL",
+ "03:23:34",
+ new Class[] { Time.class }
+ );
+ vetWrapperOK
+ (
+ wrapper,
+ 17,
+ "TIMESTAMPCOL",
+ "1962-09-23",
+ new Class[] { Date.class }
+ );
+
+ vetNoWrapper
+ (
+ wrapper,
+ 17,
+ "TIMESTAMPCOL",
+ new Class[]
+ {
+ Boolean.class,
+ BigDecimal.class, Byte.class, Short.class, Integer.class, Long.class,
+ Float.class, Double.class,
+ Blob.class, Clob.class, byteArrayClass, getClass()
+ }
+ );
+ }
+
+ @SuppressWarnings("unchecked")
+ private void vetWrapperOK
+ ( Wrapper41 wrapper, int colID, String colName, String expectedValue, Class[] supportedCoercions )
+ throws Exception
+ {
+ int coercionCount = supportedCoercions.length;
+ for ( int i = 0; i < coercionCount; i++ )
+ {
+ Class candidate = supportedCoercions[ i ];
+ vetCandidate( candidate, expectedValue, wrapper.getObject( colID, candidate ) );
+
+ // you can only retrieve a LOB once
+ if ( (candidate == Blob.class) || (candidate == Clob.class) ) { return; }
+
+ vetCandidate( candidate, expectedValue, wrapper.getObject( colName, candidate ) );
+ }
+ }
+ @SuppressWarnings("unchecked")
+ private void vetCandidate( Class candidate, String expectedValue, Object actualValue )
+ throws Exception
+ {
+ assertTrue( candidate.getName(), candidate.isAssignableFrom( actualValue.getClass( ) ) );
+
+ if ( VARIABLE_STRING.equals( expectedValue ) ) { return; }
+
+ String actualString;
+ if ( actualValue instanceof Blob )
+ {
+ Blob blob = (Blob) actualValue;
+ actualString = squeezeString( blob.getBytes( 1L, (int) blob.length() ) );
+ }
+ else if ( actualValue instanceof byte[] )
+ {
+ actualString = squeezeString( (byte[]) actualValue );
+ }
+ else if ( actualValue instanceof Clob )
+ {
+ Clob clob = (Clob) actualValue;
+ actualString = clob.getSubString( 1L, (int) clob.length() );
+ }
+ else { actualString = actualValue.toString(); }
+
+ assertEquals( candidate.getName(), expectedValue, actualString );
+ }
+ private String squeezeString( byte[] bytes ) throws Exception
+ {
+
+ String result = new String( bytes, "UTF-8" );
+
+ return result;
+ }
+ private void vetNoWrapper
+ ( Wrapper41 wrapper, int colID, String colName, Class[] unsupportedCoercions )
+ throws Exception
+ {
+ vetCoercionError( wrapper, colID, colName, unsupportedCoercions, UNSUPPORTED_COERCION );
+ }
+ @SuppressWarnings("unchecked")
+ private void vetCoercionError
+ ( Wrapper41 wrapper, int colID, String colName, Class[] unsupportedCoercions, String expectedSQLState )
+ throws Exception
+ {
+ int coercionCount = unsupportedCoercions.length;
+ for ( int i = 0; i < coercionCount; i++ )
+ {
+ Class candidate = unsupportedCoercions[ i ];
+
+ try {
+ wrapper.getObject( colID, candidate );
+ fail( "Did not expect to get a " + candidate.getName() );
+ }
+ catch (SQLException e)
+ {
+ assertSQLState( candidate.getName(), expectedSQLState, e );
+ }
+
+ // you can only retrieve a LOB once
+ if ( (candidate == Blob.class) || (candidate == Clob.class) ) { return; }
+
+ try {
+ wrapper.getObject( colName, candidate );
+ fail( "Did not expect to get a " + candidate.getName() );
+ }
+ catch (SQLException e)
+ {
+ assertSQLState( candidate.getName(), expectedSQLState, e );
+ }
+ }
+ }
+ private PreparedStatement prepareStatement( Connection conn, String text )
+ throws Exception
+ {
+ println( text );
+
+ PreparedStatement ps = conn.prepareStatement( text );
+
+ return ps;
+ }
+
}