diff --git a/src/test/java/com/qwazr/jdbc/cache/DbTestUtil.java b/src/test/java/com/qwazr/jdbc/cache/DbTestUtil.java new file mode 100644 index 0000000..07354a0 --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/DbTestUtil.java @@ -0,0 +1,248 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import org.apache.commons.io.IOUtils; +import org.hamcrest.CoreMatchers; +import org.junit.Assert; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.Date; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; + +class DbTestUtil { + + final static Object[] ROW1 = { 10, "TEN", null, null, null, null, null, 1.11D, 1.1F, (short) 1, 1000000L, "clob1" }; + final static Object[] ROW2 = { 20, "TWENTY", null, null, null, null, null, 2.22D, 2.2F, (short) 2, 2000000L, + "clob2" }; + final static Object[] ROW3 = { 30, "THIRTY", null, null, null, null, null, 3.33D, 3.3F, (short) 3, 3000000L, + "clob3" }; + final static Object[] ROW4 = { 40, null, null, null, null, null, null, 4.44D, 4.4F, (short) 4, 4000000L, "clob4" }; + final static Object[] ROW5 = { 50, null, null, null, null, null, null, 5.55D, 5.5F, (short) 5, 5000000L, null }; + + final static Object[][] ROWS = { ROW1, ROW2, ROW3, ROW4, ROW5 }; + + final static String SQL_TABLE = "CREATE TABLE FIRSTTABLE (ID INT PRIMARY KEY, NAME VARCHAR(12), TS TIMESTAMP, " + + "DT1 DATE, DT2 DATE, TI1 TIME, TI2 TIME, DBL DOUBLE, FL FLOAT, TI SMALLINT, BI BIGINT, CL CLOB)"; + final static String SQL_INSERT = "INSERT INTO FIRSTTABLE VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + + final static String[] COLUMNS = { "ID", "NAME", "TS", "DT1", "DT2", "TI1", "TI2", "DBL", "FL", "TI", "BI", "CL" }; + + final static String SQL_SIMPLE = "SELECT * FROM FIRSTTABLE"; + + final static String SQL_PREP_ARG = "SELECT * FROM FIRSTTABLE WHERE ID = ? OR ID = ?"; + + final static String SQL_PREP_NO_ARG = "SELECT * FROM FIRSTTABLE WHERE ID = " + ROW2[0]; + + static boolean initTestDb(String dbName) throws SQLException { + // Init the backend database so we can run our tests on it + Connection connection = DriverManager.getConnection("jdbc:derby:memory:" + dbName + ";create=true"); + connection.createStatement().executeUpdate(SQL_TABLE); + final PreparedStatement stmt = connection.prepareStatement(SQL_INSERT); + for (Object[] row : ROWS) { + int i = 0; + // For date/time/stamp columns + try { + Thread.sleep(10); + } catch (InterruptedException ignored) { + } + final long ts = System.currentTimeMillis(); + + stmt.setInt(i + 1, (Integer) row[i++]); + stmt.setString(i + 1, (String) row[i++]); + stmt.setTimestamp(i + 1, (Timestamp) (row[i++] = new Timestamp(ts))); + stmt.setDate(i + 1, (Date) (row[i++] = new Date(ts))); + stmt.setDate(i + 1, (Date) (row[i++] = new Date(ts)), Calendar.getInstance()); + stmt.setTime(i + 1, (Time) (row[i++] = new Time(ts))); + stmt.setTime(i + 1, (Time) (row[i++] = new Time(ts)), Calendar.getInstance()); + stmt.setDouble(i + 1, (double) row[i++]); + stmt.setFloat(i + 1, (float) row[i++]); + stmt.setShort(i + 1, (short) row[i++]); + stmt.setLong(i + 1, (long) row[i++]); + final String clob = (String) row[i++]; + stmt.setClob(i, clob == null ? null : new StringReader(clob)); + Assert.assertEquals(1, stmt.executeUpdate()); + } + return true; + } + + static void checkColString(final Object object, final int i, final ResultSet resultSet) throws SQLException { + if (object == null) { + Assert.assertNull(resultSet.getString(COLUMNS[i])); + Assert.assertNull(resultSet.getString(i + 1)); + } else { + Assert.assertEquals(object.toString(), resultSet.getString(COLUMNS[i])); + Assert.assertEquals(object.toString(), resultSet.getString(i + 1)); + } + } + + static void checkWasNull(final Object object, final int i, final ResultSet resultSet) throws SQLException { + if (object == null) + Assert.assertTrue(resultSet.wasNull()); + else + Assert.assertFalse(resultSet.wasNull()); + } + + static void checkResultSet(ResultSet resultSet, Object[]... rows) throws SQLException, IOException { + Assert.assertNotNull("The resultSet is null", resultSet); + + if (resultSet.getType() != ResultSet.TYPE_FORWARD_ONLY) + Assert.assertTrue(resultSet.isBeforeFirst()); + + int count = 0; + while (resultSet.next()) { + int i = 0; + int j = 1; + final Object[] row = rows[count]; + + if (resultSet.getType() != ResultSet.TYPE_FORWARD_ONLY) { + if (count == 0) + Assert.assertTrue(resultSet.isFirst()); + else + Assert.assertFalse(resultSet.isFirst()); + } + + Assert.assertEquals(row[i], resultSet.getInt(COLUMNS[i])); + Assert.assertEquals(row[i], resultSet.getInt(j++)); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i], resultSet.getString(COLUMNS[i])); + Assert.assertEquals(row[i], resultSet.getString(j++)); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i], resultSet.getTimestamp(COLUMNS[i])); + Assert.assertEquals(row[i], resultSet.getTimestamp(j++)); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i].toString(), resultSet.getDate(COLUMNS[i]).toString()); + Assert.assertEquals(row[i].toString(), resultSet.getDate(j++).toString()); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i].toString(), resultSet.getDate(COLUMNS[i], Calendar.getInstance()).toString()); + Assert.assertEquals(row[i].toString(), resultSet.getDate(j++, Calendar.getInstance()).toString()); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i].toString(), resultSet.getTime(COLUMNS[i]).toString()); + Assert.assertEquals(row[i].toString(), resultSet.getTime(j++).toString()); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i].toString(), resultSet.getTime(COLUMNS[i], Calendar.getInstance()).toString()); + Assert.assertEquals(row[i].toString(), resultSet.getTime(j++, Calendar.getInstance()).toString()); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i], resultSet.getDouble(COLUMNS[i])); + Assert.assertEquals(row[i], resultSet.getDouble(j++)); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i], resultSet.getFloat(COLUMNS[i])); + Assert.assertEquals(row[i], resultSet.getFloat(j++)); + // Disabled because precision issue + // checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i], resultSet.getShort(COLUMNS[i])); + Assert.assertEquals(row[i], resultSet.getShort(j++)); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + Assert.assertEquals(row[i], resultSet.getLong(COLUMNS[i])); + Assert.assertEquals(row[i], resultSet.getLong(j++)); + checkColString(row[i], i, resultSet); + checkWasNull(row[i], i++, resultSet); + + //CLob + Clob clob = resultSet.getClob(COLUMNS[i]); + if (clob == null) + Assert.assertNull(row[i]); + else { + Assert.assertEquals(row[i], clob.getSubString(1, (int) clob.length())); + Assert.assertEquals(row[i], IOUtils.toString(clob.getCharacterStream(1, (int) clob.length()))); + Assert.assertEquals(row[i], IOUtils.toString(clob.getCharacterStream())); + Assert.assertEquals(row[i], IOUtils.toString(clob.getAsciiStream(), Charset.defaultCharset())); + } + checkWasNull(row[i], i++, resultSet); + + count++; + } + Assert.assertEquals(rows.length, count); + + if (resultSet.getType() != ResultSet.TYPE_FORWARD_ONLY) + Assert.assertTrue(resultSet.isAfterLast()); + + Assert.assertFalse(resultSet.isClosed()); + resultSet.close(); + Assert.assertTrue(resultSet.isClosed()); + } + + static PreparedStatement getPreparedStatement(Connection cnx, Object[] row1, Object[] row2) throws SQLException { + final PreparedStatement stmt = cnx.prepareStatement(SQL_PREP_ARG); + stmt.setInt(1, (int) row1[0]); + stmt.setInt(2, (int) row2[0]); + return stmt; + } + + static ResultSet executeQuery(Connection cnx) throws SQLException { + final Statement stmt = cnx.createStatement(); + return stmt.executeQuery(SQL_SIMPLE); + } + + static CallableStatement getCallableStatement(Connection cnx) throws SQLException { + return cnx.prepareCall(SQL_PREP_NO_ARG); + } + + static ResultSet updateGetResultSet(Connection cnx) throws SQLException { + final Statement stmt = cnx.createStatement(); + stmt.execute(SQL_SIMPLE); + return stmt.getResultSet(); + } + + interface RunnableEx { + void run() throws SQLException; + } + + static void checkNotSupported(RunnableEx runnable) throws SQLException { + try { + runnable.run(); + Assert.fail("SQLFeatureNotSupportedException or SQLException not thrown"); + } catch (SQLFeatureNotSupportedException ignored) { + } catch (SQLException ignored) { + // Some Drivers like Derby don't throw SQLFeatureNotSupportedException but SQLException + Assert.assertThat(ignored.getMessage(), CoreMatchers.containsString("not allowed because")); + } + } +} diff --git a/src/test/java/com/qwazr/jdbc/cache/DerbyTest.java b/src/test/java/com/qwazr/jdbc/cache/DerbyTest.java deleted file mode 100644 index 1420974..0000000 --- a/src/test/java/com/qwazr/jdbc/cache/DerbyTest.java +++ /dev/null @@ -1,518 +0,0 @@ -/** - * Copyright 2016 Emmanuel Keller / QWAZR - *
- * Licensed 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 com.qwazr.jdbc.cache; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.sql.CallableStatement; -import java.sql.Clob; -import java.sql.Connection; -import java.sql.Date; -import java.sql.Driver; -import java.sql.DriverManager; -import java.sql.DriverPropertyInfo; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.SQLFeatureNotSupportedException; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Calendar; -import java.util.Properties; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Logger; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -abstract public class DerbyTest { - - private final static Logger LOGGER = Logger.getLogger(DerbyTest.class.getName()); - - private static Connection cnxCacheDisable; - private static Connection cnxCacheEnable; - private static Connection cnxCacheNoBackend; - - abstract Class extends ResultSet> expectedResultSetClass(); - abstract String getOrSetJdbcCacheUrl(); - abstract String getDerbyDbName(); - - @BeforeClass - public static void init() throws ClassNotFoundException, IOException { - Class.forName("com.qwazr.jdbc.cache.Driver"); - } - - @Test - public void test000testDriver() throws SQLException { - Driver driver = DriverManager.getDriver(getOrSetJdbcCacheUrl()); - Assert.assertNotNull(driver); - Assert.assertEquals(1, driver.getMajorVersion()); - Assert.assertEquals(3, driver.getMinorVersion()); - Assert.assertNotNull(driver.getParentLogger()); - Assert.assertFalse(driver.jdbcCompliant()); - DriverPropertyInfo[] infos = driver.getPropertyInfo(null, null); - Assert.assertNotNull(infos); - Assert.assertEquals(3, infos.length); - Assert.assertEquals(com.qwazr.jdbc.cache.Driver.CACHE_DRIVER_URL, infos[0].name); - Assert.assertEquals(com.qwazr.jdbc.cache.Driver.CACHE_DRIVER_CLASS, infos[1].name); - Assert.assertEquals(com.qwazr.jdbc.cache.Driver.CACHE_DRIVER_ACTIVE, infos[2].name); - } - - @Test - public void test001initConnectionWithoutCache() throws SQLException, IOException, ClassNotFoundException { - final Properties info = new Properties(); - info.setProperty("cache.driver.url", "jdbc:derby:memory:" + getDerbyDbName() + ";create=true"); - info.setProperty("cache.driver.class", "org.apache.derby.jdbc.EmbeddedDriver"); - info.setProperty("cache.driver.active", "false"); - cnxCacheDisable = DriverManager.getConnection(getOrSetJdbcCacheUrl(), info); - Assert.assertNotNull(cnxCacheDisable); - } - - @Test - public void test002initConnectionWithCache() throws SQLException, IOException, ClassNotFoundException { - final Properties info = new Properties(); - info.setProperty("cache.driver.url", "jdbc:derby:memory:" + getDerbyDbName() + ";create=true"); - cnxCacheEnable = DriverManager.getConnection(getOrSetJdbcCacheUrl(), info); - Assert.assertNotNull(cnxCacheEnable); - } - - @Test - public void test003initConnectionNoBackend() throws SQLException, IOException, ClassNotFoundException { - cnxCacheNoBackend = DriverManager.getConnection(getOrSetJdbcCacheUrl()); - Assert.assertNotNull(cnxCacheNoBackend); - } - - final static Object[] ROW1 = { 10, "TEN", null, null, null, null, null, 1.11D, 1.1F, (short) 1, 1000000L, "clob1" }; - final static Object[] ROW2 = { 20, "TWENTY", null, null, null, null, null, 2.22D, 2.2F, (short) 2, 2000000L, - "clob2" }; - final static Object[] ROW3 = { 30, "THIRTY", null, null, null, null, null, 3.33D, 3.3F, (short) 3, 3000000L, - "clob3" }; - final static Object[] ROW4 = { 40, null, null, null, null, null, null, 4.44D, 4.4F, (short) 4, 4000000L, "clob4" }; - final static Object[] ROW5 = { 50, null, null, null, null, null, null, 5.55D, 5.5F, (short) 5, 5000000L, null }; - - final static Object[][] ROWS = { ROW1, ROW2, ROW3, ROW4, ROW5 }; - - final static String[] COLUMNS = { "ID", "NAME", "TS", "DT1", "DT2", "TI1", "TI2", "DBL", "FL", "TI", "BI", "CL" }; - - final static String SQL_TABLE = "CREATE TABLE FIRSTTABLE (ID INT PRIMARY KEY, NAME VARCHAR(12), TS TIMESTAMP, " - + "DT1 DATE, DT2 DATE, TI1 TIME, TI2 TIME, DBL DOUBLE, FL FLOAT, TI SMALLINT, BI BIGINT, CL CLOB)"; - final static String SQL_INSERT = "INSERT INTO FIRSTTABLE VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; - - @Test - public void test100createTableAndDataSet() throws SQLException, InterruptedException { - cnxCacheDisable.createStatement().executeUpdate(SQL_TABLE); - final PreparedStatement stmt = cnxCacheDisable.prepareStatement(SQL_INSERT); - for (Object[] row : ROWS) { - int i = 0; - // For date/time/stamp columns - Thread.sleep(10); - final long ts = System.currentTimeMillis(); - - stmt.setInt(i + 1, (Integer) row[i++]); - stmt.setString(i + 1, (String) row[i++]); - stmt.setTimestamp(i + 1, (Timestamp) (row[i++] = new Timestamp(ts))); - stmt.setDate(i + 1, (Date) (row[i++] = new Date(ts))); - stmt.setDate(i + 1, (Date) (row[i++] = new Date(ts)), Calendar.getInstance()); - stmt.setTime(i + 1, (Time) (row[i++] = new Time(ts))); - stmt.setTime(i + 1, (Time) (row[i++] = new Time(ts)), Calendar.getInstance()); - stmt.setDouble(i + 1, (double) row[i++]); - stmt.setFloat(i + 1, (float) row[i++]); - stmt.setShort(i + 1, (short) row[i++]); - stmt.setLong(i + 1, (long) row[i++]); - final String clob = (String) row[i++]; - stmt.setClob(i, clob == null ? null : new StringReader(clob)); - Assert.assertEquals(1, stmt.executeUpdate()); - } - } - - private void checkColString(final Object object, final int i, final ResultSet resultSet) throws SQLException { - if (object == null) { - Assert.assertNull(resultSet.getString(COLUMNS[i])); - Assert.assertNull(resultSet.getString(i + 1)); - } else { - Assert.assertEquals(object.toString(), resultSet.getString(COLUMNS[i])); - Assert.assertEquals(object.toString(), resultSet.getString(i + 1)); - } - } - - private void checkWasNull(final Object object, final int i, final ResultSet resultSet) throws SQLException { - if (object == null) - Assert.assertTrue(resultSet.wasNull()); - else - Assert.assertFalse(resultSet.wasNull()); - } - - protected ResultSet checkCache(ResultSet resultSet) { - Assert.assertEquals(expectedResultSetClass().getName(), resultSet.getClass().getName()); - return resultSet; - } - - protected ResultSet checkNoCache(ResultSet resultSet) { - Assert.assertNotEquals(expectedResultSetClass().getName(), resultSet.getClass().getName()); - return resultSet; - } - - private void checkResultSet(ResultSet resultSet, Object[]... rows) throws SQLException, IOException { - Assert.assertNotNull("The resultSet is null", resultSet); - - if (resultSet.getType() != ResultSet.TYPE_FORWARD_ONLY) - Assert.assertTrue(resultSet.isBeforeFirst()); - - int count = 0; - while (resultSet.next()) { - int i = 0; - int j = 1; - final Object[] row = rows[count]; - - if (resultSet.getType() != ResultSet.TYPE_FORWARD_ONLY) { - if (count == 0) - Assert.assertTrue(resultSet.isFirst()); - else - Assert.assertFalse(resultSet.isFirst()); - } - - Assert.assertEquals(row[i], resultSet.getInt(COLUMNS[i])); - Assert.assertEquals(row[i], resultSet.getInt(j++)); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i], resultSet.getString(COLUMNS[i])); - Assert.assertEquals(row[i], resultSet.getString(j++)); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i], resultSet.getTimestamp(COLUMNS[i])); - Assert.assertEquals(row[i], resultSet.getTimestamp(j++)); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i].toString(), resultSet.getDate(COLUMNS[i]).toString()); - Assert.assertEquals(row[i].toString(), resultSet.getDate(j++).toString()); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i].toString(), resultSet.getDate(COLUMNS[i], Calendar.getInstance()).toString()); - Assert.assertEquals(row[i].toString(), resultSet.getDate(j++, Calendar.getInstance()).toString()); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i].toString(), resultSet.getTime(COLUMNS[i]).toString()); - Assert.assertEquals(row[i].toString(), resultSet.getTime(j++).toString()); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i].toString(), resultSet.getTime(COLUMNS[i], Calendar.getInstance()).toString()); - Assert.assertEquals(row[i].toString(), resultSet.getTime(j++, Calendar.getInstance()).toString()); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i], resultSet.getDouble(COLUMNS[i])); - Assert.assertEquals(row[i], resultSet.getDouble(j++)); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i], resultSet.getFloat(COLUMNS[i])); - Assert.assertEquals(row[i], resultSet.getFloat(j++)); - // Disabled because precision issue - // checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i], resultSet.getShort(COLUMNS[i])); - Assert.assertEquals(row[i], resultSet.getShort(j++)); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - Assert.assertEquals(row[i], resultSet.getLong(COLUMNS[i])); - Assert.assertEquals(row[i], resultSet.getLong(j++)); - checkColString(row[i], i, resultSet); - checkWasNull(row[i], i++, resultSet); - - //CLob - Clob clob = resultSet.getClob(COLUMNS[i]); - if (clob == null) - Assert.assertNull(row[i]); - else { - Assert.assertEquals(row[i], clob.getSubString(1, (int) clob.length())); - Assert.assertEquals(row[i], IOUtils.toString(clob.getCharacterStream(1, (int) clob.length()))); - Assert.assertEquals(row[i], IOUtils.toString(clob.getCharacterStream())); - Assert.assertEquals(row[i], IOUtils.toString(clob.getAsciiStream(), Charset.defaultCharset())); - } - checkWasNull(row[i], i++, resultSet); - - count++; - } - Assert.assertEquals(rows.length, count); - - if (resultSet.getType() != ResultSet.TYPE_FORWARD_ONLY) - Assert.assertTrue(resultSet.isAfterLast()); - - Assert.assertFalse(resultSet.isClosed()); - resultSet.close(); - Assert.assertTrue(resultSet.isClosed()); - } - - final static String SQL_SIMPLE = "SELECT * FROM FIRSTTABLE"; - - private ResultSet executeQuery(Connection cnx) throws SQLException { - final Statement stmt = cnx.createStatement(); - return stmt.executeQuery(SQL_SIMPLE); - } - - @Test - public void test110TestSimpleStatement() throws SQLException, IOException { - // First without the cache - checkResultSet(checkNoCache(executeQuery(cnxCacheDisable)), ROWS); - // Second the cache is written - checkResultSet(checkCache(executeQuery(cnxCacheEnable)), ROWS); - // Third the cache is read - checkResultSet(checkCache(executeQuery(cnxCacheEnable)), ROWS); - // Last, without the backend - checkResultSet(checkCache(executeQuery(cnxCacheNoBackend)), ROWS); - } - - private ResultSet updateGetResultSet(Connection cnx) throws SQLException { - final Statement stmt = cnx.createStatement(); - stmt.execute(SQL_SIMPLE); - return stmt.getResultSet(); - } - - @Test - public void test110TestUpdateAndGetResultSet() throws SQLException, IOException { - checkResultSet(checkNoCache(updateGetResultSet(cnxCacheDisable)), ROWS); - checkResultSet(checkCache(updateGetResultSet(cnxCacheEnable)), ROWS); - checkResultSet(checkCache(updateGetResultSet(cnxCacheNoBackend)), ROWS); - } - - final static String SQL_PREP_ARG = "SELECT * FROM FIRSTTABLE WHERE ID = ? OR ID = ?"; - - private PreparedStatement getPreparedStatement(Connection cnx, Object[] row1, Object[] row2) throws SQLException { - final PreparedStatement stmt = cnx.prepareStatement(SQL_PREP_ARG); - stmt.setInt(1, (int) row1[0]); - stmt.setInt(2, (int) row2[0]); - return stmt; - } - - final static String SQL_PREP_NO_ARG = "SELECT * FROM FIRSTTABLE WHERE ID = " + ROW2[0]; - - private CallableStatement getCallableStatement(Connection cnx) throws SQLException { - final CallableStatement stmt = cnx.prepareCall(SQL_PREP_NO_ARG); - return stmt; - } - - @Test - public void test110TestPreparedStatementWithoutCache() throws SQLException, IOException { - checkResultSet(checkNoCache(getPreparedStatement(cnxCacheDisable, ROW1, ROW4).executeQuery()), ROW1, ROW4); - } - - @Test - public void test110TestCallableStatementWithoutCache() throws SQLException, IOException { - checkResultSet(checkNoCache(getCallableStatement(cnxCacheDisable).executeQuery()), ROW2); - } - - @Test - public void test120TestPreparedStatementWithCache() throws SQLException, IOException { - final PreparedStatement stmt = getPreparedStatement(cnxCacheEnable, ROW1, ROW4); - // First the cache is written - checkResultSet(checkCache(stmt.executeQuery()), ROW1, ROW4); - // Second the cache is read - checkResultSet(checkCache(stmt.executeQuery()), ROW1, ROW4); - } - - @Test - public void test120TestCallableStatementWithCache() throws SQLException, IOException { - final CallableStatement stmt = getCallableStatement(cnxCacheEnable); - // First the cache is written - checkResultSet(checkCache(stmt.executeQuery()), ROW2); - // Second the cache is read - checkResultSet(checkCache(stmt.executeQuery()), ROW2); - } - - @Test - public void test130TestPreparedStatementNoBackend() throws SQLException, IOException { - final PreparedStatement stmt = getPreparedStatement(cnxCacheNoBackend, ROW1, ROW4); - checkResultSet(checkCache(stmt.executeQuery()), ROW1, ROW4); - } - - @Test - public void test130TestCallableStatementNoBackend() throws SQLException, IOException { - final PreparedStatement stmt = getCallableStatement(cnxCacheNoBackend); - checkResultSet(checkCache(stmt.executeQuery()), ROW2); - } - - @Test - public void test135TestPreparedStatementGetResultSet() throws SQLException, IOException { - final PreparedStatement stmt = getPreparedStatement(cnxCacheNoBackend, ROW1, ROW4); - stmt.execute(); - checkResultSet(checkCache(stmt.getResultSet()), ROW1, ROW4); - } - - @Test - public void test135TestCallableStatementGetResultSet() throws SQLException, IOException { - final CallableStatement stmt = getCallableStatement(cnxCacheEnable); - stmt.execute(); - checkResultSet(checkCache(stmt.getResultSet()), ROW2); - } - - @Test - public void test500ThreadSafeTest() throws InterruptedException { - final ExecutorService executor = Executors.newFixedThreadPool(8); - final long exitTime = System.currentTimeMillis() + 10 * 1000; - final AtomicInteger count = new AtomicInteger(); - try { - for (int i = 0; i < 8; i++) { - executor.submit(() -> { - while (System.currentTimeMillis() < exitTime) - try { - test110TestPreparedStatementWithoutCache(); - test120TestPreparedStatementWithCache(); - count.incrementAndGet(); - } catch (SQLException | IOException e) { - throw new RuntimeException(e); - } - }); - executor.submit(() -> { - while (System.currentTimeMillis() < exitTime) - try { - test110TestCallableStatementWithoutCache(); - test120TestCallableStatementWithCache(); - count.incrementAndGet(); - } catch (SQLException | IOException e) { - throw new RuntimeException(e); - } - }); - } - executor.shutdown(); - executor.awaitTermination(1, TimeUnit.HOURS); - LOGGER.info("Iteration count: " + count.get()); - } finally { - if (!executor.isShutdown()) - executor.shutdownNow(); - } - } - - @Test - public void test600TestResultSetMetaData() throws SQLException { - final ResultSetMetaData metaData = getPreparedStatement(cnxCacheEnable, ROW1, ROW4).executeQuery() - .getMetaData(); - Assert.assertNotNull(metaData); - int colCount = metaData.getColumnCount(); - Assert.assertTrue(colCount > 0); - for (int i = 1; i <= colCount; i++) { - Assert.assertNotNull(metaData.getColumnName(i)); - Assert.assertNotNull(metaData.getColumnLabel(i)); - Assert.assertNotNull(metaData.getColumnTypeName(i)); - Assert.assertNotNull(metaData.getCatalogName(i)); - Assert.assertNotNull(metaData.getColumnClassName(i)); - Assert.assertTrue(metaData.getColumnDisplaySize(i) > 0); - Assert.assertFalse(metaData.isReadOnly(i)); - Assert.assertNotNull(metaData.getSchemaName(i)); - Assert.assertNotNull(metaData.getTableName(i)); - Assert.assertTrue(metaData.getPrecision(i) > 0); - Assert.assertTrue(metaData.isSearchable(i)); - if (i == 1) { - Assert.assertTrue(metaData.isSigned(i)); - Assert.assertEquals(0, metaData.getScale(i)); - Assert.assertEquals(ResultSetMetaData.columnNoNulls, metaData.isNullable(i)); - Assert.assertFalse(metaData.isCaseSensitive(i)); - Assert.assertFalse(metaData.isAutoIncrement(i)); - Assert.assertFalse(metaData.isCurrency(i)); - Assert.assertFalse(metaData.isWritable(i)); - } else { - Assert.assertEquals(ResultSetMetaData.columnNullable, metaData.isNullable(i)); - } - } - } - - private interface RunnableEx { - - void run() throws SQLException; - } - - private void checkNotSupported(RunnableEx runnable) throws SQLException { - try { - runnable.run(); - Assert.fail("SQLFeatureNotSupportedException not thrown"); - } catch (SQLFeatureNotSupportedException e) { - } - } - - @Test - public void test800ResultSetNotSupportedMethod() throws SQLException { - ResultSet resultSet = getPreparedStatement(cnxCacheEnable, ROW1, ROW4).executeQuery(); - checkNotSupported(() -> resultSet.updateArray(1, null)); - checkNotSupported(() -> resultSet.updateArray("id", null)); - checkNotSupported(() -> resultSet.updateAsciiStream(1, null)); - checkNotSupported(() -> resultSet.updateAsciiStream("id", null)); - checkNotSupported(() -> resultSet.updateBigDecimal(1, null)); - checkNotSupported(() -> resultSet.updateBigDecimal("id", null)); - checkNotSupported(() -> resultSet.updateByte(1, (byte) 0)); - checkNotSupported(() -> resultSet.updateByte("id", (byte) 0)); - checkNotSupported(() -> resultSet.updateBytes(1, null)); - checkNotSupported(() -> resultSet.updateBytes("id", null)); - checkNotSupported(() -> resultSet.updateBoolean(1, false)); - checkNotSupported(() -> resultSet.updateBoolean("id", false)); - checkNotSupported(() -> resultSet.updateDate(1, null)); - checkNotSupported(() -> resultSet.updateDate("id", null)); - checkNotSupported(() -> resultSet.updateDouble(1, 0d)); - checkNotSupported(() -> resultSet.updateDouble("id", 0d)); - checkNotSupported(() -> resultSet.updateFloat(1, 0f)); - checkNotSupported(() -> resultSet.updateFloat("id", 0f)); - checkNotSupported(() -> resultSet.updateInt(1, 0)); - checkNotSupported(() -> resultSet.updateInt("id", 0)); - checkNotSupported(() -> resultSet.updateLong(1, 0)); - checkNotSupported(() -> resultSet.updateLong("id", 0)); - checkNotSupported(() -> resultSet.updateRowId(1, null)); - checkNotSupported(() -> resultSet.updateRowId("id", null)); - checkNotSupported(() -> resultSet.updateNull(1)); - checkNotSupported(() -> resultSet.updateNull("id")); - checkNotSupported(() -> resultSet.updateObject(1, null)); - checkNotSupported(() -> resultSet.updateObject("id", null)); - } - - @Test - public void test900TestCacheAPI() throws SQLException { - ResultSetCache cache = com.qwazr.jdbc.cache.Driver.getCache(cnxCacheEnable); - Assert.assertNotNull(cache); - Assert.assertEquals(3, cache.size()); - - Assert.assertEquals(0, cache.active()); - - Statement stmt = getPreparedStatement(cnxCacheEnable, ROW1, ROW4); - Assert.assertTrue(cache.exists(stmt)); - - Assert.assertFalse(cache.active(stmt)); - - cache.flush(stmt); - Assert.assertEquals(2, cache.size()); - - cache.flush(); - Assert.assertEquals(0, cache.size()); - } - -} diff --git a/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheDisabledJdbcWithDerbyBackendTest.java b/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheDisabledJdbcWithDerbyBackendTest.java new file mode 100644 index 0000000..444f199 --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheDisabledJdbcWithDerbyBackendTest.java @@ -0,0 +1,50 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import org.apache.derby.impl.jdbc.EmbedResultSet42; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +public class InMemoryCacheDisabledJdbcWithDerbyBackendTest extends InMemoryCacheJdbcWithDerbyBackendTest { + @Override + Class extends ResultSet> expectedResultSetClass() { + return EmbedResultSet42.class; + } + + @Override + boolean isCacheEnabled() { + return false; + } + + @Override + String getDerbyDbName() { + return "inMemCacheDisabled"; + } + + @Override + Connection getConnection() throws SQLException { + final Properties info = new Properties(); + info.setProperty("cache.driver.url", "jdbc:derby:memory:" + getDerbyDbName() + ";create=true"); + info.setProperty("cache.driver.class", "org.apache.derby.jdbc.EmbeddedDriver"); + info.setProperty("cache.driver.active", "false"); + return DriverManager.getConnection(getOrSetJdbcCacheUrl(), info); + } +} diff --git a/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheEnabledJdbcWithDerbyBackendTest.java b/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheEnabledJdbcWithDerbyBackendTest.java new file mode 100644 index 0000000..12b09b1 --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheEnabledJdbcWithDerbyBackendTest.java @@ -0,0 +1,46 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +public class InMemoryCacheEnabledJdbcWithDerbyBackendTest extends InMemoryCacheJdbcWithDerbyBackendTest { + @Override + Class extends ResultSet> expectedResultSetClass() { + return CachedInMemoryResultSet.class; + } + + @Override + boolean isCacheEnabled() { + return true; + } + + @Override + String getDerbyDbName() { + return "inMemCacheEnabled"; + } + + @Override + Connection getConnection() throws SQLException { + final Properties info = new Properties(); + info.setProperty("cache.driver.url", "jdbc:derby:memory:" + getDerbyDbName() + ";create=true"); + return DriverManager.getConnection(getOrSetJdbcCacheUrl(), info); + } +} diff --git a/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheDerbyTest.java b/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheJdbcWithDerbyBackendTest.java similarity index 63% rename from src/test/java/com/qwazr/jdbc/cache/InMemoryCacheDerbyTest.java rename to src/test/java/com/qwazr/jdbc/cache/InMemoryCacheJdbcWithDerbyBackendTest.java index 8452858..aac3cc3 100644 --- a/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheDerbyTest.java +++ b/src/test/java/com/qwazr/jdbc/cache/InMemoryCacheJdbcWithDerbyBackendTest.java @@ -15,26 +15,9 @@ */ package com.qwazr.jdbc.cache; -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -import java.io.File; -import java.sql.ResultSet; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class InMemoryCacheDerbyTest extends DerbyTest { - @Override - Class extends ResultSet> expectedResultSetClass() { - return CachedInMemoryResultSet.class; - } - +public abstract class InMemoryCacheJdbcWithDerbyBackendTest extends JdbcWithDerbyBackendTest { @Override String getOrSetJdbcCacheUrl() { return "jdbc:cache:mem:foo"; } - - @Override - String getDerbyDbName() { - return "myDB2"; - } } diff --git a/src/test/java/com/qwazr/jdbc/cache/JdbcTest.java b/src/test/java/com/qwazr/jdbc/cache/JdbcTest.java new file mode 100644 index 0000000..6b829b6 --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/JdbcTest.java @@ -0,0 +1,65 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.DriverPropertyInfo; +import java.sql.SQLException; +import java.util.logging.Logger; + +public abstract class JdbcTest { + final static Logger LOGGER = Logger.getLogger(JdbcTest.class.getName()); + + abstract String getOrSetJdbcCacheUrl(); + abstract Connection getConnection() throws SQLException; + + @BeforeClass + public static void initDriver() throws ClassNotFoundException, IOException { + Class.forName("com.qwazr.jdbc.cache.Driver"); + } + + Connection getNoBackendConnection() throws SQLException { + return DriverManager.getConnection(getOrSetJdbcCacheUrl()); + } + + @Test + public void test000testDriver() throws SQLException { + java.sql.Driver driver = DriverManager.getDriver(getOrSetJdbcCacheUrl()); + Assert.assertNotNull(driver); + Assert.assertEquals(1, driver.getMajorVersion()); + Assert.assertEquals(3, driver.getMinorVersion()); + Assert.assertNotNull(driver.getParentLogger()); + Assert.assertFalse(driver.jdbcCompliant()); + DriverPropertyInfo[] infos = driver.getPropertyInfo(null, null); + Assert.assertNotNull(infos); + Assert.assertEquals(3, infos.length); + Assert.assertEquals(com.qwazr.jdbc.cache.Driver.CACHE_DRIVER_URL, infos[0].name); + Assert.assertEquals(com.qwazr.jdbc.cache.Driver.CACHE_DRIVER_CLASS, infos[1].name); + Assert.assertEquals(com.qwazr.jdbc.cache.Driver.CACHE_DRIVER_ACTIVE, infos[2].name); + } + + @Test + public void test002initConnection() throws SQLException { + Assert.assertNotNull(getConnection()); + Assert.assertNotNull(getNoBackendConnection()); + } +} diff --git a/src/test/java/com/qwazr/jdbc/cache/JdbcWithDerbyBackendTest.java b/src/test/java/com/qwazr/jdbc/cache/JdbcWithDerbyBackendTest.java new file mode 100644 index 0000000..73d6bf4 --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/JdbcWithDerbyBackendTest.java @@ -0,0 +1,267 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static com.qwazr.jdbc.cache.DbTestUtil.ROW1; +import static com.qwazr.jdbc.cache.DbTestUtil.ROW2; +import static com.qwazr.jdbc.cache.DbTestUtil.ROW4; +import static com.qwazr.jdbc.cache.DbTestUtil.ROWS; +import static com.qwazr.jdbc.cache.DbTestUtil.checkNotSupported; +import static com.qwazr.jdbc.cache.DbTestUtil.checkResultSet; +import static com.qwazr.jdbc.cache.DbTestUtil.executeQuery; +import static com.qwazr.jdbc.cache.DbTestUtil.getCallableStatement; +import static com.qwazr.jdbc.cache.DbTestUtil.getPreparedStatement; +import static com.qwazr.jdbc.cache.DbTestUtil.updateGetResultSet; + +abstract public class JdbcWithDerbyBackendTest extends JdbcTest { + + private static boolean dbCreated; + + abstract String getDerbyDbName(); + abstract Class extends ResultSet> expectedResultSetClass(); + abstract boolean isCacheEnabled(); + + @BeforeClass + public static void init() throws ClassNotFoundException, IOException { + dbCreated = false; + } + + /** + * We make sure before starting a test that we have all the connections available + * and that the database has been initialized + * @throws SQLException in case we can't execute things on the database + */ + @Before + public void createConnectionsAndSampleDb() throws SQLException { + if (!dbCreated) { + // Init the backend database so we can run our tests on it + dbCreated = DbTestUtil.initTestDb(getDerbyDbName()); + } + } + + @Test + public void test110TestSimpleStatement() throws SQLException, IOException { + // First the cache might be written + checkResultSet(checkCache(executeQuery(getConnection())), ROWS); + // Second the cache might be read + checkResultSet(checkCache(executeQuery(getConnection())), ROWS); + // Try without any backend: the cache should be read if enabled + if (isCacheEnabled()) { + checkResultSet(checkCache(executeQuery(getNoBackendConnection())), ROWS); + } + } + + @Test + public void test110TestUpdateAndGetResultSet() throws SQLException, IOException { + checkResultSet(checkCache(updateGetResultSet(getConnection())), ROWS); + // Try without any backend: the cache should be read if enabled + if (isCacheEnabled()) { + checkResultSet(checkCache(updateGetResultSet(getConnection())), ROWS); + } + } + + @Test + public void test120TestPreparedStatement() throws SQLException, IOException { + final PreparedStatement stmt = getPreparedStatement(getConnection(), ROW1, ROW4); + // First the cache is written + checkResultSet(checkCache(stmt.executeQuery()), ROW1, ROW4); + // Second the cache is read + checkResultSet(checkCache(stmt.executeQuery()), ROW1, ROW4); + // Try without any backend: the cache should be read if enabled + if (isCacheEnabled()) { + checkResultSet(checkCache(stmt.executeQuery()), ROW1, ROW4); + } + } + + @Test + public void test120TestCallableStatement() throws SQLException, IOException { + final CallableStatement stmt = getCallableStatement(getConnection()); + // First the cache is written + checkResultSet(checkCache(stmt.executeQuery()), ROW2); + // Second the cache is read + checkResultSet(checkCache(stmt.executeQuery()), ROW2); + // Try without any backend: the cache should be read if enabled + if (isCacheEnabled()) { + checkResultSet(checkCache(stmt.executeQuery()), ROW2); + } + } + + @Test + public void test135TestCallableStatementGetResultSet() throws SQLException, IOException { + final CallableStatement stmt = getCallableStatement(getConnection()); + stmt.execute(); + checkResultSet(checkCache(stmt.getResultSet()), ROW2); + // Try without any backend: the cache should be read if enabled + if (isCacheEnabled()) { + checkResultSet(checkCache(stmt.getResultSet()), ROW2); + } + } + + @Test + public void test500ThreadSafeTest() throws InterruptedException { + final ExecutorService executor = Executors.newFixedThreadPool(8); + final long exitTime = System.currentTimeMillis() + 10 * 1000; + final AtomicInteger count = new AtomicInteger(); + try { + for (int i = 0; i < 8; i++) { + executor.submit(() -> { + while (System.currentTimeMillis() < exitTime) + try { + test120TestPreparedStatement(); + count.incrementAndGet(); + } catch (SQLException | IOException e) { + throw new RuntimeException(e); + } + }); + executor.submit(() -> { + while (System.currentTimeMillis() < exitTime) + try { + test120TestCallableStatement(); + count.incrementAndGet(); + } catch (SQLException | IOException e) { + throw new RuntimeException(e); + } + }); + } + executor.shutdown(); + executor.awaitTermination(1, TimeUnit.HOURS); + LOGGER.info("Iteration count: " + count.get()); + } finally { + if (!executor.isShutdown()) + executor.shutdownNow(); + } + } + + @Test + public void test600TestResultSetMetaData() throws SQLException { + final ResultSetMetaData metaData = getPreparedStatement(getConnection(), ROW1, ROW4).executeQuery() + .getMetaData(); + Assert.assertNotNull(metaData); + int colCount = metaData.getColumnCount(); + Assert.assertTrue(colCount > 0); + for (int i = 1; i <= colCount; i++) { + Assert.assertNotNull(metaData.getColumnName(i)); + Assert.assertNotNull(metaData.getColumnLabel(i)); + Assert.assertNotNull(metaData.getColumnTypeName(i)); + Assert.assertNotNull(metaData.getCatalogName(i)); + Assert.assertNotNull(metaData.getColumnClassName(i)); + Assert.assertTrue(metaData.getColumnDisplaySize(i) > 0); + Assert.assertFalse(metaData.isReadOnly(i)); + Assert.assertNotNull(metaData.getSchemaName(i)); + Assert.assertNotNull(metaData.getTableName(i)); + Assert.assertTrue(metaData.getPrecision(i) > 0); + Assert.assertTrue(metaData.isSearchable(i)); + if (i == 1) { + Assert.assertTrue(metaData.isSigned(i)); + Assert.assertEquals(0, metaData.getScale(i)); + Assert.assertEquals(ResultSetMetaData.columnNoNulls, metaData.isNullable(i)); + Assert.assertFalse(metaData.isCaseSensitive(i)); + Assert.assertFalse(metaData.isAutoIncrement(i)); + Assert.assertFalse(metaData.isCurrency(i)); + Assert.assertFalse(metaData.isWritable(i)); + } else { + Assert.assertEquals(ResultSetMetaData.columnNullable, metaData.isNullable(i)); + } + } + } + + @Test + public void test800ResultSetNotSupportedMethod() throws SQLException { + ResultSet resultSet = getPreparedStatement(getConnection(), ROW1, ROW4).executeQuery(); + checkNotSupported(() -> resultSet.updateArray(1, null)); + checkNotSupported(() -> resultSet.updateArray("id", null)); + checkNotSupported(() -> resultSet.updateAsciiStream(1, null)); + checkNotSupported(() -> resultSet.updateAsciiStream("id", null)); + checkNotSupported(() -> resultSet.updateBigDecimal(1, null)); + checkNotSupported(() -> resultSet.updateBigDecimal("id", null)); + checkNotSupported(() -> resultSet.updateByte(1, (byte) 0)); + checkNotSupported(() -> resultSet.updateByte("id", (byte) 0)); + checkNotSupported(() -> resultSet.updateBytes(1, null)); + checkNotSupported(() -> resultSet.updateBytes("id", null)); + checkNotSupported(() -> resultSet.updateBoolean(1, false)); + checkNotSupported(() -> resultSet.updateBoolean("id", false)); + checkNotSupported(() -> resultSet.updateDate(1, null)); + checkNotSupported(() -> resultSet.updateDate("id", null)); + checkNotSupported(() -> resultSet.updateDouble(1, 0d)); + checkNotSupported(() -> resultSet.updateDouble("id", 0d)); + checkNotSupported(() -> resultSet.updateFloat(1, 0f)); + checkNotSupported(() -> resultSet.updateFloat("id", 0f)); + checkNotSupported(() -> resultSet.updateInt(1, 0)); + checkNotSupported(() -> resultSet.updateInt("id", 0)); + checkNotSupported(() -> resultSet.updateLong(1, 0)); + checkNotSupported(() -> resultSet.updateLong("id", 0)); + checkNotSupported(() -> resultSet.updateRowId(1, null)); + checkNotSupported(() -> resultSet.updateRowId("id", null)); + checkNotSupported(() -> resultSet.updateNull(1)); + checkNotSupported(() -> resultSet.updateNull("id")); + checkNotSupported(() -> resultSet.updateObject(1, null)); + checkNotSupported(() -> resultSet.updateObject("id", null)); + } + + @Test + public void test900TestCacheAPI() throws SQLException, IOException { + ResultSetCache cache = com.qwazr.jdbc.cache.Driver.getCache(getConnection()); + + // We can only test the cache API in the context of a cacheable connection + Assume.assumeNotNull(cache); + + // Empty the cache if anything has been ran before + cache.flush(); + Assert.assertEquals(0, cache.size()); + Assert.assertEquals(0, cache.active()); + + executeQuery(getConnection()); + getPreparedStatement(getConnection(), ROW1, ROW4).executeQuery(); + getCallableStatement(getConnection()).executeQuery(); + + Assert.assertEquals(3, cache.size()); + Assert.assertEquals(0, cache.active()); + + Statement stmt = getPreparedStatement(getConnection(), ROW1, ROW4); + Assert.assertTrue(cache.exists(stmt)); + + Assert.assertFalse(cache.active(stmt)); + + cache.flush(stmt); + Assert.assertEquals(2, cache.size()); + + cache.flush(); + Assert.assertEquals(0, cache.size()); + } + + private ResultSet checkCache(ResultSet resultSet) { + Assert.assertEquals(expectedResultSetClass().getName(), resultSet.getClass().getName()); + return resultSet; + } +} diff --git a/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheDerbyTest.java b/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheDerbyTest.java deleted file mode 100644 index c74b91f..0000000 --- a/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheDerbyTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2016 Emmanuel Keller / QWAZR - *
- * Licensed 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 com.qwazr.jdbc.cache; - -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.sql.ResultSet; - -import static org.junit.Assert.fail; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OnDiskCacheDerbyTest extends DerbyTest { - private static String jdbcCacheUrl = null; - - @Override - Class extends ResultSet> expectedResultSetClass() { - return CachedOnDiskResultSet.class; - } - - @Override - String getOrSetJdbcCacheUrl() { - if (jdbcCacheUrl == null) { - String tempDirPath; - try { - tempDirPath = Files.createTempDirectory("jdbc-cache-test").toUri().getPath(); - if (tempDirPath.contains(":") && tempDirPath.startsWith("/")) - tempDirPath = tempDirPath.substring(1); - jdbcCacheUrl = "jdbc:cache:file:" + tempDirPath + File.separatorChar + "cache"; - } catch (IOException e) { - fail("Can not create the cache dir: " + e.getMessage()); - return null; - } - } - return jdbcCacheUrl; - } - - @Override - String getDerbyDbName() { - return "myDB1"; - } -} diff --git a/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheDisabledJdbcWithDerbyBackendTest.java b/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheDisabledJdbcWithDerbyBackendTest.java new file mode 100644 index 0000000..8048b79 --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheDisabledJdbcWithDerbyBackendTest.java @@ -0,0 +1,50 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import org.apache.derby.impl.jdbc.EmbedResultSet42; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +public class OnDiskCacheDisabledJdbcWithDerbyBackendTest extends OnDiskCacheJdbcWithDerbyBackendTest { + @Override + Class extends ResultSet> expectedResultSetClass() { + return EmbedResultSet42.class; + } + + @Override + boolean isCacheEnabled() { + return false; + } + + @Override + String getDerbyDbName() { + return "onDiskCacheDisabled"; + } + + @Override + Connection getConnection() throws SQLException { + final Properties info = new Properties(); + info.setProperty("cache.driver.url", "jdbc:derby:memory:" + getDerbyDbName() + ";create=true"); + info.setProperty("cache.driver.class", "org.apache.derby.jdbc.EmbeddedDriver"); + info.setProperty("cache.driver.active", "false"); + return DriverManager.getConnection(getOrSetJdbcCacheUrl(), info); + } +} diff --git a/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheEnabledJdbcWithDerbyBackendTest.java b/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheEnabledJdbcWithDerbyBackendTest.java new file mode 100644 index 0000000..8c7d8bb --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheEnabledJdbcWithDerbyBackendTest.java @@ -0,0 +1,46 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +public class OnDiskCacheEnabledJdbcWithDerbyBackendTest extends OnDiskCacheJdbcWithDerbyBackendTest { + @Override + Class extends ResultSet> expectedResultSetClass() { + return CachedOnDiskResultSet.class; + } + + @Override + boolean isCacheEnabled() { + return true; + } + + @Override + String getDerbyDbName() { + return "onDiskCacheEnabled"; + } + + @Override + Connection getConnection() throws SQLException { + final Properties info = new Properties(); + info.setProperty("cache.driver.url", "jdbc:derby:memory:" + getDerbyDbName() + ";create=true"); + return DriverManager.getConnection(getOrSetJdbcCacheUrl(), info); + } +} diff --git a/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheJdbcWithDerbyBackendTest.java b/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheJdbcWithDerbyBackendTest.java new file mode 100644 index 0000000..4f07aa8 --- /dev/null +++ b/src/test/java/com/qwazr/jdbc/cache/OnDiskCacheJdbcWithDerbyBackendTest.java @@ -0,0 +1,39 @@ +/** + * Copyright 2016 Emmanuel Keller / QWAZR + *
+ * Licensed 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 com.qwazr.jdbc.cache; + +import org.junit.BeforeClass; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +public abstract class OnDiskCacheJdbcWithDerbyBackendTest extends JdbcWithDerbyBackendTest { + private static String tempDirPath; + + @BeforeClass + public static void createTmpDir() throws IOException { + tempDirPath = Files.createTempDirectory("jdbc-cache-test").toUri().getPath(); + if (tempDirPath.contains(":") && tempDirPath.startsWith("/")) { + tempDirPath = tempDirPath.substring(1); + } + } + + @Override + String getOrSetJdbcCacheUrl() { + return "jdbc:cache:file:" + tempDirPath + File.separatorChar + "cache"; + } +}