diff --git a/jdbcmapper/pom.xml b/jdbcmapper/pom.xml index f803382..b9df45d 100644 --- a/jdbcmapper/pom.xml +++ b/jdbcmapper/pom.xml @@ -44,7 +44,6 @@ maven-compiler-plugin - 3.1 1.6 1.6 @@ -66,6 +65,20 @@ + + maven-jar-plugin + + + + test-jar + + test-compile + + + + ${basedir}/target + + diff --git a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/AbstractSQLParser.java b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/AbstractSQLParser.java index b492d1b..6f809f3 100644 --- a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/AbstractSQLParser.java +++ b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/AbstractSQLParser.java @@ -1,6 +1,6 @@ package com.moparisthebest.jdbc.codegen; -import com.moparisthebest.jdbc.codegen.SQLParser; +import java.util.Arrays; /** * Created by mopar on 5/25/17. @@ -25,4 +25,11 @@ public abstract class AbstractSQLParser implements SQLParser { return isSelect; } + @Override + public String toString() { + return this.getClass().getCanonicalName()+"{" + + "columnNames=" + Arrays.toString(columnNames) + + ", isSelect=" + isSelect + + '}'; + } } 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 f3f70c1..d1a53eb 100644 --- a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapperProcessor.java +++ b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/JdbcMapperProcessor.java @@ -3,6 +3,7 @@ package com.moparisthebest.jdbc.codegen; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import javax.lang.model.element.*; +import javax.lang.model.type.MirroredTypeException; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; @@ -58,7 +59,7 @@ public class JdbcMapperProcessor extends AbstractProcessor { //byteArrayType = elements.getTypeElement(byte.class.getCanonicalName()).asType(); byteArrayType = types.getArrayType(types.getPrimitiveType(TypeKind.BYTE)); /* - clobStringType = elements.getTypeElement(ClobString.class.getCanonicalName()).asType(); + clobStringType = elements.getTypeElement(ClobString.class.getCanonicalName()).asType(); blobStringType = elements.getTypeElement(BlobString.class.getCanonicalName()).asType(); arrayListObjectType = elements.getTypeElement(ArrayInList.ArrayListObject.class.getCanonicalName()).asType(); */ @@ -82,7 +83,11 @@ public class JdbcMapperProcessor extends AbstractProcessor { } final TypeElement genClass = (TypeElement) element; final JdbcMapper.Mapper mapper = genClass.getAnnotation(JdbcMapper.Mapper.class); - final SQLParser parser = new SimpleSQLParser();//(SQLParser)Class.forName(mapper.sqlParser().getCanonicalName()).newInstance(); + final String sqlParserMirror = getSqlParser(mapper).toString(); + //final SQLParser parser = new SimpleSQLParser();//(SQLParser)Class.forName(mapper.sqlParser().getCanonicalName()).newInstance(); + //final SQLParser parser = mapper.sqlParser().equals(SQLParser.class) ? new SimpleSQLParser() : mapper.sqlParser().newInstance(); + final SQLParser parser = sqlParserMirror.equals("com.moparisthebest.jdbc.codegen.SQLParser") ? + new SimpleSQLParser() : (SQLParser) Class.forName(sqlParserMirror).newInstance(); final String qualifiedName = genClass.getQualifiedName().toString(); final boolean isInterface = genClass.getKind().isInterface(); final boolean doJndi = !mapper.jndiName().isEmpty(); @@ -305,7 +310,10 @@ public class JdbcMapperProcessor extends AbstractProcessor { tryClose(w); } } catch (Exception e) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element); + final StringWriter sw = new StringWriter(); + sw.write('\n'); + e.printStackTrace(new PrintWriter(sw)); + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage() + sw.toString(), element); return false; } return true; @@ -368,6 +376,16 @@ public class JdbcMapperProcessor extends AbstractProcessor { w.write(");\n"); } + private static TypeMirror getSqlParser(final JdbcMapper.Mapper mapper) { + // ridiculous isn't it? + try { + mapper.sqlParser(); + } catch (MirroredTypeException mte) { + return mte.getTypeMirror(); + } + return null; + } + public static Class typeMirrorToClass(final TypeMirror tm) throws ClassNotFoundException { switch (tm.getKind()) { case BOOLEAN: 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 3ca9483..d256e07 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java @@ -27,8 +27,12 @@ public class JdbcMapperTest { tryClose(dao); } + public PersonDAO getDao() { + return dao; + } + @Test public void testName() throws Throwable { - assertEquals(fieldPerson1.getFirstName(), dao.getFirstName(fieldPerson1.getPersonNo())); + assertEquals(fieldPerson1.getFirstName(), getDao().getFirstName(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 0cffa41..d4ba2c2 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java @@ -14,6 +14,7 @@ import java.util.Map; @JdbcMapper.Mapper( // jndiName = "bob", cachePreparedStatements = false +// , sqlParser = SimpleSQLParser.class ) public interface PersonDAO extends JdbcMapper { diff --git a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/SqlParserTest.java b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/SimpleSQLParserTest.java similarity index 79% rename from jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/SqlParserTest.java rename to jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/SimpleSQLParserTest.java index e04bce9..13402ca 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/SqlParserTest.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/SimpleSQLParserTest.java @@ -7,13 +7,17 @@ import static org.junit.Assert.*; /** * Created by mopar on 5/30/17. */ -public class SqlParserTest { +public class SimpleSQLParserTest { private final SQLParser factory = new SimpleSQLParser(); + public SQLParser getFactory() { + return factory; + } + @Test public void testSingleSelect() { - final SQLParser ret = factory.parse("select bob from tom"); + final SQLParser ret = getFactory().parse("select bob from tom"); assertTrue(ret.isSelect()); assertArrayEquals(new String[]{null, "BOB"}, ret.columnNames()); } @@ -26,7 +30,7 @@ public class SqlParserTest { , "select some_bob bob, some_tom as tom from tom" , "select tom.bob, some_tom as tom from tom" }) { - final SQLParser ret = factory.parse(sql); + final SQLParser ret = getFactory().parse(sql); assertTrue(ret.isSelect()); assertArrayEquals(expected, ret.columnNames()); } @@ -39,7 +43,7 @@ public class SqlParserTest { , "INSERT INTO bob (bob_no, bob) VALUES (1, 'bob')" , "MERGE INTO bob bla bla bla" }) { - final SQLParser ret = factory.parse(sql); + final SQLParser ret = getFactory().parse(sql); assertFalse(ret.isSelect()); } } diff --git a/pom.xml b/pom.xml index 07849fe..9943619 100644 --- a/pom.xml +++ b/pom.xml @@ -69,6 +69,7 @@ runtime-compiler querymapper jdbcmapper + presto-sqlparser @@ -161,13 +162,12 @@ - org.codehaus.mojo - build-helper-maven-plugin - 1.8 + maven-compiler-plugin + 3.1 - maven-antrun-plugin - 1.7 + maven-jar-plugin + 2.2 diff --git a/presto-sqlparser/pom.xml b/presto-sqlparser/pom.xml new file mode 100644 index 0000000..c7ef751 --- /dev/null +++ b/presto-sqlparser/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + com.moparisthebest.jdbcmapper + jdbcmapper-parent + 1.0-SNAPSHOT + + presto-sqlparser + ${project.artifactId} + + + ${project.groupId} + jdbcmapper + ${project.version} + + + com.facebook.presto + presto-parser + 0.177 + + + ${project.groupId} + jdbcmapper + ${project.version} + test-jar + test + + + ${project.groupId} + querymapper + ${project.version} + test-jar + test + + + junit + junit + test + + + org.apache.derby + derby + test + + + + ${project.artifactId} + + + maven-compiler-plugin + + 1.8 + 1.8 + true + + + + + my-testCompile + test-compile + + testCompile + + + + com.moparisthebest.jdbc.codegen.JdbcMapperProcessor + + + + + + + + diff --git a/presto-sqlparser/src/main/java/com/moparisthebest/jdbc/codegen/PrestoSQLParser.java b/presto-sqlparser/src/main/java/com/moparisthebest/jdbc/codegen/PrestoSQLParser.java new file mode 100644 index 0000000..2af1bde --- /dev/null +++ b/presto-sqlparser/src/main/java/com/moparisthebest/jdbc/codegen/PrestoSQLParser.java @@ -0,0 +1,62 @@ +package com.moparisthebest.jdbc.codegen; + +import com.facebook.presto.sql.parser.SqlParser; +import com.facebook.presto.sql.tree.*; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by mopar on 5/31/17. + */ +public class PrestoSQLParser extends AbstractSQLParser { + + private static final SqlParser SQL_PARSER = new SqlParser(); + + public PrestoSQLParser() { + super(null, false); + } + + private PrestoSQLParser(final String[] columnNames, final boolean isSelect) { + super(columnNames, isSelect); + } + + @Override + public SQLParser parse(final String sql) { + boolean isSelect = false; + String[] columnNames = null; + try { + //final Expression stmt = SQL_PARSER.createExpression(sql); + final Statement stmt = SQL_PARSER.createStatement(sql); + isSelect = stmt instanceof Query; + if (isSelect) { + final Query query = (Query) stmt; + final List selectItems = ((QuerySpecification)query.getQueryBody()).getSelect().getSelectItems(); + columnNames = new String[selectItems.size() + 1]; + int x = 0; + for(final SelectItem selectItem : selectItems) { + final SingleColumn sc = (SingleColumn) selectItem; + if(sc.getAlias().isPresent()) { + columnNames[++x] = sc.getAlias().get().toUpperCase(); + continue; + } + final Expression scExp = sc.getExpression(); + //columnNames[++x] = selectItem.toString(); + if(scExp instanceof Identifier) { + columnNames[++x] = ((Identifier)scExp).getName().toUpperCase(); + } else if(scExp instanceof DereferenceExpression) { + columnNames[++x] = ((DereferenceExpression)scExp).getFieldName().toUpperCase(); + } else { + throw new RuntimeException("unknown syntax"); + } + } + } + } catch(com.facebook.presto.sql.parser.ParsingException e) { + // ignore + //e.printStackTrace(); + //throw new RuntimeException(e); + } + return new PrestoSQLParser(columnNames, isSelect); + } + +} 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 new file mode 100644 index 0000000..d29429f --- /dev/null +++ b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java @@ -0,0 +1,56 @@ +package com.moparisthebest.jdbc.codegen; + +import com.moparisthebest.jdbc.dto.FieldPerson; + +import java.sql.SQLException; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +/** + * Created by mopar on 5/24/17. + */ +@JdbcMapper.Mapper( +// jndiName = "bob", + cachePreparedStatements = false + , sqlParser = PrestoSQLParser.class +) +public interface PrestoPersonDAO extends PersonDAO { + + @JdbcMapper.SQL("UPDATE person SET first_name = {firstName} WHERE last_name = {lastName}") + int setFirstName(String firstName, String lastName); + + @JdbcMapper.SQL("UPDATE person SET first_name = {firstName} WHERE person_no = {personNo}") + void setFirstName(String firstName, long personNo) throws SQLException; + + @JdbcMapper.SQL("UPDATE person SET first_name = {firstName} WHERE person_no = {personNo}") + void setFirstNameBlob(byte[] firstName, long personNo) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name FROM person WHERE person_no = {personNo}") + String getFirstName(long personNo) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE person_no = {personNo}") + FieldPerson getPerson(long personNo) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}") + List getPeople(String lastName) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}") + FieldPerson[] getPeopleArray(String lastName) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}") + Iterator getPeopleIterator(String lastName) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}") + ListIterator getPeopleListIterator(String lastName) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name, person_no FROM person WHERE last_name = {lastName}") + Map getPersonMap(String lastName) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name, last_name, person_no FROM person WHERE last_name = {lastName}") + Map> getPersonMapList(String lastName) throws SQLException; + + @JdbcMapper.SQL("SELECT first_name FROM person WHERE person_no = {personNo} and last_name = {lastName}") + String getFirstName(long personNo, String lastName) throws SQLException; +} diff --git a/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAOTest.java b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAOTest.java new file mode 100644 index 0000000..c451596 --- /dev/null +++ b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAOTest.java @@ -0,0 +1,33 @@ +package com.moparisthebest.jdbc.codegen; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.moparisthebest.jdbc.QueryMapperTest.fieldPerson1; +import static com.moparisthebest.jdbc.QueryMapperTest.getConnection; +import static com.moparisthebest.jdbc.TryClose.tryClose; +import static org.junit.Assert.assertEquals; + +/** + * Created by mopar on 5/24/17. + */ +public class PrestoPersonDAOTest extends JdbcMapperTest { + + private static PersonDAO dao; + + @BeforeClass + public static void setUp() throws Throwable { + dao = JdbcMapperFactory.create(PrestoPersonDAO.class, getConnection()); + //dao = new com.moparisthebest.jdbc.codegen.PersonDAOBean(getConnection()); + } + + @AfterClass + public static void tearDown() throws Throwable { + tryClose(dao); + } + + public PersonDAO getDao() { + return dao; + } +} diff --git a/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoSQLParserTest.java b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoSQLParserTest.java new file mode 100644 index 0000000..399b308 --- /dev/null +++ b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoSQLParserTest.java @@ -0,0 +1,18 @@ +package com.moparisthebest.jdbc.codegen; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by mopar on 5/30/17. + */ +public class PrestoSQLParserTest extends SimpleSQLParserTest { + + private final SQLParser factory = new PrestoSQLParser(); + + public SQLParser getFactory() { + return factory; + } + +} diff --git a/querymapper/pom.xml b/querymapper/pom.xml index 28c40a1..ace85e0 100644 --- a/querymapper/pom.xml +++ b/querymapper/pom.xml @@ -36,7 +36,6 @@ maven-jar-plugin - 2.2