package org.simpleflatmapper.jdbc.test;
import org.junit.Test;
import org.simpleflatmapper.jdbc.JdbcColumnKey;
import org.simpleflatmapper.jdbc.JdbcMapper;
import org.simpleflatmapper.jdbc.JdbcMapperFactory;
import org.simpleflatmapper.reflect.getter.GetterFactory;
import org.simpleflatmapper.map.FieldMapper;
import org.simpleflatmapper.map.FieldMapperErrorHandler;
import org.simpleflatmapper.map.MappingContext;
import org.simpleflatmapper.map.ConsumerErrorHandler;
import org.simpleflatmapper.test.beans.DbFinalObject;
import org.simpleflatmapper.test.beans.DbObject;
import org.simpleflatmapper.test.beans.DbObjectWithAlias;
import org.simpleflatmapper.reflect.Getter;
import org.simpleflatmapper.util.TypeReference;
import org.simpleflatmapper.test.jdbc.DbHelper;
import org.simpleflatmapper.test.jdbc.TestRowHandler;
import org.simpleflatmapper.tuple.Tuple2;
import org.simpleflatmapper.tuple.Tuples;
import org.simpleflatmapper.util.ListCollector;
import org.simpleflatmapper.util.CheckedConsumer;
import java.lang.reflect.Type;
import java.sql.*;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.*;
public class JdbcMapperFactoryTest {
JdbcMapperFactory asmFactory = JdbcMapperFactoryHelper.asm();
JdbcMapperFactory nonAsmFactory = JdbcMapperFactoryHelper.noAsm();
@Test
public void testFactoryOnTuples() {
assertNotNull(asmFactory.newMapper(Tuples.typeDef(Date.class, Date.class)));
assertNotNull(asmFactory.newBuilder(Tuples.typeDef(Date.class, Date.class)));
}
@Test
public void testFactoryOnReferenceType() throws SQLException {
ResultSet rs = mock(ResultSet.class);
ResultSetMetaData metaData = mock(ResultSetMetaData.class);
when(rs.getMetaData()).thenReturn(metaData);
when(metaData.getColumnCount()).thenReturn(2);
when(metaData.getColumnLabel(1)).thenReturn("e0");
when(metaData.getColumnLabel(2)).thenReturn("e1");
when(metaData.getColumnType(1)).thenReturn(Types.VARCHAR);
when(metaData.getColumnType(2)).thenReturn(Types.VARCHAR);
when(rs.next()).thenReturn(true, false);
when(rs.getString(1)).thenReturn("v1");
when(rs.getString(2)).thenReturn("v2");
Tuple2<String, String> tuple2 = JdbcMapperFactoryHelper.asm().newMapper(new TypeReference<Tuple2<String, String>>() {
}).iterator(rs).next();
assertEquals("v1", tuple2.first());
assertEquals("v2", tuple2.second());
}
@Test
public void testFactoryOnReferenceTypeStatic() throws SQLException {
ResultSet rs = mock(ResultSet.class);
when(rs.next()).thenReturn(true, false);
when(rs.getString(1)).thenReturn("v1");
when(rs.getString(2)).thenReturn("v2");
Tuple2<String, String> tuple2 = JdbcMapperFactoryHelper.asm().newBuilder(new TypeReference<Tuple2<String, String>>() {
}).addMapping("e0").addMapping("e1").mapper()
.iterator(rs).next();
assertEquals("v1", tuple2.first());
assertEquals("v2", tuple2.second());
}
@Test
public void testAsmDbObjectMappingFromDbWithMetaData()
throws Exception {
DbHelper.testDbObjectFromDb(new TestRowHandler<PreparedStatement>() {
@Override
public void handle(PreparedStatement ps) throws Exception {
ResultSet rs = ps.executeQuery();
JdbcMapper<DbObject> mapper = asmFactory.newMapper(DbObject.class, rs.getMetaData());
assertMapPsDbObject(rs, mapper);
}
});
}
@Test
public void testAsmDbObjectWithAliasMappingFromDbWithMetaData()
throws Exception {
DbHelper.testDbObjectFromDb(new TestRowHandler<PreparedStatement>() {
@Override
public void handle(PreparedStatement ps) throws Exception {
ResultSet rs = ps.executeQuery();
JdbcMapper<DbObjectWithAlias> mapper = asmFactory.newMapper(DbObjectWithAlias.class, rs.getMetaData());
assertMapPsDbObjectWithAlias(rs, mapper);
}
});
}
@Test
public void testNonAsmDbObjectMappingFromDbWithMetaData()
throws Exception {
DbHelper.testDbObjectFromDb(new TestRowHandler<PreparedStatement>() {
@Override
public void handle(PreparedStatement ps) throws Exception {
ResultSet rs = ps.executeQuery();
JdbcMapper<DbObject> mapper = nonAsmFactory.newMapper(DbObject.class, rs.getMetaData());
assertMapPsDbObject(rs, mapper);
}
});
}
@Test
public void testAsmDbObjectMappingFromDbDynamic()
throws SQLException, Exception, ParseException {
DbHelper.testDbObjectFromDb(new TestRowHandler<PreparedStatement>() {
@Override
public void handle(PreparedStatement ps) throws Exception {
JdbcMapper<DbObject> mapper = asmFactory.newMapper(DbObject.class);
assertMapPsDbObject(ps.executeQuery(), mapper);
}
});
}
@Test
public void testNonAsmDbObjectMappingFromDbDynamic()
throws SQLException, Exception, ParseException {
DbHelper.testDbObjectFromDb(new TestRowHandler<PreparedStatement>() {
@Override
public void handle(PreparedStatement ps) throws Exception {
JdbcMapper<DbObject> mapper = nonAsmFactory.newMapper(DbObject.class);
assertMapPsDbObject(ps.executeQuery(), mapper);
}
});
}
@Test
public void testAsmFinalDbObjectMappingFromDbDynamic()
throws SQLException, Exception, ParseException {
DbHelper.testDbObjectFromDb(new TestRowHandler<PreparedStatement>() {
@Override
public void handle(PreparedStatement ps) throws Exception {
JdbcMapper<DbFinalObject> mapper = asmFactory.newMapper(DbFinalObject.class);
assertMapPsFinalDbObject(ps.executeQuery(), mapper);
}
});
}
@Test
public void testNonAsmFinalDbObjectMappingFromDbDynamic()
throws SQLException, Exception, ParseException {
DbHelper.testDbObjectFromDb(new TestRowHandler<PreparedStatement>() {
@Override
public void handle(PreparedStatement ps) throws Exception {
JdbcMapper<DbFinalObject> mapper = nonAsmFactory.newMapper(DbFinalObject.class);
assertMapPsFinalDbObject(ps.executeQuery(), mapper);
}
});
}
@Test
public void testFieldErrorHandling()
throws SQLException, Exception, ParseException {
@SuppressWarnings("unchecked")
FieldMapperErrorHandler<JdbcColumnKey> fieldMapperErrorHandler = mock(FieldMapperErrorHandler.class);
final Exception exception = new Exception("Error!");
JdbcMapper<DbObject> mapper = JdbcMapperFactoryHelper.asm()
.fieldMapperErrorHandler(fieldMapperErrorHandler)
.addCustomFieldMapper("id", new FieldMapper<ResultSet, DbObject>() {
@Override
public void mapTo(ResultSet source, DbObject target, MappingContext<? super ResultSet> mappingContext) throws Exception {
throw exception;
}
}).newBuilder(DbObject.class).addMapping("id").mapper();
List<DbObject> list = mapper.forEach(new MockDbObjectResultSet(1), new ListCollector<DbObject>()).getList();
assertNotNull(list.get(0));
verify(fieldMapperErrorHandler).errorMappingField(eq(new JdbcColumnKey("id", 1)), any(), same(list.get(0)), same(exception));
}
@Test
public void testFieldErrorHandlingOnResultSet()
throws SQLException, Exception, ParseException {
@SuppressWarnings("unchecked")
FieldMapperErrorHandler<JdbcColumnKey> fieldMapperErrorHandler = mock(FieldMapperErrorHandler.class);
ResultSet rs = mock(ResultSet.class);
final Exception exception = new SQLException("Error!");
JdbcMapper<DbObject> mapper = JdbcMapperFactoryHelper.asm()
.fieldMapperErrorHandler(fieldMapperErrorHandler)
.newBuilder(DbObject.class).addMapping("id").mapper();
when(rs.next()).thenReturn(true, false);
when(rs.getLong(1)).thenThrow(exception);
List<DbObject> list = mapper.forEach(rs, new ListCollector<DbObject>()).getList();
assertNotNull(list.get(0));
verify(fieldMapperErrorHandler).errorMappingField(eq(new JdbcColumnKey("id", 1)), any(), same(list.get(0)), same(exception));
}
@Test
public void testSetCheckedConsumerError() throws SQLException {
ConsumerErrorHandler errorHandler = mock(ConsumerErrorHandler.class);
ResultSet rs = mock(ResultSet.class);
when(rs.next()).thenReturn(true, true, false);
when(rs.getLong(1)).thenReturn(1l);
final Exception exception = new SQLException("Error!");
JdbcMapper<DbObject> mapper = JdbcMapperFactoryHelper.asm()
.consumerErrorHandler(errorHandler)
.newBuilder(DbObject.class).addMapping("id").mapper();
mapper.forEach(rs, new CheckedConsumer<DbObject>() {
@Override
public void accept(DbObject dbObject) throws Exception {
throw exception;
}
});
verify(errorHandler, times(2)).handlerError(same(exception), any(DbObject.class));
}
@Test
public void testCustomGetterFactory() throws SQLException {
JdbcMapper<DbObject> mapper = JdbcMapperFactoryHelper.asm().getterFactory(new GetterFactory<ResultSet, JdbcColumnKey>() {
@SuppressWarnings("unchecked")
@Override
public <P> Getter<ResultSet, P> newGetter(Type target, JdbcColumnKey key, Object... properties) {
return new Getter() {
@Override
public Object get(Object target) throws Exception {
return "Hello!";
}
}
;
}
}).newBuilder(DbObject.class).addMapping("name").mapper();
ResultSet rs = mock(ResultSet.class);
when(rs.next()).thenReturn(true, false);
DbObject object = mapper.iterator(rs).next();
assertEquals("Hello!", object.getName());
}
private void assertMapPsDbObject(ResultSet rs,
JdbcMapper<DbObject> mapper) throws Exception,
ParseException {
List<DbObject> list = mapper.forEach(rs, new ListCollector<DbObject>()).getList();
assertEquals(1, list.size());
DbHelper.assertDbObjectMapping(list.get(0));
}
private void assertMapPsDbObjectWithAlias(ResultSet rs,
JdbcMapper<DbObjectWithAlias> mapper) throws Exception,
ParseException {
List<DbObjectWithAlias> list = mapper.forEach(rs, new ListCollector<DbObjectWithAlias>()).getList();
assertEquals(1, list.size());
DbHelper.assertDbObjectWithAliasMapping(list.get(0));
}
private void assertMapPsFinalDbObject(ResultSet rs,
JdbcMapper<DbFinalObject> mapper) throws Exception,
ParseException {
List<DbFinalObject> list = mapper.forEach(rs, new ListCollector<DbFinalObject>()).getList();
assertEquals(1, list.size());
DbHelper.assertDbObjectMapping(list.get(0));
}
}