diff --git a/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java b/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java index 6045a4f4..0e40e239 100644 --- a/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java +++ b/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java @@ -99,7 +99,7 @@ public void setGeneratedKey(Object key) { } } - public boolean isTestRollback() { + boolean isTestRollback() { return testRollback; } @@ -310,9 +310,9 @@ private void flushIO() throws SQLException { } throw new UcanaccessSQLException(_t); } + try { ref.getDbIO().flush(); - } catch (IOException _ex) { throw new UcanaccessSQLException(_ex); } diff --git a/src/test/java/net/ucanaccess/test/integration/ComplexTest.java b/src/test/java/net/ucanaccess/test/integration/ComplexTest.java index 920f1a50..53f75323 100644 --- a/src/test/java/net/ucanaccess/test/integration/ComplexTest.java +++ b/src/test/java/net/ucanaccess/test/integration/ComplexTest.java @@ -1,8 +1,11 @@ package net.ucanaccess.test.integration; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + import net.ucanaccess.complex.Attachment; import net.ucanaccess.complex.SingleValue; import net.ucanaccess.jdbc.UcanaccessConnection; +import net.ucanaccess.jdbc.UcanaccessSQLException; import net.ucanaccess.test.util.AccessVersion; import net.ucanaccess.test.util.UcanaccessBaseTest; import org.junit.jupiter.api.Disabled; @@ -10,7 +13,6 @@ import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.EnumSource.Mode; -import java.io.IOException; import java.lang.reflect.Method; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -108,58 +110,54 @@ private void complex1() throws Exception { ps.setObject(1, svs); ps.execute(); checkQuery("SELECT * FROM TABLE1 ORDER BY id"); - assertEquals(7, getCount("SELECT COUNT(*) FROM TABLE1", true)); + assertEquals(7, getCount("SELECT COUNT(*) FROM TABLE1")); ps.close(); } @ParameterizedTest(name = "[{index}] {0}") @EnumSource(value = AccessVersion.class, mode=Mode.INCLUDE, names = {"V2010"}) - void testComplexRollback(AccessVersion _accessVersion) throws SQLException, IOException, SecurityException, IllegalArgumentException { + void testComplexRollback(AccessVersion _accessVersion) throws Exception { init(_accessVersion); - PreparedStatement ps = null; - int i = getCount("SELECT COUNT(*) FROM TABLE1", true); - try { + // ucanaccess = Mockito.spy(ucanaccess); + // Mockito.when(ucanaccess.afterFlushIoHook()).thenReturn(...); - ucanaccess.setAutoCommit(false); + int countBefore = getCount("SELECT COUNT(*) FROM TABLE1"); - Method mth = UcanaccessConnection.class.getDeclaredMethod("setTestRollback", boolean.class); - mth.setAccessible(true); - mth.invoke(ucanaccess, Boolean.TRUE); - ps = ucanaccess.prepareStatement( - "INSERT INTO TABLE1(ID , [MEMO-DATA] , [APPEND-MEMO-DATA] , [MULTI-VALUE-DATA] , [ATTACH-DATA]) " - + "VALUES (?,?,?,?,?)"); + ucanaccess.setAutoCommit(false); + + Method mth = UcanaccessConnection.class.getDeclaredMethod("setTestRollback", boolean.class); + mth.setAccessible(true); + mth.invoke(ucanaccess, Boolean.TRUE); + + try (PreparedStatement ps = ucanaccess.prepareStatement( + "INSERT INTO TABLE1(ID, [MEMO-DATA], [APPEND-MEMO-DATA], [MULTI-VALUE-DATA], [ATTACH-DATA]) VALUES (?,?,?,?,?)")) { ps.setString(1, "row123"); ps.setString(2, "ciao"); ps.setString(3, "to version"); SingleValue[] svs = new SingleValue[] {new SingleValue("16"), new SingleValue("24")}; ps.setObject(4, svs); - Attachment[] atcs = - new Attachment[] {new Attachment(null, "ccc.txt", "txt", "ddddd ddd".getBytes(), LocalDateTime.now(), null), new Attachment(null, "ccczz.txt", "txt", "ddddd zzddd".getBytes(), - LocalDateTime.now(), null)}; + Attachment[] atcs = new Attachment[] { + new Attachment(null, "ccc.txt", "txt", "ddddd ddd".getBytes(), LocalDateTime.now(), null), + new Attachment(null, "ccczz.txt", "txt", "ddddd zzddd".getBytes(), LocalDateTime.now(), null)}; ps.setObject(5, atcs); ps.execute(); - ps.close(); - ps = ucanaccess - .prepareStatement("UPDATE TABLE1 SET [APPEND-MEMO-DATA]='THE BIG BIG CAT' WHERE ID='row12' "); + } + + try (PreparedStatement ps = ucanaccess.prepareStatement("UPDATE TABLE1 SET [APPEND-MEMO-DATA]='THE BIG BIG CAT' WHERE ID='row12'")) { ps.execute(); - ps.close(); - dumpQueryResult("SELECT * FROM TABLE1"); - ucanaccess.commit(); - checkQuery("SELECT * FROM TABLE1 ORDER BY id"); - - } catch (Throwable _ex) { - getLogger().warn("Encountered exception: {}: ", _ex.getMessage(), _ex); - } finally { - if (ps != null) { - ps.close(); - } } + dumpQueryResult("SELECT * FROM TABLE1"); + + assertThatThrownBy(() -> ucanaccess.commit()) + .isInstanceOf(UcanaccessSQLException.class) + .hasMessageEndingWith("PhysicalRollbackTest"); ucanaccess = getUcanaccessConnection(); + checkQuery("SELECT * FROM TABLE1 ORDER BY id"); dumpQueryResult("SELECT * FROM TABLE1"); checkQuery("SELECT * FROM TABLE1 WHERE ID='row12' ORDER BY id"); - assertEquals(i, getCount("SELECT COUNT(*) FROM TABLE1", true)); + assertEquals(countBefore, getCount("SELECT COUNT(*) FROM TABLE1")); } } diff --git a/src/test/java/net/ucanaccess/test/integration/CreateTableTest.java b/src/test/java/net/ucanaccess/test/integration/CreateTableTest.java index 6adb2960..c8ab397f 100644 --- a/src/test/java/net/ucanaccess/test/integration/CreateTableTest.java +++ b/src/test/java/net/ucanaccess/test/integration/CreateTableTest.java @@ -87,38 +87,30 @@ void defaults() throws Exception { } void setDPK() throws SQLException, IOException { - Statement st = null; - try { - st = ucanaccess.createStatement(); - st.execute("create table dkey(c counter , " + "number numeric(23,5) , " + " PRIMARY KEY (C,NUMBER))"); - st.execute("create table dunique(c text , " + "number numeric(23,5) , " + " unique (C,NUMBER))"); - st.close(); - ucanaccess.setAutoCommit(false); - try { - st = ucanaccess.createStatement(); - st.execute("INSERT INTO dunique values('ddl forces commit',2.3)"); - st.close(); - st = ucanaccess.createStatement(); - st.execute("create table dtrx(c text , " + "number numeric(23,5) , " + " unique (C,NUMBER))"); - st.execute("INSERT INTO dtrx values('I''ll be forgotten sob sob ',55555.3)"); - st.close(); - st = ucanaccess.createStatement(); - st.execute("alter table dtrx ADD CONSTRAINT pk_dtrx PRIMARY KEY (c,number)"); - st.close(); - } catch (Exception _ex) { - ucanaccess.rollback(); - } - st = ucanaccess.createStatement(); - st.execute("INSERT INTO dtrx values('Hi all',444.3)"); - st.execute("INSERT INTO dtrx values('Hi all',4454.3)"); - dumpQueryResult("SELECT * FROM dtrx"); - dumpQueryResult("SELECT * FROM dunique"); - ucanaccess.commit(); - checkQuery("SELECT * FROM dunique"); - checkQuery("SELECT * FROM dtrx"); - } finally { - st.close(); + Statement st1 = ucanaccess.createStatement(); + st1.execute("create table dkey(c counter , " + "number numeric(23,5) , " + " PRIMARY KEY (C,NUMBER))"); + st1.execute("create table dunique(c text , " + "number numeric(23,5) , " + " unique (C,NUMBER))"); + st1.close(); + ucanaccess.setAutoCommit(false); + try (Statement st2 = ucanaccess.createStatement()) { + st2.execute("INSERT INTO dunique values('ddl forces commit',2.3)"); + st2.execute("create table dtrx(c text , " + "number numeric(23,5) , " + " unique (C,NUMBER))"); + st2.execute("INSERT INTO dtrx values('I''ll be forgotten sob sob ',55555.3)"); + st2.execute("alter table dtrx ADD CONSTRAINT pk_dtrx PRIMARY KEY (c,number)"); + } catch (Exception _ex) { + ucanaccess.rollback(); + } + + try (Statement st3 = ucanaccess.createStatement()) { + st3.execute("INSERT INTO dtrx values('Hi all',444.3)"); + st3.execute("INSERT INTO dtrx values('Hi all',4454.3)"); } + + dumpQueryResult("SELECT * FROM dtrx"); + dumpQueryResult("SELECT * FROM dunique"); + ucanaccess.commit(); + checkQuery("SELECT * FROM dunique"); + checkQuery("SELECT * FROM dtrx"); } void setTableProperties() throws SQLException { diff --git a/src/test/java/net/ucanaccess/test/integration/MetaDataParameterizedTest.java b/src/test/java/net/ucanaccess/test/integration/MetaDataParameterizedTest.java index 76d572ff..066ede47 100644 --- a/src/test/java/net/ucanaccess/test/integration/MetaDataParameterizedTest.java +++ b/src/test/java/net/ucanaccess/test/integration/MetaDataParameterizedTest.java @@ -1,6 +1,9 @@ package net.ucanaccess.test.integration; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import net.ucanaccess.jdbc.UcanaccessSQLException; import net.ucanaccess.test.util.AccessVersion; import net.ucanaccess.test.util.UcanaccessBaseTest; import org.junit.jupiter.params.ParameterizedTest; @@ -28,8 +31,7 @@ void testCreateBadMetadata(AccessVersion _accessVersion) throws Exception { dumpQueryResult("SELECT * FROM [健康]"); st.execute("CREATE TABLE [123456 nn%&/健康] ([q3¹²³¼½¾ß€ Ð×ÝÞðýþäüöß] aUtoIncrement PRIMARY KEY, [Sometime I wonder who I am ] text, " + "[Πλήθος Αντιγράφων] CURRENCY,[ជំរាបសួរ] CURRENCY,[ЗДОРОВЫЙ] CURRENCY,[健康] CURRENCY,[健康な] CURRENCY,[किआओ ] CURRENCY default 12.88, [11q3 ¹²³¼½¾ß€] text(2), unique ([किआओ ] ,[健康な]) )"); - st.execute( - "INSERT INTO [123456 nn%&/健康] ([Sometime I wonder who I am ],[Πλήθος Αντιγράφων],[健康],[健康な],[किआओ ] ) VALUES('I''m a wonderful forty',10.56,10.33,13,14)"); + st.execute("INSERT INTO [123456 nn%&/健康] ([Sometime I wonder who I am ],[Πλήθος Αντιγράφων],[健康],[健康な],[किआओ ] ) VALUES('I''m a wonderful forty',10.56,10.33,13,14)"); PreparedStatement ps = ucanaccess.prepareStatement("SELECT * FROM [123456 nn%&/健康]", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE, ResultSet.CLOSE_CURSORS_AT_COMMIT); ResultSet rs = ps.executeQuery(); @@ -38,22 +40,20 @@ void testCreateBadMetadata(AccessVersion _accessVersion) throws Exception { rs.updateString("Sometime I wonder who I am ", "Growing old without emotions"); rs.updateString("11q3 ¹²³¼½¾ß€", "康"); rs.insertRow(); - getLogger().info("crazy names in create table with updatable resultset..."); + getLogger().debug("Crazy names in create table with updatable resultset..."); dumpQueryResult("SELECT * FROM [123456 nn%&/健康]"); - try { - st.execute( - "INSERT INTO [123456 nn%&/健康] ([Sometime I wonder who I am ],[Πλήθος Αντιγράφων],[健康],[किआओ ] ,健康な) VALUES('I''m a wonderful forty',11,11,14,13)"); - } catch (Exception _ex) { - getLogger().info("ok, unique constraint gotten"); - } - st.execute( - "INSERT INTO [123456 nn%&/健康] ([Sometime I wonder who I am ],[Πλήθος Αντιγράφων],[健康],[किआओ ] ,[健康な]) VALUES('I''m a wonderful forty',11,11,14.01,13)"); - try { - st.execute("update [123456 nn%&/健康] set [健康な]=13, [किआओ ]=14"); - } catch (Exception _ex) { - getLogger().info("ok, unique constraint gotten"); - } + assertThatThrownBy(() -> st.execute( + "INSERT INTO [123456 nn%&/健康] ([Sometime I wonder who I am ],[Πλήθος Αντιγράφων],[健康],[किआओ ] ,健康な) VALUES('I''m a wonderful forty',11,11,14,13)")) + .isInstanceOf(UcanaccessSQLException.class) + .hasMessageContaining("integrity constraint violation: unique constraint or index violation"); + st.execute("INSERT INTO [123456 nn%&/健康] ([Sometime I wonder who I am ],[Πλήθος Αντιγράφων],[健康],[किआओ ] ,[健康な]) " + + "VALUES('I''m a wonderful forty',11,11,14.01,13)"); + + assertThatThrownBy(() -> st.execute( + "update [123456 nn%&/健康] set [健康な]=13, [किआओ ]=14")) + .isInstanceOf(UcanaccessSQLException.class) + .hasMessageContaining("integrity constraint violation: unique constraint or index violation"); dumpQueryResult("SELECT * FROM [123456 nn%&/健康]"); diff --git a/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java b/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java index aeb2c699..595fb105 100644 --- a/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java +++ b/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java @@ -8,6 +8,9 @@ import java.io.IOException; import java.sql.*; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; class MultiThreadAccessTest extends UcanaccessBaseTest { private static int intVal; @@ -71,20 +74,17 @@ void crudUpdatableRS() throws SQLException { @MethodSource("net.ucanaccess.test.util.AccessVersion#getDefaultAccessVersion()") void testMultiThread(AccessVersion _accessVersion) throws SQLException, IOException { init(_accessVersion); - int nt = 50; - Thread[] threads = new Thread[nt]; - for (int i = 0; i < nt; i++) { - threads[i] = new Thread(() -> { - try { - crud(); - crudPS(); - crudUpdatableRS(); - } catch (SQLException _ex) { - fail(_ex); - } + + List threads = IntStream.range(0, 50).mapToObj(i -> new Thread(() -> { + assertDoesNotThrow(() -> { + crud(); + crudPS(); + crudUpdatableRS(); }); - threads[i].start(); - } + })).collect(Collectors.toList()); + + threads.forEach(Thread::start); + for (Thread t : threads) { try { t.join(); diff --git a/src/test/java/net/ucanaccess/test/integration/PasswordTest.java b/src/test/java/net/ucanaccess/test/integration/PasswordTest.java index 48d63185..4ce9b30d 100644 --- a/src/test/java/net/ucanaccess/test/integration/PasswordTest.java +++ b/src/test/java/net/ucanaccess/test/integration/PasswordTest.java @@ -1,7 +1,8 @@ package net.ucanaccess.test.integration; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import net.ucanaccess.jdbc.UcanaccessSQLException; import net.ucanaccess.test.util.AccessVersion; import net.ucanaccess.test.util.UcanaccessBaseTest; import org.junit.jupiter.params.ParameterizedTest; @@ -16,18 +17,17 @@ class PasswordTest extends UcanaccessBaseTest { @EnumSource(value = AccessVersion.class) void testPassword(AccessVersion _accessVersion) throws Exception { init(_accessVersion); + File dbFile = copyResourceToTempFile(TEST_DB_DIR + "pwd.mdb"); - Connection ucanaccessConnection = null; - try { - ucanaccessConnection = getUcanaccessConnection(dbFile.getAbsolutePath()); - } catch (Exception _ex) { - assertThat(_ex.getMessage()).contains("Password authentication failed"); - } - assertNull(ucanaccessConnection); + + setPassword(""); + assertThatThrownBy(() -> getUcanaccessConnection(dbFile.getAbsolutePath())) + .isInstanceOf(UcanaccessSQLException.class) + .hasMessageContaining("Password authentication failed"); setPassword("ucanaccess"); - ucanaccessConnection = getUcanaccessConnection(); - ucanaccessConnection.close(); - assertNotNull(ucanaccessConnection); + try (Connection ucanaccessConnection = getUcanaccessConnection()) { + assertNotNull(ucanaccessConnection); + } } } diff --git a/src/test/java/net/ucanaccess/test/integration/PhysicalRollbackTest.java b/src/test/java/net/ucanaccess/test/integration/PhysicalRollbackTest.java index ae6b7f0b..5d14776f 100644 --- a/src/test/java/net/ucanaccess/test/integration/PhysicalRollbackTest.java +++ b/src/test/java/net/ucanaccess/test/integration/PhysicalRollbackTest.java @@ -1,6 +1,6 @@ package net.ucanaccess.test.integration; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import net.ucanaccess.jdbc.UcanaccessConnection; import net.ucanaccess.test.util.AccessVersion; @@ -49,19 +49,15 @@ void testCommit(AccessVersion _accessVersion) throws Exception { st.execute("INSERT INTO T4 (id, descr) VALUES(4, 'nel mezzo del cammin di nostra vita')"); st.execute("DELETE FROM T4 WHERE id=4"); - Exception ex = null; - try { - ucanaccess.commit(); - } catch (Exception _ex) { - ex = _ex; - } - assertNotNull(ex); - assertThat(ex.getMessage()).contains(getClass().getSimpleName()); + + assertThatThrownBy(() -> ucanaccess.commit()) + .isInstanceOf(SQLException.class) + .hasMessageContaining(getClass().getSimpleName()); ucanaccess = getUcanaccessConnection(); dumpQueryResult("SELECT * FROM T4"); - assertEquals(0, getCount("SELECT COUNT(*) FROM T4", true)); + assertEquals(0, getCount("SELECT COUNT(*) FROM T4")); } } diff --git a/src/test/java/net/ucanaccess/test/integration/RegexTest.java b/src/test/java/net/ucanaccess/test/integration/RegexTest.java index acaea5d6..ee12d516 100644 --- a/src/test/java/net/ucanaccess/test/integration/RegexTest.java +++ b/src/test/java/net/ucanaccess/test/integration/RegexTest.java @@ -14,7 +14,7 @@ class RegexTest extends UcanaccessBaseTest { @Override protected void init(AccessVersion _accessVersion) throws SQLException { super.init(_accessVersion); - executeStatements("CREATE TABLE reg (id COUNTER,descr memo) "); + executeStatements("CREATE TABLE reg (id COUNTER, descr MEMO) "); } @AfterEach @@ -33,7 +33,8 @@ void testRegex(AccessVersion _accessVersion) throws SQLException { try (Statement st = ucanaccess.createStatement()) { for (String c : in) { - executeStatement(c); + st.execute(getStatement(c.replaceAll("'", "''"), "'")); + st.execute(getStatement(c.replaceAll("\"", "\"\""), "\"")); } String[][] out = new String[in.length * 2][1]; int k = 0; @@ -47,19 +48,6 @@ void testRegex(AccessVersion _accessVersion) throws SQLException { } } - private void executeStatement(String s) throws SQLException { - try (Statement st = ucanaccess.createStatement()) { - st.execute(getStatement(s.replaceAll("'", "''"), "'")); - - st.execute(getStatement(s.replaceAll("\"", "\"\""), "\"")); - - } catch (SQLException sqle) { - System.err.println(getStatement(s, "\"")); - System.err.println("Converted sql: " + ucanaccess.nativeSQL(getStatement(s.replaceAll("\"", "\"\""), "\""))); - throw sqle; - } - } - private String getStatement(String _s, String _dlm) { return "INSERT INTO reg (descr) VALUES( " + _dlm + _s + _dlm + ")"; } diff --git a/src/test/java/net/ucanaccess/test/integration/TransactionTest.java b/src/test/java/net/ucanaccess/test/integration/TransactionTest.java index 4f456d6d..237dad90 100644 --- a/src/test/java/net/ucanaccess/test/integration/TransactionTest.java +++ b/src/test/java/net/ucanaccess/test/integration/TransactionTest.java @@ -29,11 +29,11 @@ void testCommit(AccessVersion _accessVersion) throws SQLException { init(_accessVersion); ucanaccess.setAutoCommit(false); Statement st = ucanaccess.createStatement(); - int i = getCount("SELECT COUNT(*) FROM T4", true); + int i = getCount("SELECT COUNT(*) FROM T4"); st.execute("INSERT INTO T4 (id,descr) VALUES( 6666554,'nel mezzo del cammin di nostra vita')"); assertEquals(i, getCount("SELECT COUNT(*) FROM T4", false)); ucanaccess.commit(); - assertEquals(i + 1, getCount("SELECT COUNT(*) FROM T4", true)); + assertEquals(i + 1, getCount("SELECT COUNT(*) FROM T4")); st.close(); } diff --git a/src/test/java/net/ucanaccess/test/util/UcanaccessBaseTest.java b/src/test/java/net/ucanaccess/test/util/UcanaccessBaseTest.java index 8e3a48ed..6da175ac 100644 --- a/src/test/java/net/ucanaccess/test/util/UcanaccessBaseTest.java +++ b/src/test/java/net/ucanaccess/test/util/UcanaccessBaseTest.java @@ -361,10 +361,12 @@ public int getCount(String _sql, boolean _equals) throws SQLException { ResultSet joRs = st.executeQuery(_sql); joRs.next(); int count = joRs.getInt(1); + st = ucanaccess.createStatement(); ResultSet myRs = st.executeQuery(_sql); myRs.next(); int myCount = myRs.getInt(1); + if (_equals) { assertEquals(count, myCount); } else {