| /* |
| * |
| * Derby - Class org.apache.derbyTesting.functionTests.tests.jdbc4.StatementTest |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to you under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
| * either express or implied. See the License for the specific |
| * language governing permissions and limitations under the License. |
| */ |
| |
| package org.apache.derbyTesting.functionTests.tests.jdbc4; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.sql.CallableStatement; |
| import java.sql.Connection; |
| import java.sql.PreparedStatement; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.sql.SQLTimeoutException; |
| import java.sql.Statement; |
| import junit.framework.Test; |
| import org.apache.derby.client.am.ClientStatement; |
| import org.apache.derby.impl.jdbc.EmbedResultSet; |
| import org.apache.derby.impl.sql.execute.RowUtil; |
| import org.apache.derby.shared.common.sanity.SanityManager; |
| import org.apache.derbyTesting.functionTests.tests.jdbcapi.BatchUpdateTest; |
| import org.apache.derbyTesting.functionTests.tests.jdbcapi.SetQueryTimeoutTest; |
| import org.apache.derbyTesting.functionTests.tests.jdbcapi.Wrapper41Statement; |
| import org.apache.derbyTesting.functionTests.util.SQLStateConstants; |
| import org.apache.derbyTesting.junit.BaseJDBCTestCase; |
| import org.apache.derbyTesting.junit.BaseTestSuite; |
| import org.apache.derbyTesting.junit.TestConfiguration; |
| |
| /** |
| * Tests for new methods added for Statement in JDBC4. |
| */ |
| public class StatementTest |
| extends BaseJDBCTestCase { |
| |
| /** Default statement used by the tests. */ |
| private Statement stmt = null; |
| |
| /** |
| * Create a new test with the given name. |
| * |
| * @param name name of the test. |
| */ |
| public StatementTest(String name) { |
| super(name); |
| } |
| |
| /** |
| * Create default connection and statement. |
| * |
| * @throws SQLException if setAutoCommit, createStatement or |
| * BaseJDBCTestCase.getConnection fails. |
| */ |
| protected void setUp() |
| throws SQLException { |
| getConnection().setAutoCommit(false); |
| // Create a default statement. |
| stmt = createStatement(); |
| assertFalse("First statement must be open initially", |
| stmt.isClosed()); |
| } |
| |
| /** |
| * Close default connection and statement if necessary. |
| * |
| * @throws SQLException if a database access exception occurs. |
| */ |
| protected void tearDown() |
| throws Exception { |
| // Close default statement |
| if (stmt != null) { |
| stmt.close(); |
| stmt = null; |
| } |
| |
| super.tearDown(); |
| } |
| |
| /** |
| * Check that <code>isClosed</code> returns <code>true</code> after |
| * the statement has been explicitly closed. |
| */ |
| public void testIsClosedBasic() |
| throws SQLException { |
| ResultSet rs = stmt.executeQuery("select count(*) from stmtTable"); |
| assertFalse("Statement should still be open", stmt.isClosed()); |
| rs.close(); |
| assertFalse("Statement should be open after ResultSet has been " + |
| "closed", stmt.isClosed()); |
| stmt.close(); |
| assertTrue("Statement should be closed, close() has been called", |
| stmt.isClosed()); |
| } |
| |
| /** |
| * Test that creating two statements on the same connection does not |
| * cause side effects on the statements. |
| */ |
| public void testIsClosedWithTwoStatementsOnSameConnection() |
| throws SQLException { |
| // Create a second statement on the default connection. |
| Statement stmt2 = createStatement(); |
| assertFalse("Second statement must be open initially", |
| stmt2.isClosed()); |
| assertFalse("First statement should not be closed when " + |
| "creating a second statement", stmt.isClosed()); |
| ResultSet rs = stmt2.executeQuery("select count(*) from stmtTable"); |
| assertFalse("Second statement should be open after call to " + |
| "execute()", stmt2.isClosed()); |
| assertFalse("First statement should be open after call to " + |
| "second statment's execute()", stmt.isClosed()); |
| stmt2.close(); |
| assertTrue("Second statement should be closed, close() has " + |
| "been called!", stmt2.isClosed()); |
| assertFalse("First statement should be open after call to " + |
| "second statment's close()", stmt.isClosed()); |
| } |
| |
| /** |
| * Test that the two statements created on the connection are closed |
| * when the connection itself is closed. |
| */ |
| public void testIsClosedWhenClosingConnection() |
| throws SQLException { |
| // Create an extra statement for good measure. |
| Statement stmt2 = createStatement(); |
| assertFalse("Second statement must be open initially", |
| stmt2.isClosed()); |
| // Exeute something on it, as opposed to the default statement. |
| stmt2.execute("select count(*) from stmtTable"); |
| assertFalse("Second statement should be open after call to " + |
| "execute()", stmt2.isClosed()); |
| // Close the connection. We must commit/rollback first, or else a |
| // "Invalid transaction state" exception is raised. |
| rollback(); |
| Connection con = getConnection(); |
| con.close(); |
| assertTrue("Connection should be closed after close()", |
| con.isClosed()); |
| assertTrue("First statement should be closed, as parent " + |
| "connection has been closed", stmt.isClosed()); |
| assertTrue("Second statement should be closed, as parent " + |
| "connection has been closed", stmt2.isClosed()); |
| } |
| |
| /** |
| * Check the state of the statement when the connection is first attempted |
| * closed when in an invalid transaction state, then closed after a |
| * commit. According to the JDBC 4 API documentation: </i>"It is strongly |
| * recommended that an application explictly commits or rolls back an |
| * active transaction prior to calling the close method. If the close |
| * method is called and there is an active transaction, |
| * the results are implementation-defined."</i> |
| * Derby throws an exception and keeps the connection open. |
| */ |
| public void testIsClosedWhenClosingConnectionInInvalidState() |
| throws SQLException { |
| stmt.executeQuery("select count(*) from stmtTable"); |
| // Connection should now be in an invalid transaction state. |
| Connection con = stmt.getConnection(); |
| try { |
| con.close(); |
| fail("Invalid transaction state exception was not thrown"); |
| } catch (SQLException sqle) { |
| String expectedState = |
| SQLStateConstants.INVALID_TRANSACTION_STATE_ACTIVE_SQL_TRANSACTION; |
| assertSQLState(expectedState, sqle); |
| } |
| assertFalse("Statement should still be open, because " + |
| "Connection.close() failed", stmt.isClosed()); |
| assertFalse("Connection should still be open", con.isClosed()); |
| // Do a commit here, since we do a rollback in another test. |
| con.commit(); |
| con.close(); |
| assertTrue("Connection should be closed after close()", |
| con.isClosed()); |
| assertTrue("Statement should be closed, because " + |
| "the connection has been closed", stmt.isClosed()); |
| stmt.close(); |
| assertTrue("Statement should still be closed", stmt.isClosed()); |
| } |
| |
| /** |
| * Execute a query on a statement after the parent connection has been |
| * closed. |
| */ |
| public void testStatementExecuteAfterConnectionClose() |
| throws SQLException { |
| Connection con = stmt.getConnection(); |
| con.close(); |
| assertTrue("Connection should be closed after close()", |
| con.isClosed()); |
| try { |
| stmt.executeQuery("select count(*) from stmtTable"); |
| } catch (SQLException sqle) { |
| assertEquals("Unexpected SQL state for performing " + |
| "operations on a closed statement.", |
| SQLStateConstants.CONNECTION_EXCEPTION_CONNECTION_DOES_NOT_EXIST, |
| sqle.getSQLState()); |
| } |
| assertTrue("Statement should be closed, because " + |
| "the connection has been closed", stmt.isClosed()); |
| } |
| |
| public void testIsWrapperForStatement() throws SQLException { |
| assertTrue(stmt.isWrapperFor(Statement.class)); |
| } |
| |
| public void testIsNotWrapperForPreparedStatement() throws SQLException { |
| assertFalse(stmt.isWrapperFor(PreparedStatement.class)); |
| } |
| |
| public void testIsNotWrapperForCallableStatement() throws SQLException { |
| assertFalse(stmt.isWrapperFor(CallableStatement.class)); |
| } |
| |
| public void testIsNotWrapperForResultSet() throws SQLException { |
| assertFalse(stmt.isWrapperFor(ResultSet.class)); |
| } |
| |
| public void testUnwrapStatement() throws SQLException { |
| Statement stmt2 = stmt.unwrap(Statement.class); |
| assertSame("Unwrap returned wrong object.", stmt, stmt2); |
| } |
| |
| public void testUnwrapPreparedStatement() { |
| try { |
| PreparedStatement ps = stmt.unwrap(PreparedStatement.class); |
| fail("Unwrap didn't fail."); |
| } catch (SQLException e) { |
| assertSQLState("XJ128", e); |
| } |
| } |
| |
| public void testUnwrapCallableStatement() { |
| try { |
| CallableStatement cs = stmt.unwrap(CallableStatement.class); |
| fail("Unwrap didn't fail."); |
| } catch (SQLException e) { |
| assertSQLState("XJ128", e); |
| } |
| } |
| |
| public void testUnwrapResultSet() throws SQLException { |
| try { |
| ResultSet rs = stmt.unwrap(ResultSet.class); |
| fail("Unwrap didn't fail."); |
| } catch (SQLException e) { |
| assertSQLState("XJ128", e); |
| } |
| } |
| |
| /** |
| * Tests isPoolable, setPoolable, and the default poolability. |
| */ |
| public void testPoolable() throws SQLException { |
| assertFalse("Statement cannot be poolable by default", |
| stmt.isPoolable()); |
| stmt.setPoolable(true); |
| assertTrue("Statement must be poolable", stmt.isPoolable()); |
| |
| stmt.setPoolable(false); |
| assertFalse("Statement cannot be poolable", stmt.isPoolable()); |
| } |
| |
| /** |
| * Test that Statement.setQueryTimeout() causes statements to |
| * raise SQLTimeoutException per the JDBC 4.1 spec clarification. |
| */ |
| public void test_jdbc4_1_queryTimeoutException() throws Exception |
| { |
| SQLException se = null; |
| |
| PreparedStatement ps = prepareStatement |
| ( |
| "select columnnumber from sys.syscolumns c, sys.systables t\n" + |
| "where t.tablename = 'SYSTABLES'\n" + |
| "and t.tableid = c.referenceid\n" + |
| "and mod( delay_st( 5, c.columnnumber ), 3 ) = 0" |
| ); |
| println( "Testing timeout exception for a " + ps.getClass().getName() ); |
| |
| SetQueryTimeoutTest.StatementExecutor executor = |
| new SetQueryTimeoutTest.StatementExecutor( ps, true, 1 ); |
| |
| executor.start(); |
| executor.join(); |
| |
| ps.close(); |
| |
| se = executor.getSQLException(); |
| |
| assertNotNull( se ); |
| assertEquals( SQLTimeoutException.class.getName(), se.getClass().getName() ); |
| } |
| |
| /** |
| * Test the closeOnCompletion() and isCloseOnCompletion() methods |
| * when using ResultSets which close implicitly. |
| */ |
| public void testCompletionClosure_jdbc4_1_implicitRSClosure() throws Exception |
| { |
| Connection conn = getConnection(); |
| conn.setHoldability( ResultSet.CLOSE_CURSORS_AT_COMMIT ); |
| conn.setAutoCommit( true ); |
| |
| PreparedStatement ps; |
| ResultSet rs; |
| Wrapper41Statement wrapper; |
| |
| ps = conn.prepareStatement( "values ( 1 )" ); |
| println( "Testing implicit closure WITH autocommit on a " + ps.getClass().getName() ); |
| |
| wrapper = new Wrapper41Statement( ps ); |
| wrapper.closeOnCompletion(); |
| |
| rs = ps.executeQuery(); |
| rs.next(); |
| rs.next(); |
| |
| assertTrue( rs.isClosed() ); |
| assertTrue( ps.isClosed() ); |
| |
| conn.setAutoCommit( false ); |
| |
| // now retry the experiment with an explicit commit |
| |
| ps = conn.prepareStatement( "values ( 1 )" ); |
| println( "Testing implicit closure WITHOUT autocommit on a " + ps.getClass().getName() ); |
| |
| wrapper = new Wrapper41Statement( ps ); |
| wrapper.closeOnCompletion(); |
| |
| rs = ps.executeQuery(); |
| rs.next(); |
| rs.next(); |
| |
| assertFalse( rs.isClosed() ); |
| assertFalse( ps.isClosed() ); |
| |
| conn.commit(); |
| |
| assertTrue( rs.isClosed() ); |
| assertTrue( ps.isClosed() ); |
| } |
| |
| /** |
| * Test the large update methods added by JDBC 4.2. |
| */ |
| public void testLargeUpdate_jdbc4_2() throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| largeUpdate_jdbc4_2( conn ); |
| } |
| |
| public static void largeUpdate_jdbc4_2( Connection conn ) |
| throws Exception |
| { |
| // |
| // This test makes use of a debug entry point which is a NOP |
| // in an insane production build. |
| // |
| if (!SanityManager.DEBUG) { return; } |
| else { println( "Running largeUpdate_jdbc4_2() on debug code." ); } |
| |
| conn.prepareStatement |
| ( |
| "create procedure setRowCountBase( newBase bigint )\n" + |
| "language java parameter style java no sql\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.jdbc4.StatementTest.setRowCountBase'\n" |
| ).execute(); |
| conn.prepareStatement |
| ( |
| "create table bigintTable( col1 int generated always as identity, col2 bigint )" |
| ).execute(); |
| |
| StatementWrapper sw = new StatementWrapper( conn.createStatement() ); |
| |
| largeUpdateTest( sw, (long) Integer.MAX_VALUE ); |
| largeUpdateTest( sw, 0L); |
| |
| largeBatchTest( sw, (long) Integer.MAX_VALUE ); |
| largeBatchTest( sw, 0L); |
| |
| largeMaxRowsTest( sw, ((long) Integer.MAX_VALUE) + 1L ); |
| |
| largeBatchUpdateExceptionTest( sw, ((long) Integer.MAX_VALUE) + 1L ); |
| } |
| private static void largeUpdateTest( StatementWrapper sw, long rowCountBase ) |
| throws Exception |
| { |
| // |
| // This test makes use of a debug entry point which is a NOP |
| // in an insane production build. |
| // |
| if (!SanityManager.DEBUG) { return; } |
| else { println( "Running largeUpdateTest() on debug code." ); } |
| |
| // poke the rowCountBase into the engine. all returned row counts will be |
| // increased by this amount |
| setRowCountBase( sw.getWrappedStatement(), false, rowCountBase ); |
| |
| largeUpdateTest( sw, rowCountBase, 1L ); |
| largeUpdateTest( sw, rowCountBase, 3L ); |
| } |
| private static void largeUpdateTest( StatementWrapper sw, long rowCountBase, long rowCount ) |
| throws Exception |
| { |
| StringBuffer buffer = new StringBuffer(); |
| buffer.append( "insert into bigintTable( col2 ) values " ); |
| for ( long i = 0L; i < rowCount; i++ ) |
| { |
| if ( i > 0L ) { buffer.append( ", " ); } |
| buffer.append( "( " + i + " )" ); |
| } |
| String text = buffer.toString(); |
| |
| long expectedResult = rowCountBase + rowCount; |
| |
| vetUpdateSize( sw, (int) expectedResult, |
| sw.getWrappedStatement().executeUpdate( text ), expectedResult ); |
| vetUpdateSize( sw, (int) expectedResult, |
| sw.getWrappedStatement().executeUpdate( text, Statement.RETURN_GENERATED_KEYS ), expectedResult ); |
| vetUpdateSize( sw, (int) expectedResult, |
| sw.getWrappedStatement().executeUpdate( text, new int[] { 1 } ), expectedResult ); |
| vetUpdateSize( sw, (int) expectedResult, |
| sw.getWrappedStatement().executeUpdate( text, new String[] { "COL1" } ), expectedResult ); |
| |
| vetUpdateSize( sw, expectedResult, sw.executeLargeUpdate( text ), expectedResult ); |
| vetUpdateSize( sw, expectedResult, sw.executeLargeUpdate( text, Statement.RETURN_GENERATED_KEYS ), expectedResult ); |
| vetUpdateSize( sw, expectedResult, sw.executeLargeUpdate( text, new int[] { 1 } ), expectedResult ); |
| vetUpdateSize( sw, expectedResult, sw.executeLargeUpdate( text, new String[] { "COL1" } ), expectedResult ); |
| } |
| private static void vetUpdateSize( StatementWrapper sw, int expected, int actual, long longAnswer ) |
| throws Exception |
| { |
| assertEquals( expected, actual ); |
| assertEquals( expected, sw.getWrappedStatement().getUpdateCount() ); |
| assertEquals( longAnswer, sw.getLargeUpdateCount() ); |
| } |
| private static void vetUpdateSize( StatementWrapper sw, long expected, long actual, long longAnswer ) |
| throws Exception |
| { |
| assertEquals( expected, actual ); |
| assertEquals( (int) expected, sw.getWrappedStatement().getUpdateCount() ); |
| assertEquals( longAnswer, sw.getLargeUpdateCount() ); |
| } |
| private static void largeBatchTest( StatementWrapper sw, long rowCountBase ) |
| throws Exception |
| { |
| // |
| // This test makes use of a debug entry point which is a NOP |
| // in an insane production build. |
| // |
| if (!SanityManager.DEBUG) { return; } |
| |
| println( "Large batch test with rowCountBase = " + rowCountBase ); |
| |
| // poke the rowCountBase into the engine. all returned row counts will be |
| // increased by this amount |
| sw.getWrappedStatement().clearBatch(); |
| setRowCountBase( sw.getWrappedStatement(), false, rowCountBase ); |
| |
| long[] expectedResult = new long[] { rowCountBase + 1L, rowCountBase + 1L, rowCountBase + 2L }; |
| |
| createBatch( sw ); |
| assertEquals( sw.getWrappedStatement().executeBatch(), squashLongs( expectedResult ) ); |
| |
| createBatch( sw ); |
| assertEquals( sw.executeLargeBatch(), expectedResult ); |
| } |
| private static void createBatch( StatementTest.StatementWrapper sw ) |
| throws Exception |
| { |
| sw.getWrappedStatement().clearBatch(); |
| truncate( sw ); |
| sw.getWrappedStatement().addBatch( "insert into bigintTable( col2 ) values ( 1 )" ); |
| sw.getWrappedStatement().addBatch( "update bigintTable set col2 = 2" ); |
| sw.getWrappedStatement().addBatch( "insert into bigintTable( col2 ) values ( 3 ), ( 4 )" ); |
| } |
| private static void largeMaxRowsTest( StatementWrapper sw, long maxRows ) |
| throws Exception |
| { |
| // |
| // This test makes use of a debug entry point which is a NOP |
| // in an insane production build. |
| // |
| if (!SanityManager.DEBUG) { return; } |
| |
| println( "Large max rows test with maxRows = " + maxRows ); |
| |
| long expectedRowCount = 3L; |
| |
| truncate( sw ); |
| sw.getWrappedStatement().execute( "insert into bigintTable( col2 ) values ( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 )" ); |
| |
| setRowCountBase( sw.getWrappedStatement(), usingDerbyNetClient(), maxRows - expectedRowCount ); |
| |
| sw.setLargeMaxRows( maxRows ); |
| |
| ResultSet rs = sw.getWrappedStatement().executeQuery( "select * from bigintTable" ); |
| int rowCount = 0; |
| while( rs.next() ) { rowCount++; } |
| rs.close(); |
| |
| setRowCountBase( sw.getWrappedStatement(), usingDerbyNetClient(), 0L ); |
| |
| assertEquals( expectedRowCount, rowCount ); |
| assertEquals( maxRows, sw.getLargeMaxRows() ); |
| } |
| private static void largeBatchUpdateExceptionTest( StatementWrapper sw, long rowCountBase ) |
| throws Exception |
| { |
| // |
| // This test makes use of a debug entry point which is a NOP |
| // in an insane production build. |
| // |
| if (!SanityManager.DEBUG) { return; } |
| |
| println( "Large batch update exception test with rowCountBase = " + rowCountBase ); |
| |
| sw.getWrappedStatement().clearBatch(); |
| sw.getWrappedStatement().execute( "create table intTable( col1 int generated always as identity, col2 int )" ); |
| |
| // poke the rowCountBase into the engine. all returned row counts will be |
| // increased by this amount |
| setRowCountBase( sw.getWrappedStatement(), false, rowCountBase ); |
| |
| // |
| // Create a batch of statements. The last one will die on an overflow condition. |
| // |
| sw.getWrappedStatement().addBatch( "insert into intTable( col2 ) values ( 1 )" ); |
| sw.getWrappedStatement().addBatch( "insert into intTable( col2 ) values ( 1 )" ); |
| sw.getWrappedStatement().addBatch( "update intTable set col2 = 2147483647 + 1" ); |
| |
| if ( usingEmbedded() ) |
| { |
| BatchUpdateTest.assertBatchExecuteError |
| ( |
| "22003", sw.getWrappedStatement(), |
| new long[] { rowCountBase + 1L, rowCountBase + 1L } |
| ); |
| } |
| else if ( usingDerbyNetClient() ) |
| { |
| BatchUpdateTest.assertBatchExecuteError |
| ( |
| "XJ208", sw.getWrappedStatement(), |
| new long[] { rowCountBase + 1L, rowCountBase + 1L, -3 } |
| ); |
| } |
| |
| sw.getWrappedStatement().clearBatch(); |
| setRowCountBase( sw.getWrappedStatement(), false, 0L ); |
| } |
| |
| public static void setRowCountBase |
| ( Statement stmt, boolean onClient, long rowCountBase ) |
| throws Exception |
| { |
| if ( onClient ) |
| { |
| ClientStatement.setFetchedRowBase( rowCountBase ); |
| } |
| else |
| { |
| stmt.execute( "call setRowCountBase( " + rowCountBase + " )" ); |
| } |
| } |
| private static void truncate( StatementTest.StatementWrapper sw ) |
| throws Exception |
| { |
| sw.getWrappedStatement().execute( "truncate table bigintTable" ); |
| } |
| private static int[] squashLongs( long[] longs ) |
| { |
| int count = (longs == null) ? 0 : longs.length; |
| int[] ints = new int[ count ]; |
| for ( int i = 0; i < count; i++ ) { ints[ i ] = (int) longs[ i ]; } |
| |
| return ints; |
| } |
| |
| /** |
| * Create test suite for StatementTest. |
| */ |
| public static Test suite() { |
| BaseTestSuite suite = new BaseTestSuite("StatementTest suite"); |
| // Decorate test suite with a TestSetup class. |
| suite.addTest(new StatementTestSetup( |
| new BaseTestSuite(StatementTest.class))); |
| suite.addTest(TestConfiguration.clientServerDecorator( |
| new StatementTestSetup(new BaseTestSuite(StatementTest.class)))); |
| return suite; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // |
| // NESTED JDBC 4.2 WRAPPER AROUND A Statement |
| // |
| //////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * <p> |
| * This wrapper is used to expose JDBC 4.2 methods which can run on |
| * VM rev levels lower than Java 8. |
| * </p> |
| */ |
| public static class StatementWrapper |
| { |
| private Statement _wrappedStatement; |
| |
| public StatementWrapper( Statement wrappedStatement ) |
| { |
| _wrappedStatement = wrappedStatement; |
| } |
| |
| public Statement getWrappedStatement() { return _wrappedStatement; } |
| |
| // New methods added by JDBC 4.2 |
| public long[] executeLargeBatch() throws SQLException |
| { |
| return ((long[]) invoke |
| ( |
| "executeLargeBatch", |
| new Class[] {}, |
| new Object[] {} |
| )); |
| } |
| public long executeLargeUpdate( String sql ) throws SQLException |
| { |
| return ((Long) invoke |
| ( |
| "executeLargeUpdate", |
| new Class[] { String.class }, |
| new Object[] { sql } |
| )).longValue(); |
| } |
| public long executeLargeUpdate( String sql, int autoGeneratedKeys) throws SQLException |
| { |
| return ((Long) invoke |
| ( |
| "executeLargeUpdate", |
| new Class[] { String.class, Integer.TYPE }, |
| new Object[] { sql, autoGeneratedKeys } |
| )).longValue(); |
| } |
| public long executeLargeUpdate( String sql, int[] columnIndexes ) throws SQLException |
| { |
| return ((Long) invoke |
| ( |
| "executeLargeUpdate", |
| new Class[] { String.class, columnIndexes.getClass() }, |
| new Object[] { sql, columnIndexes } |
| )).longValue(); |
| } |
| public long executeLargeUpdate( String sql, String[] columnNames ) throws SQLException |
| { |
| return ((Long) invoke |
| ( |
| "executeLargeUpdate", |
| new Class[] { String.class, columnNames.getClass() }, |
| new Object[] { sql, columnNames } |
| )).longValue(); |
| } |
| public long getLargeMaxRows() throws SQLException |
| { |
| return ((Long) invoke |
| ( |
| "getLargeMaxRows", |
| new Class[] {}, |
| new Object[] {} |
| )).longValue(); |
| } |
| public long getLargeUpdateCount() throws SQLException |
| { |
| return ((Long) invoke |
| ( |
| "getLargeUpdateCount", |
| new Class[] {}, |
| new Object[] {} |
| )).longValue(); |
| } |
| public void setLargeMaxRows( long max ) throws SQLException |
| { |
| invoke |
| ( |
| "setLargeMaxRows", |
| new Class[] { Long.TYPE }, |
| new Object[] { max } |
| ); |
| } |
| |
| |
| // Reflection minion |
| protected Object invoke( String methodName, Class[] argTypes, Object[] argValues ) |
| throws SQLException |
| { |
| try { |
| Method method = _wrappedStatement.getClass().getMethod( methodName, argTypes ); |
| |
| return method.invoke( _wrappedStatement, argValues ); |
| } |
| catch (NoSuchMethodException nsme) { throw wrap( nsme ); } |
| catch (SecurityException se) { throw wrap( se ); } |
| catch (IllegalAccessException iae) { throw wrap( iae ); } |
| catch (IllegalArgumentException iare) { throw wrap( iare ); } |
| catch (InvocationTargetException ite) { throw wrap( ite ); } |
| } |
| private SQLException wrap( Throwable t ) { return new SQLException( t.getMessage(), t ); } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // |
| // PROCEDURE FOR BUMPING THE RETURNED ROW COUNT, FOR TESTING JDBC 4.2. |
| // |
| //////////////////////////////////////////////////////////////////////// |
| |
| /** Set the base which is used for returned row counts and fetched row counters */ |
| public static void setRowCountBase( long newBase ) |
| { |
| EmbedResultSet.setFetchedRowBase( newBase ); |
| RowUtil.setRowCountBase( newBase ); |
| } |
| |
| } // End class StatementTest |