package org.simpleflatmapper.jdbc.test; import org.junit.Test; import org.simpleflatmapper.jdbc.ConnectedCrud; import org.simpleflatmapper.jdbc.Crud; import org.simpleflatmapper.jdbc.JdbcMapperFactory; import org.simpleflatmapper.jdbc.impl.DataSourceTransactionTemplate; import org.simpleflatmapper.test.beans.DbObject; import org.simpleflatmapper.test.jdbc.DbHelper; import org.simpleflatmapper.util.CheckedConsumer; import org.simpleflatmapper.util.ListCollector; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; import java.util.*; import static org.junit.Assert.*; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class ConnectedCrudTest { @Test public void testDbObjectCrud() throws Exception { DataSource dataSource = DbHelper.getHsqlDataSource(); ConnectedCrud<DbObject, Long> objectCrud = JdbcMapperFactory.newInstance().<DbObject, Long>crud(DbObject.class, Long.class).table(dataSource, "TEST_DB_OBJECT"); checkCrudDbObject(objectCrud, DbObject.newInstance()); Connection connection = dataSource.getConnection(); try { CrudTest.checkCrudDbObject(connection, objectCrud.crud(), DbObject.newInstance()); } finally { connection.close(); } } @Test public void testDelegateSuccess() throws SQLException { Crud<Object, Object> crud = mock(Crud.class); DataSource dataSource = mock(DataSource.class); Connection connection = mock(Connection.class); when(dataSource.getConnection()).thenReturn(connection); ConnectedCrud<Object, Object> connectedCrud = new ConnectedCrud<Object, Object>(new DataSourceTransactionTemplate(dataSource), crud); Collection<Object> values = new ArrayList<Object>(); Object value = new Object(); CheckedConsumer consumer = new CheckedConsumer() { @Override public void accept(Object o) throws Exception { } }; connectedCrud.create(values); verify(crud).create(connection, values); verifyCloseCommitAndReset(crud, connection); connectedCrud.create(value); verify(crud).create(connection, value); verifyCloseCommitAndReset(crud, connection); connectedCrud.create(values, consumer); verify(crud).create(connection, values, consumer); verifyCloseCommitAndReset(crud, connection); connectedCrud.create(value, consumer); verify(crud).create(connection, value, consumer); verifyCloseCommitAndReset(crud, connection); // read connectedCrud.read(value); verify(crud).read(connection, value); verifyCloseCommitAndReset(crud, connection); connectedCrud.read(values, consumer); verify(crud).read(connection, values, consumer); verifyCloseCommitAndReset(crud, connection); // update connectedCrud.update(value); verify(crud).update(connection, value); verifyCloseCommitAndReset(crud, connection); connectedCrud.update(values); verify(crud).update(connection, values); verifyCloseCommitAndReset(crud, connection); // delete connectedCrud.delete(value); verify(crud).delete(connection, value); verifyCloseCommitAndReset(crud, connection); connectedCrud.delete(values); verify(crud).delete(connection, values); verifyCloseCommitAndReset(crud, connection); // create or update connectedCrud.createOrUpdate(value); verify(crud).createOrUpdate(connection, value); verifyCloseCommitAndReset(crud, connection); connectedCrud.createOrUpdate(values); verify(crud).createOrUpdate(connection, values); verifyCloseCommitAndReset(crud, connection); connectedCrud.createOrUpdate(value, consumer); verify(crud).createOrUpdate(connection, value, consumer); verifyCloseCommitAndReset(crud, connection); connectedCrud.createOrUpdate(values, consumer); verify(crud).createOrUpdate(connection, values, consumer); verifyCloseCommitAndReset(crud, connection); } @Test public void testDelegateFail() throws SQLException { Crud<Object, Object> crud = mock(Crud.class); DataSource dataSource = mock(DataSource.class); Connection connection = mock(Connection.class); when(dataSource.getConnection()).thenReturn(connection); ConnectedCrud<Object, Object> connectedCrud = new ConnectedCrud<Object, Object>(new DataSourceTransactionTemplate(dataSource), crud); Collection<Object> values = new ArrayList<Object>(); Object value = new Object(); CheckedConsumer consumer = new CheckedConsumer() { @Override public void accept(Object o) throws Exception { } }; RuntimeException exception = new RuntimeException(); doThrow(exception).when(connection).commit(); try { connectedCrud.create(values); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).create(connection, values); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.create(value); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).create(connection, value); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.create(values, consumer); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).create(connection, values, consumer); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.create(value, consumer); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).create(connection, value, consumer); verifyCloseCommitFailAndReset(exception, crud, connection); } // read try { connectedCrud.read(value); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).read(connection, value); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.read(values, consumer); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).read(connection, values, consumer); verifyCloseCommitFailAndReset(exception, crud, connection); } // update try { connectedCrud.update(value); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).update(connection, value); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.update(values); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).update(connection, values); verifyCloseCommitFailAndReset(exception, crud, connection); } // delete try { connectedCrud.delete(value); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).delete(connection, value); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.delete(values); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).delete(connection, values); verifyCloseCommitFailAndReset(exception, crud, connection); } // create or update try { connectedCrud.createOrUpdate(value); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).createOrUpdate(connection, value); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.createOrUpdate(values); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).createOrUpdate(connection, values); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.createOrUpdate(value, consumer); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).createOrUpdate(connection, value, consumer); verifyCloseCommitFailAndReset(exception, crud, connection); } try { connectedCrud.createOrUpdate(values, consumer); fail(); } catch (RuntimeException e) { assertSame(exception, e); verify(crud).createOrUpdate(connection, values, consumer); verifyCloseCommitFailAndReset(exception, crud, connection); } } private void verifyCloseCommitAndReset(Crud<Object, Object> crud, Connection connection) throws SQLException { verify(connection).commit(); verify(connection).close(); reset(crud, connection); } private void verifyCloseCommitFailAndReset(Exception exception, Crud<Object, Object> crud, Connection connection) throws SQLException { verify(connection).commit(); verify(connection).rollback(); verify(connection).close(); reset(crud, connection); doThrow(exception).when(connection).commit(); } @Test public void testDbObjectCrudTable() throws Exception { DataSource dataSource = DbHelper.getHsqlDataSource(); ConnectedCrud<CrudTest.DbObjectTable, Long> objectCrud = JdbcMapperFactory.newInstance().<CrudTest.DbObjectTable, Long>crud(CrudTest.DbObjectTable.class, Long.class).to(dataSource); checkCrudDbObject(objectCrud, DbObject.newInstance(new CrudTest.DbObjectTable())); Connection connection = dataSource.getConnection(); try { CrudTest.checkCrudDbObject(connection, objectCrud.crud(), DbObject.newInstance(new CrudTest.DbObjectTable())); } finally { connection.close(); } } private <T extends DbObject> void checkCrudDbObject(ConnectedCrud<T, Long> objectCrud, T object) throws SQLException { assertNull(objectCrud.read(object.getId())); // create Long key = objectCrud.create(object, new CheckedConsumer<Long>() { Long key; @Override public void accept(Long aLong) throws Exception { key = aLong; } }).key; assertNull(key); key = object.getId(); // read assertEquals(object, objectCrud.read(key)); object.setName("Udpdated"); // update objectCrud.update(object); assertEquals(object, objectCrud.read(key)); // delete objectCrud.delete(key); assertNull(objectCrud.read(key)); objectCrud.create(object); assertEquals(object, objectCrud.where("id = :id", Long.class).readFirst(object.getId())); assertEquals(Arrays.asList(object), objectCrud.where("name = :name and id = :id", DbObject.class).read(object, new ListCollector<T>()).getList()); } }