Implement UnNestArrayInList for hsqldb

This commit is contained in:
Travis Burtrum 2018-05-15 23:32:00 -04:00
parent 30599a15fd
commit 7cc5af55fb
4 changed files with 57 additions and 6 deletions

View File

@ -129,6 +129,7 @@ public interface JdbcMapper extends Closeable {
public enum DatabaseType { public enum DatabaseType {
DEFAULT(null, null), DEFAULT(null, null),
STANDARD("numeric", "text"), STANDARD("numeric", "text"),
UNNEST("numeric", "text"),
ORACLE("ARRAY_NUM_TYPE", "ARRAY_STR_TYPE"); ORACLE("ARRAY_NUM_TYPE", "ARRAY_STR_TYPE");
public final String arrayNumberTypeName, arrayStringTypeName; public final String arrayNumberTypeName, arrayStringTypeName;

View File

@ -1,9 +1,6 @@
package com.moparisthebest.jdbc.codegen; package com.moparisthebest.jdbc.codegen;
import com.moparisthebest.jdbc.ArrayInList; import com.moparisthebest.jdbc.*;
import com.moparisthebest.jdbc.Cleaner;
import com.moparisthebest.jdbc.MapperException;
import com.moparisthebest.jdbc.OracleArrayInList;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
@ -194,6 +191,9 @@ public class JdbcMapperProcessor extends AbstractProcessor {
case STANDARD: case STANDARD:
arrayInList = new ArrayInList(arrayNumberTypeName, arrayStringTypeName); arrayInList = new ArrayInList(arrayNumberTypeName, arrayStringTypeName);
break; break;
case UNNEST:
arrayInList = new UnNestArrayInList(arrayNumberTypeName, arrayStringTypeName);
break;
default: default:
// no support // no support
arrayInList = null; arrayInList = null;
@ -403,6 +403,11 @@ public class JdbcMapperProcessor extends AbstractProcessor {
"(" + inColumnName + " != ANY(?))" : "(" + inColumnName + " != ANY(?))" :
"(" + inColumnName + " = ANY(?))"; "(" + inColumnName + " = ANY(?))";
break; break;
case UNNEST:
replacement = not ?
"(" + inColumnName + " NOT IN(UNNEST(?)))" :
"(" + inColumnName + " IN(UNNEST(?)))";
break;
default: default:
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "default DatabaseType? should never happen!!", bindParam); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "default DatabaseType? should never happen!!", bindParam);
return false; return false;
@ -749,6 +754,7 @@ public class JdbcMapperProcessor extends AbstractProcessor {
//w.write("(Array) createArray.invoke(conn.unwrap(oracleConnection), \""); //w.write("(Array) createArray.invoke(conn.unwrap(oracleConnection), \"");
break; break;
case STANDARD: case STANDARD:
case UNNEST:
w.write("conn.createArrayOf(\""); w.write("conn.createArrayOf(\"");
break; break;
default: default:

View File

@ -0,0 +1,26 @@
package com.moparisthebest.jdbc;
/**
* HSQLDB requires array in lists to be implemented this way:
* https://stackoverflow.com/questions/35939489/createarrayof-string-in-hsqldb-jdbc-returns-abstractmethoderror/35964424#35964424
*/
public class UnNestArrayInList extends ArrayInList {
private static final InList instance = new UnNestArrayInList();
public static InList instance() {
return instance;
}
public UnNestArrayInList(final String numberType, final String otherType) {
super(numberType, otherType);
}
public UnNestArrayInList() {
super();
}
protected String columnAppend(final String columnName) {
return "(" + columnName + " IN(UNNEST(?)))";
}
}

View File

@ -54,12 +54,13 @@ public class QueryMapperQmDao implements QmDao {
public static final String selectStrVal = "SELECT str_val FROM val WHERE val_no = ?"; public static final String selectStrVal = "SELECT str_val FROM val WHERE val_no = ?";
private static final Collection<Class<?>> noArrayInListSupport; private static final Collection<Class<?>> noArrayInListSupport;
private static final Class<?> hsqlConnection;
static { static {
Collection<Class<?>> no = new ArrayList<Class<?>>(); Collection<Class<?>> no = new ArrayList<Class<?>>();
for(final String connectionClassName : new String[]{ for(final String connectionClassName : new String[]{
"org.apache.derby.impl.jdbc.EmbedConnection" "org.apache.derby.impl.jdbc.EmbedConnection"
, "org.hsqldb.jdbc.JDBCConnection" , "org.hsqldb.jdbc.JDBCConnection" // does not support ArrayInList but *does* support UnNestArrayInList
, "org.sqlite.jdbc3.JDBC3Connection" , "org.sqlite.jdbc3.JDBC3Connection"
, "org.mariadb.jdbc.MariaDbConnection" , "org.mariadb.jdbc.MariaDbConnection"
// h2 doesn't support this with java6 either... // h2 doesn't support this with java6 either...
@ -73,6 +74,13 @@ public class QueryMapperQmDao implements QmDao {
// ignore // ignore
} }
noArrayInListSupport = Collections.unmodifiableCollection(no); noArrayInListSupport = Collections.unmodifiableCollection(no);
Class<?> hsql = null;
try {
hsql = Class.forName("org.hsqldb.jdbc.JDBCConnection");
} catch(Exception e) {
// ignore
}
hsqlConnection = hsql;
} }
public static boolean supportsArrayInList(final Connection conn) { public static boolean supportsArrayInList(final Connection conn) {
@ -89,7 +97,17 @@ public class QueryMapperQmDao implements QmDao {
} }
public static InList getBestInList(final Connection conn) { public static InList getBestInList(final Connection conn) {
return supportsArrayInList(conn) ? ArrayInList.instance() : BindInList.instance(); if(supportsArrayInList(conn))
return ArrayInList.instance();
if(hsqlConnection != null)
try {
if(conn.isWrapperFor(hsqlConnection))
return UnNestArrayInList.instance();
} catch (SQLException e) {
// ignore
}
// works for everything
return BindInList.instance();
} }
protected final QueryMapper qm; protected final QueryMapper qm;