From 9829e98ae0c6d289ccc58003d6245343aefd42de Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 23 Oct 2017 00:34:37 -0400 Subject: [PATCH] Add support for @SingleRow in JdbcMapper --- .../moparisthebest/jdbc/codegen/JdbcMapper.java | 7 +++++++ .../jdbc/codegen/CompileTimeResultSetMapper.java | 4 ++-- .../codegen/CompileTimeRowToObjectMapper.java | 11 ++++++----- .../jdbc/codegen/JdbcMapperTest.java | 15 +++++++++++++++ .../moparisthebest/jdbc/codegen/PersonDAO.java | 9 +++++++++ .../jdbc/codegen/PrestoPersonDAO.java | 9 +++++++++ 6 files changed, 48 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapper.java b/common/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapper.java index 15e99bd..909dba9 100644 --- a/common/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapper.java +++ b/common/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapper.java @@ -125,6 +125,13 @@ public interface JdbcMapper extends Closeable { @Target({ElementType.PARAMETER}) public @interface Clob {} + /** + * Equivalent to QueryMapper.toObject for arrays, and .toSingleMap for maps + */ + @Retention(RetentionPolicy.SOURCE) + @Target({ElementType.METHOD}) + public @interface SingleRow {} + public enum OptionalBool { DEFAULT, TRUE, diff --git a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeResultSetMapper.java b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeResultSetMapper.java index 9731d23..273d6e5 100644 --- a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeResultSetMapper.java +++ b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeResultSetMapper.java @@ -98,13 +98,13 @@ public class CompileTimeResultSetMapper { //final Class returnType = m.getReturnType(); final TypeMirror returnTypeMirror = eeMethod.getReturnType(); //final Class returnType = typeMirrorToClass(returnTypeMirror); - if (returnTypeMirror.getKind() == TypeKind.ARRAY && !types.isSameType(returnTypeMirror, byteArrayType)) { + if (returnTypeMirror.getKind() == TypeKind.ARRAY && !types.isSameType(returnTypeMirror, byteArrayType) && eeMethod.getAnnotation(JdbcMapper.SingleRow.class) == null) { final TypeMirror componentType = ((ArrayType) returnTypeMirror).getComponentType(); toArray(w, keys, componentType, maxRows, cal, cleaner, reflectionFields); } else if (types.isAssignable(returnTypeMirror, collectionType)) { final List typeArguments = ((DeclaredType) returnTypeMirror).getTypeArguments(); toCollection(w, keys, returnTypeMirror, typeArguments.get(0), maxRows, cal, cleaner, reflectionFields); - } else if (types.isAssignable(returnTypeMirror, mapType)) { + } else if (types.isAssignable(returnTypeMirror, mapType) && eeMethod.getAnnotation(JdbcMapper.SingleRow.class) == null) { final List typeArguments = ((DeclaredType) returnTypeMirror).getTypeArguments(); //if (types[1] instanceof ParameterizedType) { // for collectionMaps if (types.isAssignable(returnTypeMirror, mapCollectionType)) { // for collectionMaps diff --git a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java index edbf81a..f3fe057 100644 --- a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java +++ b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java @@ -16,6 +16,7 @@ import java.util.regex.Matcher; import static com.moparisthebest.jdbc.CompilingRowToObjectMapper.escapeMapKeyString; import static com.moparisthebest.jdbc.RowToObjectMapper._setterRegex; +import static com.moparisthebest.jdbc.codegen.CompileTimeResultSetMapper.getConcreteClassCanonicalName; import static com.moparisthebest.jdbc.codegen.JdbcMapperProcessor.typeMirrorToClass; /** @@ -69,9 +70,9 @@ public class CompileTimeRowToObjectMapper { returnMap = rsm.types.isAssignable(returnTypeClass, rsm.mapType); if (returnMap) { - // todo: need this? _returnTypeClass = ResultSetMapper.getConcreteClass(returnTypeClass, HashMap.class); - _returnTypeClass = null; - componentType = mapValType; + _returnTypeClass = returnTypeClass; + final List typeArguments = ((DeclaredType) returnTypeClass).getTypeArguments(); + componentType = typeArguments.size() > 1 ? typeArguments.get(1) : mapValType; resultSetConstructor = false; } else { _returnTypeClass = returnTypeClass; @@ -325,11 +326,11 @@ public class CompileTimeRowToObjectMapper { if (returnMap) // we want a map try { - java.append("final ").append(tType).append(" ret = new ").append(tType).append("();\n"); + java.append("final ").append(tType).append(" ret = new ").append(getConcreteClassCanonicalName(_returnTypeClass, HashMap.class)).append(tType.substring(tType.indexOf('<'))).append("();\n"); final int columnLength = _columnCount + 1; int typeId = getTypeId(componentType); - final String enumName = componentType.toString(); if (componentType != null && typeId != TypeMappingsFactory.TYPE_UNKNOWN) { // we want a specific value type + final String enumName = componentType.toString(); for (int x = 1; x < columnLength; ++x) { java.append("ret.put(").append(escapeMapKeyString(keys[x]).toLowerCase()).append(", "); extractColumnValueString(java, x, typeId, enumName); diff --git a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java index beda834..16c1d33 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java @@ -11,8 +11,10 @@ import org.junit.Test; import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; //IFJAVA8_START +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import java.time.*; @@ -194,4 +196,17 @@ public class JdbcMapperTest { public void testPerson() throws SQLException { assertEquals(fieldPerson1, dao.getPerson(fieldPerson1.getPersonNo())); } + + @Test + public void testSinglePersonNameArray() throws SQLException { + assertArrayEquals(new String[]{fieldPerson1.getFirstName(), fieldPerson1.getLastName()}, dao.getSinglePersonNameArray(fieldPerson1.getPersonNo())); + } + + @Test + public void testSinglePersonNameMap() throws SQLException { + final Map expected = new HashMap(); + expected.put("first_name", fieldPerson1.getFirstName()); + expected.put("last_name", fieldPerson1.getLastName()); + assertEquals(expected, dao.getSinglePersonNameMap(fieldPerson1.getPersonNo())); + } } diff --git a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java index a5a71af..bb59db0 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java @@ -242,4 +242,13 @@ public interface PersonDAO extends JdbcMapper { // test blob @JdbcMapper.SQL("SELECT some_blob FROM val WHERE val_no = {valNo}") byte[] getBlob(long valNo); + + // test Single rows + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE person_no = {personNo}") + @SingleRow + String[] getSinglePersonNameArray(long personNo) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE person_no = {personNo}") + @SingleRow + Map getSinglePersonNameMap(long personNo) throws SQLException; } diff --git a/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java index da52fa3..b97242e 100644 --- a/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java +++ b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java @@ -242,4 +242,13 @@ public interface PrestoPersonDAO extends PersonDAO { // test blob @JdbcMapper.SQL("SELECT some_blob FROM val WHERE val_no = {valNo}") byte[] getBlob(long valNo); + + // test Single rows + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE person_no = {personNo}") + @SingleRow + String[] getSinglePersonNameArray(long personNo) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE person_no = {personNo}") + @SingleRow + Map getSinglePersonNameMap(long personNo) throws SQLException; }