http://git-wip-us.apache.org/repos/asf/ignite/blob/dbedbba0/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java index 418b5fc..3fb8f0e 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java @@ -17,26 +17,31 @@ package org.apache.ignite.jdbc.thin; +import java.io.InputStream; +import java.io.Reader; import java.io.Serializable; import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; +import java.sql.Blob; +import java.sql.Clob; import java.sql.Connection; import java.sql.Date; import java.sql.DriverManager; +import java.sql.NClob; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.util.Arrays; +import java.util.GregorianCalendar; import java.util.concurrent.Callable; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.query.annotations.QuerySqlField; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; @@ -49,7 +54,7 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; /** * Result set test. */ -@SuppressWarnings("FloatingPointEquality") +@SuppressWarnings({"FloatingPointEquality", "ThrowableNotThrown", "AssertWithSideEffects"}) public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest { /** IP finder. */ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); @@ -87,8 +92,6 @@ public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest { cfg.setDiscoverySpi(disco); - cfg.setMarshaller(new BinaryMarshaller()); - return cfg; } @@ -570,6 +573,924 @@ public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest { } /** + * @throws Exception If failed. + */ + public void testNotSupportedTypes() throws Exception { + final ResultSet rs = stmt.executeQuery(SQL); + + assert rs.next(); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getArray(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getArray("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getAsciiStream(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getAsciiStream("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getBinaryStream(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getBinaryStream("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getBlob(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getBlob("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getClob(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getClob("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getCharacterStream(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getCharacterStream("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getNCharacterStream(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getNCharacterStream("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getNClob(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getNClob("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getNString(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getNString("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getRef(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getRef("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getRowId(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getRowId("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getSQLXML(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getSQLXML("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getURL(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.getURL("id"); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testUpdateNotSupported() throws Exception { + final ResultSet rs = stmt.executeQuery(SQL); + + assert rs.next(); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBoolean(1, true); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBoolean("id", true); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateByte(1, (byte)0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateByte("id", (byte)0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateShort(1, (short)0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateShort("id", (short)0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateInt(1, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateInt("id", 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateLong(1, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateLong("id", 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateFloat(1, (float)0.0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateFloat("id", (float)0.0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateDouble(1, 0.0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateDouble("id", 0.0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateString(1, ""); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateString("id", ""); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateTime(1, new Time(0)); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateTime("id", new Time(0)); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateDate(1, new Date(0)); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateDate("id", new Date(0)); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateTimestamp(1, new Timestamp(0)); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateTimestamp("id", new Timestamp(0)); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBytes(1, new byte[]{}); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBytes("id", new byte[]{}); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateArray(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateArray("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBlob(1, (Blob)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBlob(1, (InputStream)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBlob(1, null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBlob("id", (Blob)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBlob("id", (InputStream)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBlob("id", null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateClob(1, (Clob)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateClob(1, (Reader)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateClob(1, null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateClob("id", (Clob)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateClob("id", (Reader)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateClob("id", null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNClob(1, (NClob)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNClob(1, (Reader)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNClob(1, null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNClob("id", (NClob)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNClob("id", (Reader)null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNClob("id", null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateAsciiStream(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateAsciiStream(1, null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateAsciiStream(1, null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateAsciiStream("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateAsciiStream("id", null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateAsciiStream("id", null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateCharacterStream(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateCharacterStream(1, null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateCharacterStream(1, null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateCharacterStream("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateCharacterStream("id", null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateCharacterStream("id", null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNCharacterStream(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNCharacterStream(1, null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNCharacterStream(1, null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNCharacterStream("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNCharacterStream("id", null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNCharacterStream("id", null, 0L); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateRef(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateRef("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateRowId(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateRowId("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNString(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNString("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateSQLXML(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateSQLXML("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateObject(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateObject(1, null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateObject("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateObject("id", null, 0); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBigDecimal(1, null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateBigDecimal("id", null); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNull(1); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateNull("id"); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.cancelRowUpdates(); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.updateRow(); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.deleteRow(); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.insertRow(); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + rs.moveToInsertRow(); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testExceptionOnClosedResultSet() throws Exception { + final ResultSet rs = stmt.executeQuery(SQL); + + rs.close(); + + // Must do nothing on closed result set + rs.close(); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getBoolean(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getBoolean("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getByte(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getByte("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getShort(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getShort("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getInt(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getInt("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getLong(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getLong("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getFloat(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getFloat("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getDouble(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getDouble("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getString(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getString("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getBytes(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getBytes("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getDate(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getDate(1, new GregorianCalendar()); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getDate("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getDate("id", new GregorianCalendar()); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTime(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTime(1, new GregorianCalendar()); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTime("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTime("id", new GregorianCalendar()); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTimestamp(1); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTimestamp(1, new GregorianCalendar()); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTimestamp("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getTimestamp("id", new GregorianCalendar()); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.wasNull(); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getMetaData(); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.next(); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.last(); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.afterLast(); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.beforeFirst(); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.first(); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.findColumn("id"); + } + }); + + checkResultSetClosed(new RunnableX() { + @Override public void run() throws Exception { + rs.getRow(); + } + }); + } + + /** * Test object. */ @SuppressWarnings("UnusedDeclaration") @@ -579,71 +1500,71 @@ public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest { private final int id; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Boolean boolVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Byte byteVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Short shortVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Integer intVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Long longVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Float floatVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Double doubleVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private BigDecimal bigVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private String strVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private byte[] arrVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Date dateVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Time timeVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private Timestamp tsVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private URL urlVal; /** */ - @QuerySqlField(index = false) + @QuerySqlField private TestObjectField f1 = new TestObjectField(100, "AAAA"); /** */ - @QuerySqlField(index = false) + @QuerySqlField private TestObjectField f2 = new TestObjectField(500, "BBBB"); /** */ - @QuerySqlField(index = false) + @QuerySqlField private TestObjectField f3; /**
http://git-wip-us.apache.org/repos/asf/ignite/blob/dbedbba0/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java index a6046be..97e3300 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java @@ -21,15 +21,22 @@ import java.io.Serializable; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLTimeoutException; import java.sql.Statement; +import java.util.concurrent.Callable; import org.apache.ignite.IgniteCache; import org.apache.ignite.cache.query.annotations.QuerySqlField; +import org.apache.ignite.cache.query.annotations.QuerySqlFunction; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.GridTestUtils; import static org.apache.ignite.cache.CacheMode.PARTITIONED; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; @@ -37,6 +44,7 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; /** * Statement test. */ +@SuppressWarnings("ThrowableNotThrown") public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { /** IP finder. */ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); @@ -63,7 +71,8 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { cache.setBackups(1); cache.setWriteSynchronizationMode(FULL_SYNC); cache.setIndexedTypes( - String.class, Person.class + String.class, Person.class, + Integer.class, Test.class ); cfg.setCacheConfiguration(cache); @@ -83,13 +92,8 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { startGridsMultiThreaded(3); - IgniteCache<String, Person> cache = grid(0).cache(DEFAULT_CACHE_NAME); - assert cache != null; - - cache.put("p1", new Person(1, "John", "White", 25)); - cache.put("p2", new Person(2, "Joe", "Black", 35)); - cache.put("p3", new Person(3, "Mike", "Green", 40)); + fillCache(); } /** {@inheritDoc} */ @@ -126,7 +130,7 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { /** * @throws Exception If failed. */ - public void testExecuteQuery() throws Exception { + public void testExecuteQuery0() throws Exception { ResultSet rs = stmt.executeQuery(SQL); assert rs != null; @@ -158,6 +162,32 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { /** * @throws Exception If failed. */ + public void testExecuteQuery1() throws Exception { + final String sqlText = "select val from test"; + + try (ResultSet rs = stmt.executeQuery(sqlText)) { + assertNotNull(rs); + + assertTrue(rs.next()); + + int val = rs.getInt(1); + + assertTrue("Invalid val: " + val, val >= 1 && val <= 10); + } + + stmt.close(); + + // Call on a closed statement + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.executeQuery(sqlText); + } + }); + } + + /** + * @throws Exception If failed. + */ public void testExecute() throws Exception { assert stmt.execute(SQL); @@ -199,6 +229,8 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { public void testMaxRows() throws Exception { stmt.setMaxRows(1); + assert stmt.getMaxRows() == 1; + ResultSet rs = stmt.executeQuery(SQL); assert rs != null; @@ -358,6 +390,677 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { } /** + * @throws Exception If failed. + */ + public void testExecuteQueryTimeout() throws Exception { + fail("https://issues.apache.org/jira/browse/IGNITE-5438"); + + final String sqlText = "select sleep_func(3)"; + + stmt.setQueryTimeout(1); + + // Timeout + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + return stmt.executeQuery(sqlText); + } + }, + SQLTimeoutException.class, + "Timeout" + ); + } + + /** + * @throws Exception If failed. + */ + public void testExecuteQueryMultipleResultSets() throws Exception { + assert !conn.getMetaData().supportsMultipleResultSets(); + + fail("https://issues.apache.org/jira/browse/IGNITE-6046"); + + final String sqlText = "select 1; select 1"; + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + return stmt.executeQuery(sqlText); + } + }, + SQLException.class, + "Multiple result sets" + ); + } + + /** + * @throws Exception If failed. + */ + public void testExecuteUpdate() throws Exception { + final String sqlText = "update test set val=1 where _key=1"; + + assertEquals(1, stmt.executeUpdate(sqlText)); + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.executeUpdate(sqlText); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testExecuteUpdateProducesResultSet() throws Exception { + final String sqlText = "select * from test"; + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + return stmt.executeUpdate(sqlText); + } + }, + SQLException.class, + "The query is not DML" + ); + } + + /** + * @throws Exception If failed. + */ + public void testExecuteUpdateTimeout() throws Exception { + fail("https://issues.apache.org/jira/browse/IGNITE-5438"); + + final String sqlText = "update test set val=1 where _key=sleep_func(3)"; + + stmt.setQueryTimeout(1); + + // Timeout + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + return stmt.executeUpdate(sqlText); + } + }, + SQLTimeoutException.class, + "Timeout" + ); + } + + /** + * @throws Exception If failed. + */ + public void testClose() throws Exception { + String sqlText = "select * from test"; + + ResultSet rs = stmt.executeQuery(sqlText); + + assertTrue(rs.next()); + assertFalse(rs.isClosed()); + + assertFalse(stmt.isClosed()); + + stmt.close(); + stmt.close(); // Closing closed is ok + + assertTrue(stmt.isClosed()); + + // Current result set must be closed + assertTrue(rs.isClosed()); + } + + /** + * @throws Exception If failed. + */ + public void testGetSetMaxFieldSizeUnsupported() throws Exception { + assertEquals(0, stmt.getMaxFieldSize()); + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.setMaxFieldSize(100); + + return null; + } + }, + SQLFeatureNotSupportedException.class, + "Field size limitation is not supported" + ); + + assertEquals(0, stmt.getMaxFieldSize()); + + stmt.close(); + + // Call on a closed statement + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getMaxFieldSize(); + } + }); + + // Call on a closed statement + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.setMaxFieldSize(100); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testGetSetMaxRows() throws Exception { + assertEquals(0, stmt.getMaxRows()); + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.setMaxRows(-1); + + return null; + } + }, + SQLException.class, + "Invalid max rows value" + ); + + assertEquals(0, stmt.getMaxRows()); + + final int maxRows = 1; + + stmt.setMaxRows(maxRows); + + assertEquals(maxRows, stmt.getMaxRows()); + + String sqlText = "select * from test"; + + ResultSet rs = stmt.executeQuery(sqlText); + + assertTrue(rs.next()); + assertFalse(rs.next()); //max rows reached + + stmt.close(); + + // Call on a closed statement + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getMaxRows(); + } + }); + + // Call on a closed statement + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.setMaxRows(maxRows); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testSetEscapeProcessing() throws Exception { + fail("https://issues.apache.org/jira/browse/IGNITE-5440"); + + stmt.setEscapeProcessing(false); + + final String sqlText = "select {fn CONVERT(1, SQL_BOOLEAN)}"; + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + return stmt.executeQuery(sqlText); + } + }, + SQLException.class, + "Failed to parse" + ); + + ResultSet rs = stmt.executeQuery(sqlText); + + assertTrue(rs.next()); + + assertEquals(true, rs.getBoolean(1)); + + stmt.setEscapeProcessing(true); + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.setEscapeProcessing(true); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testGetSetQueryTimeout() throws Exception { + assertEquals(0, stmt.getQueryTimeout()); + + // Invalid argument + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.setQueryTimeout(-1); + + return null; + } + }, + SQLException.class, + "Invalid timeout value" + ); + + assertEquals(0, stmt.getQueryTimeout()); + + final int timeout = 3; + + stmt.setQueryTimeout(timeout); + + assertEquals(timeout, stmt.getQueryTimeout()); + + stmt.close(); + + // Call on a closed statement + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getQueryTimeout(); + } + }); + + // Call on a closed statement + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.setQueryTimeout(timeout); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testMaxFieldSize() throws Exception { + assert stmt.getMaxFieldSize() >= 0; + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.setMaxFieldSize(-1); + + return null; + } + }, + SQLException.class, + "Invalid field limit" + ); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.setMaxFieldSize(100); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testQueryTimeout() throws Exception { + assert stmt.getQueryTimeout() == 0 : "Default timeout invalid: " + stmt.getQueryTimeout(); + + stmt.setQueryTimeout(10); + + assert stmt.getQueryTimeout() == 10; + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getQueryTimeout(); + } + }); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.setQueryTimeout(10); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testWarningsOnClosedStatement() throws Exception { + stmt.clearWarnings(); + + assert stmt.getWarnings() == null; + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getWarnings(); + } + }); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.clearWarnings(); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testCursorName() throws Exception { + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.setCursorName("test"); + } + }); + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.setCursorName("test"); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testGetMoreResults() throws Exception { + assert !stmt.getMoreResults(); + + stmt.execute("select 1"); + + ResultSet rs = stmt.getResultSet(); + + assert !stmt.getMoreResults(); + + assert rs.isClosed(); + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getMoreResults(); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testGetMoreResults1() throws Exception { + assert !stmt.getMoreResults(Statement.CLOSE_CURRENT_RESULT); + assert !stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT); + assert !stmt.getMoreResults(Statement.CLOSE_ALL_RESULTS); + + stmt.execute("select 1"); + + ResultSet rs = stmt.getResultSet(); + + assert !stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT); + + assert !rs.isClosed(); + + assert !stmt.getMoreResults(Statement.CLOSE_ALL_RESULTS); + + assert rs.isClosed(); + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testBatchEmpty() throws Exception { + assert conn.getMetaData().supportsBatchUpdates(); + + stmt.addBatch(""); + stmt.clearBatch(); + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.executeBatch(); + + return null; + } + }, + SQLException.class, + "Batch is empty" + ); + } + + /** + * @throws Exception If failed. + */ + public void testFetchDirection() throws Exception { + assert stmt.getFetchDirection() == ResultSet.FETCH_FORWARD; + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.setFetchDirection(ResultSet.FETCH_REVERSE); + + return null; + } + }, + SQLFeatureNotSupportedException.class, + "Only forward direction is supported." + ); + + stmt.close(); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.setFetchDirection(-1); + } + }); + + checkStatementClosed(new RunnableX() { + @Override public void run() throws Exception { + stmt.getFetchDirection(); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testAutogenerated() throws Exception { + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.executeUpdate("select 1", -1); + + return null; + } + }, + SQLException.class, + "Invalid autoGeneratedKeys value"); + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.execute("select 1", -1); + + return null; + } + }, + SQLException.class, + "Invalid autoGeneratedKeys value"); + + assert !conn.getMetaData().supportsGetGeneratedKeys(); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.getGeneratedKeys(); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.executeUpdate("select 1", Statement.RETURN_GENERATED_KEYS); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.executeUpdate("select 1", new int[] {1, 2}); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.executeUpdate("select 1", new String[] {"a", "b"}); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.execute("select 1", Statement.RETURN_GENERATED_KEYS); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.execute("select 1", new int[] {1, 2}); + } + }); + + checkNotSupported(new RunnableX() { + @Override public void run() throws Exception { + stmt.execute("select 1", new String[] {"a", "b"}); + } + }); + } + + /** + * @throws Exception If failed. + */ + public void testCloseOnCompletion() throws Exception { + fail("https://issues.apache.org/jira/browse/IGNITE-5344"); + + assert !stmt.isCloseOnCompletion() : "Default value of CloseOnCompletion is invalid"; + + stmt.execute("select 1"); + + stmt.closeOnCompletion(); + + assert stmt.isCloseOnCompletion(); + + stmt.getResultSet().close(); + + assert stmt.isClosed() : "Must be closed on complete"; + } + + /** + * @throws Exception If failed. + */ + public void testCancel() throws Exception { + fail("https://issues.apache.org/jira/browse/IGNITE-5439"); + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.execute("select sleep_func(3)"); + + return null; + } + }, + SQLException.class, + "The query is canceled"); + + IgniteInternalFuture f = GridTestUtils.runAsync(new Runnable() { + @Override public void run() { + try { + stmt.cancel(); + } + catch (SQLException e) { + log.error("Unexpected exception", e); + + fail("Unexpected exception."); + } + } + }); + + f.get(); + + stmt.close(); + + GridTestUtils.assertThrows(log, + new Callable<Object>() { + @Override public Object call() throws Exception { + stmt.cancel(); + + return null; + } + }, + SQLException.class, + "Statement is closed"); + } + + /** */ + private void fillCache() { + IgniteCache<String, Person> cachePerson = grid(0).cache(DEFAULT_CACHE_NAME); + + assert cachePerson != null; + + cachePerson.put("p1", new Person(1, "John", "White", 25)); + cachePerson.put("p2", new Person(2, "Joe", "Black", 35)); + cachePerson.put("p3", new Person(3, "Mike", "Green", 40)); + + IgniteCache<Integer, Test> cacheTest = grid(0).cache(DEFAULT_CACHE_NAME); + + for (int i = 1; i <= 10; i++) + cacheTest.put(i, new Test(i)); + } + + /** */ + @SuppressWarnings("unused") + public static class Test { + @QuerySqlField + private int val; + + /** + * @param val Value. + */ + public Test(int val) { + this.val = val; + } + } + + /** + * + * @param v seconds to sleep + * @return passed value + */ + @SuppressWarnings("unused") + @QuerySqlFunction + public static int sleep_func(int v) { + try { + Thread.sleep(v * 1000); + } + catch (InterruptedException ignored) { + // No-op + } + return v; + } + + /** * Person. */ @SuppressWarnings("UnusedDeclaration") http://git-wip-us.apache.org/repos/asf/ignite/blob/dbedbba0/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java index ff76011..23235dc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java @@ -17,8 +17,6 @@ package org.apache.ignite.internal.jdbc.thin; -import org.apache.ignite.internal.util.typedef.F; - import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; @@ -39,21 +37,22 @@ import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; import java.util.logging.Logger; +import org.apache.ignite.internal.util.typedef.F; +import static java.sql.ResultSet.CLOSE_CURSORS_AT_COMMIT; import static java.sql.ResultSet.CONCUR_READ_ONLY; import static java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT; import static java.sql.ResultSet.TYPE_FORWARD_ONLY; - import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_AUTO_CLOSE_SERVER_CURSORS; +import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_COLLOCATED; +import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_DISTRIBUTED_JOINS; +import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_ENFORCE_JOIN_ORDER; import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_HOST; import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_LAZY; import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_PORT; -import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_DISTRIBUTED_JOINS; -import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_ENFORCE_JOIN_ORDER; -import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_COLLOCATED; import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_REPLICATED_ONLY; -import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_SOCK_SND_BUF; import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_SOCK_RCV_BUF; +import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_SOCK_SND_BUF; import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_TCP_NO_DELAY; /** @@ -77,7 +76,7 @@ public class JdbcThinConnection implements Connection { /** Current transaction isolation. */ private int txIsolation; - /** Auto commit flag. */ + /** Auto-commit flag. */ private boolean autoCommit; /** Read-only flag. */ @@ -113,7 +112,7 @@ public class JdbcThinConnection implements Connection { autoCommit = true; txIsolation = Connection.TRANSACTION_NONE; - this.schema = schema; + this.schema = schema == null ? "PUBLIC" : schema; String host = extractHost(props); int port = extractPort(props); @@ -160,7 +159,7 @@ public class JdbcThinConnection implements Connection { checkCursorOptions(resSetType, resSetConcurrency, resSetHoldability); - JdbcThinStatement stmt = new JdbcThinStatement(this); + JdbcThinStatement stmt = new JdbcThinStatement(this, resSetHoldability); if (timeout > 0) stmt.timeout(timeout); @@ -186,7 +185,10 @@ public class JdbcThinConnection implements Connection { checkCursorOptions(resSetType, resSetConcurrency, resSetHoldability); - JdbcThinPreparedStatement stmt = new JdbcThinPreparedStatement(this, sql); + if (sql == null) + throw new SQLException("SQL string cannot be null."); + + JdbcThinPreparedStatement stmt = new JdbcThinPreparedStatement(this, sql, resSetHoldability); if (timeout > 0) stmt.timeout(timeout); @@ -203,7 +205,7 @@ public class JdbcThinConnection implements Connection { private void checkCursorOptions(int resSetType, int resSetConcurrency, int resSetHoldability) throws SQLException { if (resSetType != TYPE_FORWARD_ONLY) - throw new SQLFeatureNotSupportedException("Invalid result set type (only forward is supported.)"); + throw new SQLFeatureNotSupportedException("Invalid result set type (only forward is supported)."); if (resSetConcurrency != CONCUR_READ_ONLY) throw new SQLFeatureNotSupportedException("Invalid concurrency (updates are not supported)."); @@ -231,6 +233,9 @@ public class JdbcThinConnection implements Connection { @Override public String nativeSQL(String sql) throws SQLException { ensureNotClosed(); + if (sql == null) + throw new SQLException("SQL string cannot be null."); + return sql; } @@ -258,6 +263,9 @@ public class JdbcThinConnection implements Connection { @Override public void commit() throws SQLException { ensureNotClosed(); + if (autoCommit) + throw new SQLException("Transaction cannot be committed explicitly in auto-commit mode."); + LOG.warning("Transactions are not supported."); } @@ -265,6 +273,9 @@ public class JdbcThinConnection implements Connection { @Override public void rollback() throws SQLException { ensureNotClosed(); + if (autoCommit) + throw new SQLException("Transaction cannot rollback in auto-commit mode."); + LOG.warning("Transactions are not supported."); } @@ -323,7 +334,21 @@ public class JdbcThinConnection implements Connection { @Override public void setTransactionIsolation(int level) throws SQLException { ensureNotClosed(); - LOG.warning("Transactions are not supported."); + switch (level) { + case Connection.TRANSACTION_READ_UNCOMMITTED: + case Connection.TRANSACTION_READ_COMMITTED: + case Connection.TRANSACTION_REPEATABLE_READ: + case Connection.TRANSACTION_SERIALIZABLE: + LOG.warning("Transactions are not supported."); + + break; + + case Connection.TRANSACTION_NONE: + break; + + default: + throw new SQLException("Invalid transaction isolation level."); + } txIsolation = level; } @@ -351,6 +376,8 @@ public class JdbcThinConnection implements Connection { /** {@inheritDoc} */ @Override public Map<String, Class<?>> getTypeMap() throws SQLException { + ensureNotClosed(); + throw new SQLFeatureNotSupportedException("Types mapping is not supported."); } @@ -368,6 +395,9 @@ public class JdbcThinConnection implements Connection { if (holdability != HOLD_CURSORS_OVER_COMMIT) LOG.warning("Transactions are not supported."); + if (holdability != HOLD_CURSORS_OVER_COMMIT && holdability != CLOSE_CURSORS_AT_COMMIT) + throw new SQLException("Invalid result set holdability value."); + this.holdability = holdability; } @@ -382,6 +412,9 @@ public class JdbcThinConnection implements Connection { @Override public Savepoint setSavepoint() throws SQLException { ensureNotClosed(); + if (autoCommit) + throw new SQLException("Savepoint cannot be set in auto-commit mode."); + throw new SQLFeatureNotSupportedException("Savepoints are not supported."); } @@ -389,6 +422,12 @@ public class JdbcThinConnection implements Connection { @Override public Savepoint setSavepoint(String name) throws SQLException { ensureNotClosed(); + if (name == null) + throw new SQLException("Savepoint name cannot be null."); + + if (autoCommit) + throw new SQLException("Savepoint cannot be set in auto-commit mode."); + throw new SQLFeatureNotSupportedException("Savepoints are not supported."); } @@ -396,6 +435,12 @@ public class JdbcThinConnection implements Connection { @Override public void rollback(Savepoint savepoint) throws SQLException { ensureNotClosed(); + if (savepoint == null) + throw new SQLException("Invalid savepoint."); + + if (autoCommit) + throw new SQLException("Auto-commit mode."); + throw new SQLFeatureNotSupportedException("Savepoints are not supported."); } @@ -403,6 +448,9 @@ public class JdbcThinConnection implements Connection { @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { ensureNotClosed(); + if (savepoint == null) + throw new SQLException("Savepoint cannot be null."); + throw new SQLFeatureNotSupportedException("Savepoints are not supported."); } @@ -501,6 +549,9 @@ public class JdbcThinConnection implements Connection { @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException { ensureNotClosed(); + if (typeName == null) + throw new SQLException("Type name cannot be null."); + throw new SQLFeatureNotSupportedException("SQL-specific types are not supported."); } @@ -508,6 +559,9 @@ public class JdbcThinConnection implements Connection { @Override public Struct createStruct(String typeName, Object[] attrs) throws SQLException { ensureNotClosed(); + if (typeName == null) + throw new SQLException("Type name cannot be null."); + throw new SQLFeatureNotSupportedException("SQL-specific types are not supported."); } @@ -527,29 +581,43 @@ public class JdbcThinConnection implements Connection { /** {@inheritDoc} */ @Override public void setSchema(String schema) throws SQLException { + ensureNotClosed(); + this.schema = schema; } /** {@inheritDoc} */ @Override public String getSchema() throws SQLException { + ensureNotClosed(); + return schema; } /** {@inheritDoc} */ @Override public void abort(Executor executor) throws SQLException { + if (executor == null) + throw new SQLException("Executor cannot be null."); + close(); } /** {@inheritDoc} */ @Override public void setNetworkTimeout(Executor executor, int ms) throws SQLException { + ensureNotClosed(); + + if (executor == null) + throw new SQLException("Executor cannot be null."); + if (ms < 0) - throw new IllegalArgumentException("Timeout is below zero: " + ms); + throw new SQLException("Network timeout cannot be negative."); timeout = ms; } /** {@inheritDoc} */ @Override public int getNetworkTimeout() throws SQLException { + ensureNotClosed(); + return timeout; } http://git-wip-us.apache.org/repos/asf/ignite/blob/dbedbba0/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java index e6dfa59..d0c85b6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java @@ -63,9 +63,10 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep * * @param conn Connection. * @param sql SQL query. + * @param resHoldability Result set holdability. */ - JdbcThinPreparedStatement(JdbcThinConnection conn, String sql) { - super(conn); + JdbcThinPreparedStatement(JdbcThinConnection conn, String sql, int resHoldability) { + super(conn, resHoldability); this.sql = sql; } @@ -105,6 +106,21 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep } /** {@inheritDoc} */ + @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + throw new SQLException("The method 'executeUpdate(String, int)' is called on PreparedStatement instance."); + } + + /** {@inheritDoc} */ + @Override public int executeUpdate(String sql, int columnIndexes[]) throws SQLException { + throw new SQLException("The method 'executeUpdate(String, int[])' is called on PreparedStatement instance."); + } + + /** {@inheritDoc} */ + @Override public int executeUpdate(String sql, String columnNames[]) throws SQLException { + throw new SQLException("The method 'executeUpdate(String, String[])' is called on PreparedStatement instance."); + } + + /** {@inheritDoc} */ @Override public void setNull(int paramIdx, int sqlType) throws SQLException { setArgument(paramIdx, null); } @@ -483,6 +499,7 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public <T> T unwrap(Class<T> iface) throws SQLException { if (!isWrapperFor(iface)) throw new SQLException("Prepared statement is not a wrapper for " + iface.getName()); http://git-wip-us.apache.org/repos/asf/ignite/blob/dbedbba0/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java index 9457b30..1b7e87c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java @@ -244,6 +244,9 @@ public class JdbcThinResultSet implements ResultSet { /** {@inheritDoc} */ @Override public boolean wasNull() throws SQLException { + ensureNotClosed(); + ensureHasCurrentRow(); + return wasNull; } @@ -269,6 +272,9 @@ public class JdbcThinResultSet implements ResultSet { /** {@inheritDoc} */ @Override public boolean getBoolean(int colIdx) throws SQLException { + ensureNotClosed(); + ensureHasCurrentRow(); + try { Object val = curRow.get(colIdx - 1); @@ -1041,8 +1047,7 @@ public class JdbcThinResultSet implements ResultSet { @Override public void cancelRowUpdates() throws SQLException { ensureNotClosed(); - if (getConcurrency() == CONCUR_READ_ONLY) - throw new SQLException("The result set concurrency is CONCUR_READ_ONLY"); + throw new SQLFeatureNotSupportedException("Row updates are not supported."); } /** {@inheritDoc} */ @@ -1189,12 +1194,18 @@ public class JdbcThinResultSet implements ResultSet { /** {@inheritDoc} */ @Override public URL getURL(int colIdx) throws SQLException { - return getTypedValue(colIdx, URL.class); + ensureNotClosed(); + ensureHasCurrentRow(); + + throw new SQLFeatureNotSupportedException("URL type is not supported."); } /** {@inheritDoc} */ @Override public URL getURL(String colLb) throws SQLException { - return getTypedValue(colLb, URL.class); + ensureNotClosed(); + ensureHasCurrentRow(); + + throw new SQLFeatureNotSupportedException("URL type is not supported."); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/dbedbba0/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java index 59594ec..df77261 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java @@ -36,7 +36,6 @@ import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteResult; import static java.sql.ResultSet.CONCUR_READ_ONLY; import static java.sql.ResultSet.FETCH_FORWARD; -import static java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT; import static java.sql.ResultSet.TYPE_FORWARD_ONLY; /** @@ -67,6 +66,9 @@ public class JdbcThinStatement implements Statement { /** Result set or update count has been already read. */ private boolean alreadyRead; + /** Result set holdability*/ + private final int resHoldability; + /** Batch. */ protected List<JdbcQuery> batch; @@ -77,11 +79,13 @@ public class JdbcThinStatement implements Statement { * Creates new statement. * * @param conn JDBC connection. + * @param resHoldability Result set holdability. */ - JdbcThinStatement(JdbcThinConnection conn) { + JdbcThinStatement(JdbcThinConnection conn, int resHoldability) { assert conn != null; this.conn = conn; + this.resHoldability = resHoldability; } /** {@inheritDoc} */ @@ -169,6 +173,9 @@ public class JdbcThinStatement implements Statement { @Override public void setMaxFieldSize(int max) throws SQLException { ensureNotClosed(); + if (max < 0) + throw new SQLException("Invalid field limit."); + throw new SQLFeatureNotSupportedException("Field size limitation is not supported."); } @@ -183,6 +190,9 @@ public class JdbcThinStatement implements Statement { @Override public void setMaxRows(int maxRows) throws SQLException { ensureNotClosed(); + if (maxRows < 0) + throw new SQLException("Invalid max rows value."); + this.maxRows = maxRows; } @@ -202,6 +212,9 @@ public class JdbcThinStatement implements Statement { @Override public void setQueryTimeout(int timeout) throws SQLException { ensureNotClosed(); + if (timeout < 0) + throw new SQLException("Invalid timeout value."); + this.timeout = timeout * 1000; } @@ -281,7 +294,7 @@ public class JdbcThinStatement implements Statement { @Override public boolean getMoreResults() throws SQLException { ensureNotClosed(); - return false; + return getMoreResults(CLOSE_CURRENT_RESULT); } /** {@inheritDoc} */ @@ -289,7 +302,7 @@ public class JdbcThinStatement implements Statement { ensureNotClosed(); if (direction != FETCH_FORWARD) - throw new SQLFeatureNotSupportedException("Only forward direction is supported"); + throw new SQLFeatureNotSupportedException("Only forward direction is supported."); } /** {@inheritDoc} */ @@ -394,8 +407,20 @@ public class JdbcThinStatement implements Statement { @Override public boolean getMoreResults(int curr) throws SQLException { ensureNotClosed(); - if (curr == KEEP_CURRENT_RESULT || curr == CLOSE_ALL_RESULTS) - throw new SQLFeatureNotSupportedException("Multiple open results are not supported."); + switch (curr) { + case CLOSE_CURRENT_RESULT: + case CLOSE_ALL_RESULTS: + if (rs != null) + rs.close(); + + break; + + case KEEP_CURRENT_RESULT: + break; + + default: + throw new SQLException("Invalid 'current' parameter."); + } return false; } @@ -404,38 +429,52 @@ public class JdbcThinStatement implements Statement { @Override public ResultSet getGeneratedKeys() throws SQLException { ensureNotClosed(); - throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported ."); + throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported."); } /** {@inheritDoc} */ @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { ensureNotClosed(); - throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported ."); + switch (autoGeneratedKeys) { + case Statement.RETURN_GENERATED_KEYS: + throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported."); + + case Statement.NO_GENERATED_KEYS: + return executeUpdate(sql); + + default: + throw new SQLException("Invalid autoGeneratedKeys value"); + } } /** {@inheritDoc} */ @Override public int executeUpdate(String sql, int[] colIndexes) throws SQLException { ensureNotClosed(); - - throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported ."); + throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported."); } /** {@inheritDoc} */ @Override public int executeUpdate(String sql, String[] colNames) throws SQLException { ensureNotClosed(); - throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported ."); + throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported."); } /** {@inheritDoc} */ @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { ensureNotClosed(); - if (autoGeneratedKeys == RETURN_GENERATED_KEYS) - throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported ."); + switch (autoGeneratedKeys) { + case Statement.RETURN_GENERATED_KEYS: + throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported."); - return execute(sql); + case Statement.NO_GENERATED_KEYS: + return execute(sql); + + default: + throw new SQLException("Invalid autoGeneratedKeys value."); + } } /** {@inheritDoc} */ @@ -443,7 +482,7 @@ public class JdbcThinStatement implements Statement { ensureNotClosed(); if (colIndexes != null && colIndexes.length > 0) - throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported ."); + throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported."); return execute(sql); } @@ -453,7 +492,7 @@ public class JdbcThinStatement implements Statement { ensureNotClosed(); if (colNames != null && colNames.length > 0) - throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported ."); + throw new SQLFeatureNotSupportedException("Auto-generated columns are not supported."); return execute(sql); } @@ -462,7 +501,7 @@ public class JdbcThinStatement implements Statement { @Override public int getResultSetHoldability() throws SQLException { ensureNotClosed(); - return HOLD_CURSORS_OVER_COMMIT; + return resHoldability; } /** {@inheritDoc} */ @@ -486,6 +525,7 @@ public class JdbcThinStatement implements Statement { } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public <T> T unwrap(Class<T> iface) throws SQLException { if (!isWrapperFor(iface)) throw new SQLException("Statement is not a wrapper for " + iface.getName());
