/* * 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.ignite.internal.jdbc2; import java.io.Serializable; import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; import java.sql.Date; import java.sql.DriverManager; 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.concurrent.Callable; import org.apache.ignite.IgniteCache; import org.apache.ignite.cache.query.annotations.QuerySqlField; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.ConnectorConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; 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; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import static org.apache.ignite.IgniteJdbcDriver.CFG_URL_PREFIX; import static org.apache.ignite.cache.CacheMode.PARTITIONED; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; /** * Result set test. */ @SuppressWarnings("FloatingPointEquality") public class JdbcResultSetSelfTest extends GridCommonAbstractTest { /** IP finder. */ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); /** JDBC URL. */ private static final String BASE_URL = CFG_URL_PREFIX + "cache=default@modules/clients/src/test/config/jdbc-config.xml"; /** SQL query. */ private static final String SQL = "select id, boolVal, byteVal, shortVal, intVal, longVal, floatVal, " + "doubleVal, bigVal, strVal, arrVal, dateVal, timeVal, tsVal, urlVal, f1, f2, f3, _val, " + "boolVal2, boolVal3, boolVal4 " + "from TestObject where id = 1"; /** Statement. */ private Statement stmt; /** {@inheritDoc} */ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); CacheConfiguration<?,?> cache = defaultCacheConfiguration(); cache.setCacheMode(PARTITIONED); cache.setBackups(1); cache.setWriteSynchronizationMode(FULL_SYNC); cache.setIndexedTypes( Integer.class, TestObject.class ); cfg.setCacheConfiguration(cache); TcpDiscoverySpi disco = new TcpDiscoverySpi(); disco.setIpFinder(IP_FINDER); cfg.setDiscoverySpi(disco); cfg.setConnectorConfiguration(new ConnectorConfiguration()); return cfg; } /** {@inheritDoc} */ @Override protected void beforeTestsStarted() throws Exception { startGridsMultiThreaded(3); IgniteCache<Integer, TestObject> cache = grid(0).cache(DEFAULT_CACHE_NAME); assert cache != null; TestObject o = createObjectWithData(1); cache.put(1, o); cache.put(2, new TestObject(2)); cache.put(3, new TestObject(3)); Class.forName("org.apache.ignite.IgniteJdbcDriver"); } /** {@inheritDoc} */ @Override protected void afterTestsStopped() throws Exception { stopAllGrids(); } /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { stmt = DriverManager.getConnection(BASE_URL).createStatement(); assert stmt != null; assert !stmt.isClosed(); } /** {@inheritDoc} */ @Override protected void afterTest() throws Exception { if (stmt != null) { stmt.getConnection().close(); stmt.close(); assert stmt.isClosed(); } } /** * @param id ID. * @return Object. * @throws MalformedURLException If URL in incorrect. */ @SuppressWarnings("deprecation") private TestObject createObjectWithData(int id) throws MalformedURLException { TestObject o = new TestObject(id); o.boolVal = true; o.boolVal2 = true; o.boolVal3 = true; o.boolVal4 = true; o.byteVal = 1; o.shortVal = 1; o.intVal = 1; o.longVal = 1L; o.floatVal = 1.0f; o.doubleVal = 1.0d; o.bigVal = new BigDecimal(1); o.strVal = "str"; o.arrVal = new byte[] {1}; o.dateVal = new Date(1, 1, 1); o.timeVal = new Time(1, 1, 1); o.tsVal = new Timestamp(1); o.urlVal = new URL("http://abc.com/"); return o; } /** * @throws Exception If failed. */ public void testBoolean() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getBoolean("boolVal"); assert rs.getBoolean(2); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testBoolean2() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getBoolean("boolVal2"); assert rs.getBoolean(20); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testBoolean3() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getBoolean("boolVal3"); assert rs.getBoolean(21); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testBoolean4() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getBoolean("boolVal4"); assert rs.getBoolean(22); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testByte() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getByte("byteVal") == 1; assert rs.getByte(3) == 1; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testShort() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getShort("shortVal") == 1; assert rs.getShort(4) == 1; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testInteger() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getInt("intVal") == 1; assert rs.getInt(5) == 1; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testLong() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getLong("longVal") == 1; assert rs.getLong(6) == 1; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testFloat() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getFloat("floatVal") == 1.0; assert rs.getFloat(7) == 1.0; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testDouble() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getDouble("doubleVal") == 1.0; assert rs.getDouble(8) == 1.0; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testBigDecimal() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getBigDecimal("bigVal").intValue() == 1; assert rs.getBigDecimal(9).intValue() == 1; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testString() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert "str".equals(rs.getString("strVal")); assert "str".equals(rs.getString(10)); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testArray() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert Arrays.equals(rs.getBytes("arrVal"), new byte[] {1}); assert Arrays.equals(rs.getBytes(11), new byte[] {1}); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ @SuppressWarnings("deprecation") public void testDate() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getDate("dateVal").equals(new Date(1, 1, 1)); assert rs.getDate(12).equals(new Date(1, 1, 1)); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ @SuppressWarnings("deprecation") public void testTime() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getTime("timeVal").equals(new Time(1, 1, 1)); assert rs.getTime(13).equals(new Time(1, 1, 1)); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testTimestamp() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assert rs.getTimestamp("tsVal").getTime() == 1; assert rs.getTimestamp(14).getTime() == 1; } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testUrl() throws Exception { ResultSet rs = stmt.executeQuery(SQL); int cnt = 0; while (rs.next()) { if (cnt == 0) { assertTrue("http://abc.com/".equals(rs.getURL("urlVal").toString())); assertTrue("http://abc.com/".equals(rs.getURL(15).toString())); } cnt++; } assert cnt == 1; } /** * @throws Exception If failed. */ public void testObject() throws Exception { ResultSet rs = stmt.executeQuery(SQL); TestObjectField f1 = new TestObjectField(100, "AAAA"); TestObjectField f2 = new TestObjectField(500, "BBBB"); TestObject o = createObjectWithData(1); assertTrue(rs.next()); assertEquals(f1.toString(), rs.getObject("f1")); assertEquals(f1.toString(), rs.getObject(16)); assertEquals(f2.toString(), rs.getObject("f2")); assertEquals(f2.toString(), rs.getObject(17)); assertNull(rs.getObject("f3")); assertTrue(rs.wasNull()); assertNull(rs.getObject(18)); assertTrue(rs.wasNull()); assertEquals(o.toString(), rs.getObject("_val")); assertEquals(o.toString(), rs.getObject(19)); assertFalse(rs.next()); } /** * @throws Exception If failed. */ public void testNavigation() throws Exception { ResultSet rs = stmt.executeQuery("select * from TestObject where id > 0"); assertTrue(rs.isBeforeFirst()); assertFalse(rs.isAfterLast()); assertFalse(rs.isFirst()); assertFalse(rs.isLast()); assertEquals(0, rs.getRow()); assertTrue(rs.next()); assertFalse(rs.isBeforeFirst()); assertFalse(rs.isAfterLast()); assertTrue(rs.isFirst()); assertFalse(rs.isLast()); assertEquals(1, rs.getRow()); assertTrue(rs.next()); assertFalse(rs.isBeforeFirst()); assertFalse(rs.isAfterLast()); assertFalse(rs.isFirst()); assertFalse(rs.isLast()); assertEquals(2, rs.getRow()); assertTrue(rs.next()); assertFalse(rs.isBeforeFirst()); assertFalse(rs.isAfterLast()); assertFalse(rs.isFirst()); assertTrue(rs.isLast()); assertEquals(3, rs.getRow()); assertFalse(rs.next()); assertFalse(rs.isBeforeFirst()); assertTrue(rs.isAfterLast()); assertFalse(rs.isFirst()); assertFalse(rs.isLast()); assertEquals(0, rs.getRow()); } /** * @throws Exception If failed. */ public void testFetchSize() throws Exception { stmt.setFetchSize(1); ResultSet rs = stmt.executeQuery("select * from TestObject where id > 0"); assertTrue(rs.next()); assertTrue(rs.next()); assertTrue(rs.next()); stmt.setFetchSize(0); } /** * @throws Exception If failed. */ public void testNewQueryTaskFetchSize() throws Exception { stmt.setFetchSize(1); boolean res = stmt.execute("select * from TestObject where id > 0"); assertTrue(res); ResultSet rs = stmt.getResultSet(); assertTrue(rs.next()); assertTrue(rs.next()); assertTrue(rs.next()); stmt.setFetchSize(0); } /** * @throws Exception If failed. */ public void testFindColumn() throws Exception { final ResultSet rs = stmt.executeQuery(SQL); assertNotNull(rs); assertTrue(rs.next()); assert rs.findColumn("id") == 1; GridTestUtils.assertThrows( log, new Callable<Object>() { @Override public Object call() throws Exception { rs.findColumn("wrong"); return null; } }, SQLException.class, "Column not found: wrong" ); } /** * Test object. */ @SuppressWarnings("UnusedDeclaration") private static class BaseTestObject implements Serializable { /** */ @QuerySqlField(index = false) protected Boolean boolVal2; /** */ @QuerySqlField(index = false) protected boolean boolVal3; /** */ @QuerySqlField(index = false) protected boolean boolVal4; /** */ public boolean isBoolVal4() { return boolVal4; } } /** * Test object. */ @SuppressWarnings("UnusedDeclaration") private static class TestObject extends BaseTestObject { /** */ @QuerySqlField private final int id; /** */ @QuerySqlField(index = false) private Boolean boolVal; /** */ @QuerySqlField(index = false) private Byte byteVal; /** */ @QuerySqlField(index = false) private Short shortVal; /** */ @QuerySqlField(index = false) private Integer intVal; /** */ @QuerySqlField(index = false) private Long longVal; /** */ @QuerySqlField(index = false) private Float floatVal; /** */ @QuerySqlField(index = false) private Double doubleVal; /** */ @QuerySqlField(index = false) private BigDecimal bigVal; /** */ @QuerySqlField(index = false) private String strVal; /** */ @QuerySqlField(index = false) private byte[] arrVal; /** */ @QuerySqlField(index = false) private Date dateVal; /** */ @QuerySqlField(index = false) private Time timeVal; /** */ @QuerySqlField(index = false) private Timestamp tsVal; /** */ @QuerySqlField(index = false) private URL urlVal; /** */ @QuerySqlField(index = false) private TestObjectField f1 = new TestObjectField(100, "AAAA"); /** */ @QuerySqlField(index = false) private TestObjectField f2 = new TestObjectField(500, "BBBB"); /** */ @QuerySqlField(index = false) private TestObjectField f3; /** * @param id ID. */ private TestObject(int id) { this.id = id; } /** {@inheritDoc} */ @Override public String toString() { return S.toString(TestObject.class, this); } /** {@inheritDoc} */ @SuppressWarnings({"BigDecimalEquals", "EqualsHashCodeCalledOnUrl", "RedundantIfStatement"}) @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TestObject that = (TestObject)o; if (id != that.id) return false; if (!Arrays.equals(arrVal, that.arrVal)) return false; if (bigVal != null ? !bigVal.equals(that.bigVal) : that.bigVal != null) return false; if (boolVal != null ? !boolVal.equals(that.boolVal) : that.boolVal != null) return false; if (byteVal != null ? !byteVal.equals(that.byteVal) : that.byteVal != null) return false; if (dateVal != null ? !dateVal.equals(that.dateVal) : that.dateVal != null) return false; if (doubleVal != null ? !doubleVal.equals(that.doubleVal) : that.doubleVal != null) return false; if (f1 != null ? !f1.equals(that.f1) : that.f1 != null) return false; if (f2 != null ? !f2.equals(that.f2) : that.f2 != null) return false; if (f3 != null ? !f3.equals(that.f3) : that.f3 != null) return false; if (floatVal != null ? !floatVal.equals(that.floatVal) : that.floatVal != null) return false; if (intVal != null ? !intVal.equals(that.intVal) : that.intVal != null) return false; if (longVal != null ? !longVal.equals(that.longVal) : that.longVal != null) return false; if (shortVal != null ? !shortVal.equals(that.shortVal) : that.shortVal != null) return false; if (strVal != null ? !strVal.equals(that.strVal) : that.strVal != null) return false; if (timeVal != null ? !timeVal.equals(that.timeVal) : that.timeVal != null) return false; if (tsVal != null ? !tsVal.equals(that.tsVal) : that.tsVal != null) return false; if (urlVal != null ? !urlVal.equals(that.urlVal) : that.urlVal != null) return false; return true; } /** {@inheritDoc} */ @SuppressWarnings("EqualsHashCodeCalledOnUrl") @Override public int hashCode() { int res = id; res = 31 * res + (boolVal != null ? boolVal.hashCode() : 0); res = 31 * res + (byteVal != null ? byteVal.hashCode() : 0); res = 31 * res + (shortVal != null ? shortVal.hashCode() : 0); res = 31 * res + (intVal != null ? intVal.hashCode() : 0); res = 31 * res + (longVal != null ? longVal.hashCode() : 0); res = 31 * res + (floatVal != null ? floatVal.hashCode() : 0); res = 31 * res + (doubleVal != null ? doubleVal.hashCode() : 0); res = 31 * res + (bigVal != null ? bigVal.hashCode() : 0); res = 31 * res + (strVal != null ? strVal.hashCode() : 0); res = 31 * res + (arrVal != null ? Arrays.hashCode(arrVal) : 0); res = 31 * res + (dateVal != null ? dateVal.hashCode() : 0); res = 31 * res + (timeVal != null ? timeVal.hashCode() : 0); res = 31 * res + (tsVal != null ? tsVal.hashCode() : 0); res = 31 * res + (urlVal != null ? urlVal.hashCode() : 0); res = 31 * res + (f1 != null ? f1.hashCode() : 0); res = 31 * res + (f2 != null ? f2.hashCode() : 0); res = 31 * res + (f3 != null ? f3.hashCode() : 0); return res; } } /** * Test object field. */ @SuppressWarnings("PackageVisibleField") private static class TestObjectField implements Serializable { /** */ final int a; /** */ final String b; /** * @param a A. * @param b B. */ private TestObjectField(int a, String b) { this.a = a; this.b = b; } /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TestObjectField that = (TestObjectField)o; return a == that.a && !(b != null ? !b.equals(that.b) : that.b != null); } /** {@inheritDoc} */ @Override public int hashCode() { int res = a; res = 31 * res + (b != null ? b.hashCode() : 0); return res; } /** {@inheritDoc} */ @Override public String toString() { return S.toString(TestObjectField.class, this); } } }