From 664c00a5b21654b77860eb613eed2cea9ea2ffd8 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Sat, 9 Feb 2019 00:06:13 -0500 Subject: [PATCH] Implement JdbcMapper.sqlBuilder() method --- .../java/com/moparisthebest/jdbc/InList.java | 1 - .../jdbc/codegen/JdbcMapper.java | 8 ++- .../jdbc/codegen/JdbcMapperProcessor.java | 58 +++++++++++++++++++ .../com/moparisthebest/jdbc/QueryMapper.java | 5 ++ .../jdbc/codegen/QueryMapperQmDao.java | 5 ++ .../moparisthebest/jdbc/QueryMapperTest.java | 12 ++-- 6 files changed, 81 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/com/moparisthebest/jdbc/InList.java b/common/src/main/java/com/moparisthebest/jdbc/InList.java index 4208618..655a7ef 100644 --- a/common/src/main/java/com/moparisthebest/jdbc/InList.java +++ b/common/src/main/java/com/moparisthebest/jdbc/InList.java @@ -3,7 +3,6 @@ package com.moparisthebest.jdbc; import com.moparisthebest.jdbc.codegen.JdbcMapper; import com.moparisthebest.jdbc.util.Bindable; import com.moparisthebest.jdbc.util.InListUtil; -import com.moparisthebest.jdbc.util.PreparedStatementUtil; import java.lang.reflect.Method; import java.sql.Connection; 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 cad0774..7844fb0 100644 --- a/common/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapper.java +++ b/common/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapper.java @@ -16,10 +16,16 @@ public interface JdbcMapper extends Closeable { Connection getConnection(); + /*IFJAVA6_START + + SqlBuilder sqlBuilder(); + + IFJAVA6_END*/ + //IFJAVA8_START default SqlBuilder sqlBuilder() { - return SqlBuilder.of(getConnection()); // todo: should this use the current inList ? + return SqlBuilder.of(getConnection()); } //IFJAVA8_END diff --git a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapperProcessor.java b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapperProcessor.java index 1e2bc1e..3bb8b9a 100644 --- a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapperProcessor.java +++ b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapperProcessor.java @@ -230,6 +230,12 @@ public class JdbcMapperProcessor extends AbstractProcessor { w.write(packageName); w.write(";\n\n"); } + + final ExecutableElement sqlBuilderMethod = getSqlBuilderMethod(genClass); + if(sqlBuilderMethod != null) { + w.write("import com.moparisthebest.jdbc.util.SqlBuilder;\n"); + } + w.write("import com.moparisthebest.jdbc.Factory;\n\n"); w.write("import java.sql.*;\n\n"); w.write("import static com.moparisthebest.jdbc.util.ResultSetUtil.*;\n"); @@ -688,6 +694,30 @@ public class JdbcMapperProcessor extends AbstractProcessor { } // end close method + + if(sqlBuilderMethod != null) { + // we want to generate this method returning proper InList + w.append("\n\t@Override\n\tpublic SqlBuilder sqlBuilder() {\n\t\treturn SqlBuilder.of(conn, com.moparisthebest.jdbc."); + switch(databaseType) { + case ORACLE: + w.append("OracleArrayInList"); + break; + case ANY: + w.append("ArrayInList"); + break; + case UNNEST: + w.append("UnNestArrayInList"); + break; + case BIND: + w.append("BindInList"); + break; + default: + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@JdbcMapper.Mapper.databaseType unsupported", element); + continue; + } + w.append(".instance());\n\t}\n"); + } + w.write("}\n"); } finally { tryClose(w); @@ -1126,6 +1156,34 @@ public class JdbcMapperProcessor extends AbstractProcessor { methodElement.getParameters().isEmpty() ? methodElement : null; } + public ExecutableElement getSqlBuilderMethod(final TypeElement genClass) { + ExecutableElement ret = null; + for (final Element methodElement : genClass.getEnclosedElements()) { + if ((ret = getSqlBuilderMethod(methodElement)) != null) + return ret; + } + // superclasses + final TypeMirror superclass = genClass.getSuperclass(); + if (superclass.getKind() == TypeKind.DECLARED && (ret = getSqlBuilderMethod((TypeElement) types.asElement(superclass))) != null) + return ret; + // interfaces + for (final TypeMirror iface : genClass.getInterfaces()) { + if (iface.getKind() == TypeKind.DECLARED && (ret = getSqlBuilderMethod((TypeElement) types.asElement(iface))) != null) + return ret; + } + return ret; + } + + public static ExecutableElement getSqlBuilderMethod(final Element element) { + return element.getKind() != ElementKind.METHOD ? null : getSqlBuilderMethod((ExecutableElement) element); + } + + public static ExecutableElement getSqlBuilderMethod(final ExecutableElement methodElement) { + return methodElement.getReturnType().getKind() == TypeKind.DECLARED && + methodElement.getSimpleName().toString().equals("sqlBuilder") && + methodElement.getParameters().isEmpty() ? methodElement : null; + } + public static boolean isPrimitiveInteger(final TypeKind kind) { switch(kind) { case BYTE: diff --git a/querymapper/src/main/java/com/moparisthebest/jdbc/QueryMapper.java b/querymapper/src/main/java/com/moparisthebest/jdbc/QueryMapper.java index 20f9720..340f96b 100644 --- a/querymapper/src/main/java/com/moparisthebest/jdbc/QueryMapper.java +++ b/querymapper/src/main/java/com/moparisthebest/jdbc/QueryMapper.java @@ -179,6 +179,11 @@ public class QueryMapper implements JdbcMapper { return inListEnabled && sql.contains(inListReplace) ? recursiveReplace(new StringBuilder(sql), bindObjects).toString() : sql; } + @Override + public SqlBuilder sqlBuilder() { + return SqlBuilder.of(conn, inList); + } + public InList.InListObject inList(final String columnName, final Collection values) throws SQLException { this.inListEnabled = true; // worth checking if it's already this or not? return this.inList.inList(conn, columnName, values); diff --git a/test/src/main/java/com/moparisthebest/jdbc/codegen/QueryMapperQmDao.java b/test/src/main/java/com/moparisthebest/jdbc/codegen/QueryMapperQmDao.java index a26e3b8..653761e 100644 --- a/test/src/main/java/com/moparisthebest/jdbc/codegen/QueryMapperQmDao.java +++ b/test/src/main/java/com/moparisthebest/jdbc/codegen/QueryMapperQmDao.java @@ -74,6 +74,11 @@ public class QueryMapperQmDao implements QmDao { tryClose(qm); } + @Override + public SqlBuilder sqlBuilder() { + return qm.sqlBuilder(); + } + @Override public FieldPerson getFieldRegularPerson(final long personNo) throws SQLException { return qm.toObject(personRegular, FieldPerson.class, personNo); diff --git a/test/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java b/test/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java index 3518ee2..f72a092 100644 --- a/test/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java +++ b/test/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java @@ -770,12 +770,12 @@ public class QueryMapperTest { @Test public void testSelectRandomSqlBuilder() throws Throwable { final List arr = Arrays.asList(1L, 2L, 3L); - assertEquals(arr, qm.selectRandomSqlBuilder(SqlBuilder.of(qm.getConnection()).appendInList("person_no", arr))); - assertEquals(arr, qm.selectRandomSqlBuilder(SqlBuilder.of(qm.getConnection()).append("person_no = ? OR ", 1L).appendInList("person_no", Arrays.asList(2L, 3L)))); - assertEquals(arr, qm.selectRandomSqlBuilder(SqlBuilder.of(qm.getConnection()).append("person_no = 1 OR ").appendInList("person_no", Arrays.asList(2L, 3L)))); - assertEquals(arr, qm.selectRandomSqlBuilder(1L, SqlBuilder.of(qm.getConnection()).append(" OR person_no in (2,3)"), "NoNameMatch")); - assertEquals(Collections.singletonList(2L), qm.selectRandomSqlBuilder(2L, SqlBuilder.of(qm.getConnection()), "NoNameMatch")); + assertEquals(arr, qm.selectRandomSqlBuilder(qm.sqlBuilder().appendInList("person_no", arr))); + assertEquals(arr, qm.selectRandomSqlBuilder(qm.sqlBuilder().append("person_no = ? OR ", 1L).appendInList("person_no", Arrays.asList(2L, 3L)))); + assertEquals(arr, qm.selectRandomSqlBuilder(qm.sqlBuilder().append("person_no = 1 OR ").appendInList("person_no", Arrays.asList(2L, 3L)))); + assertEquals(arr, qm.selectRandomSqlBuilder(1L, qm.sqlBuilder().append(" OR person_no in (2,3)"), "NoNameMatch")); + assertEquals(Collections.singletonList(2L), qm.selectRandomSqlBuilder(2L, qm.sqlBuilder(), "NoNameMatch")); assertEquals(Collections.singletonList(3L), qm.selectRandomSqlBuilder(3L, Bindable.empty, "NoNameMatch")); - assertEquals(arr, qm.selectRandomSqlBuilder(2L, SqlBuilder.of(qm.getConnection()).append("OR person_no = ? OR ", 1L).appendInList("person_no", Collections.singletonList(3L)), "NoNameMatch")); + assertEquals(arr, qm.selectRandomSqlBuilder(2L, qm.sqlBuilder().append("OR person_no = ? OR ", 1L).appendInList("person_no", Collections.singletonList(3L)), "NoNameMatch")); } }