mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#836 - ENH: Add support for @DbArray even for H2 db
This commit is contained in:
@@ -197,6 +197,13 @@ public class DatabasePlatform {
|
||||
return platform == null || platform.name().equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this matches the given platform.
|
||||
*/
|
||||
public boolean isPlatform(Platform platform) {
|
||||
return platform.name().equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the DatabasePlatform.
|
||||
* <p>
|
||||
|
||||
@@ -5,7 +5,7 @@ import java.util.UUID;
|
||||
/**
|
||||
* Type conversion for use with ScalarTypeArrayList.
|
||||
*/
|
||||
public interface ArrayElementConverter<T> {
|
||||
interface ArrayElementConverter<T> {
|
||||
|
||||
/**
|
||||
* Convert the array element to the logical type.
|
||||
@@ -32,6 +32,11 @@ public interface ArrayElementConverter<T> {
|
||||
*/
|
||||
ArrayElementConverter INTEGER = new IntegerConverter();
|
||||
|
||||
/**
|
||||
* The Double converter implementation.
|
||||
*/
|
||||
ArrayElementConverter DOUBLE = new DoubleConverter();
|
||||
|
||||
class LongConverter implements ArrayElementConverter<Long> {
|
||||
|
||||
@Override
|
||||
@@ -56,6 +61,18 @@ public interface ArrayElementConverter<T> {
|
||||
}
|
||||
}
|
||||
|
||||
class DoubleConverter implements ArrayElementConverter<Double> {
|
||||
|
||||
@Override
|
||||
public Double toElement(Object rawValue) {
|
||||
if (rawValue instanceof Double) {
|
||||
return (Double) rawValue;
|
||||
} else {
|
||||
return ((Number) rawValue).doubleValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String converter (noop based).
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.avaje.ebean.annotation.EnumValue;
|
||||
import com.avaje.ebean.config.CompoundType;
|
||||
import com.avaje.ebean.config.CompoundTypeProperty;
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.config.Platform;
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
@@ -185,6 +186,8 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
*/
|
||||
private ScalarType<?> jsonNodeJsonb;
|
||||
|
||||
private final PlatformArrayTypeFactory arrayTypeFactory;
|
||||
|
||||
/**
|
||||
* Create the DefaultTypeManager.
|
||||
*/
|
||||
@@ -204,6 +207,8 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
|
||||
this.extraTypeFactory = new DefaultTypeFactory(config);
|
||||
this.postgres = isPostgres(config.getDatabasePlatform());
|
||||
this.arrayTypeFactory = arrayTypeFactory(postgres, config.getDatabasePlatform());
|
||||
|
||||
this.offlineMigrationGeneration = DbOffline.isGenerateMigration();
|
||||
|
||||
initialiseStandard(jsonDateTime, config);
|
||||
@@ -220,6 +225,19 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the factory to use to support DB ARRAY types.
|
||||
*/
|
||||
private PlatformArrayTypeFactory arrayTypeFactory(boolean postgres, DatabasePlatform databasePlatform) {
|
||||
if (postgres) {
|
||||
return ScalarTypeArrayList.factory();
|
||||
} else if (databasePlatform.isPlatform(Platform.H2)) {
|
||||
return ScalarTypeArrayListH2.factory();
|
||||
}
|
||||
// not supported for this DB platform
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load custom scalar types registered via ExtraTypeFactory and ServiceLoader.
|
||||
*/
|
||||
@@ -397,9 +415,9 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
public ScalarType<?> getArrayScalarType(Class<?> type, DbArray dbArray, Type genericType) {
|
||||
|
||||
if (type.equals(List.class)) {
|
||||
if (postgres) {
|
||||
if (arrayTypeFactory != null) {
|
||||
Type valueType = getValueType(genericType);
|
||||
return ScalarTypeArrayList.typeFor(valueType);
|
||||
return arrayTypeFactory.typeFor(valueType);
|
||||
}
|
||||
// fallback to JSON storage in VARCHAR column
|
||||
return new ScalarTypeJsonList.Varchar(getDocType(getValueType(genericType)));
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Factory for platform specific handling/ScalarTypes for DB ARRAY.
|
||||
*/
|
||||
public interface PlatformArrayTypeFactory {
|
||||
|
||||
/**
|
||||
* Return the ScalarType to handle DB ARRAY for the given element type.
|
||||
*/
|
||||
ScalarType<?> typeFor(Type valueType);
|
||||
|
||||
}
|
||||
@@ -22,30 +22,38 @@ import java.util.UUID;
|
||||
public class ScalarTypeArrayList extends ScalarTypeJsonCollection<List> {
|
||||
|
||||
private static ScalarTypeArrayList UUID = new ScalarTypeArrayList("uuid", DocPropertyType.UUID, ArrayElementConverter.UUID);
|
||||
|
||||
private static ScalarTypeArrayList LONG = new ScalarTypeArrayList("bigint", DocPropertyType.LONG, ArrayElementConverter.LONG);
|
||||
|
||||
private static ScalarTypeArrayList INTEGER = new ScalarTypeArrayList("integer", DocPropertyType.INTEGER, ArrayElementConverter.INTEGER);
|
||||
|
||||
private static ScalarTypeArrayList DOUBLE = new ScalarTypeArrayList("float", DocPropertyType.DOUBLE, ArrayElementConverter.DOUBLE);
|
||||
private static ScalarTypeArrayList STRING = new ScalarTypeArrayList("varchar", DocPropertyType.STRING, ArrayElementConverter.STRING);
|
||||
|
||||
/**
|
||||
* Return the ScalarType to use based on the List's generic parameter type.
|
||||
*/
|
||||
public static ScalarTypeArrayList typeFor(Type valueType) {
|
||||
if (valueType.equals(UUID.class)) {
|
||||
return UUID;
|
||||
static PlatformArrayTypeFactory factory() {
|
||||
return new Factory();
|
||||
}
|
||||
|
||||
static class Factory implements PlatformArrayTypeFactory {
|
||||
|
||||
/**
|
||||
* Return the ScalarType to use based on the List's generic parameter type.
|
||||
*/
|
||||
public ScalarTypeArrayList typeFor(Type valueType) {
|
||||
if (valueType.equals(UUID.class)) {
|
||||
return UUID;
|
||||
}
|
||||
if (valueType.equals(Long.class)) {
|
||||
return LONG;
|
||||
}
|
||||
if (valueType.equals(Integer.class)) {
|
||||
return INTEGER;
|
||||
}
|
||||
if (valueType.equals(Double.class)) {
|
||||
return DOUBLE;
|
||||
}
|
||||
if (valueType.equals(String.class)) {
|
||||
return STRING;
|
||||
}
|
||||
throw new IllegalArgumentException("Type [" + valueType + "] not supported for @DbArray mapping");
|
||||
}
|
||||
if (valueType.equals(Long.class)) {
|
||||
return LONG;
|
||||
}
|
||||
if (valueType.equals(Integer.class)) {
|
||||
return INTEGER;
|
||||
}
|
||||
if (valueType.equals(String.class)) {
|
||||
return STRING;
|
||||
}
|
||||
throw new IllegalArgumentException("Type [" + valueType + "] not supported for @DbArray mapping");
|
||||
}
|
||||
|
||||
private final String arrayType;
|
||||
@@ -79,7 +87,7 @@ public class ScalarTypeArrayList extends ScalarTypeJsonCollection<List> {
|
||||
return new ModifyAwareList(list);
|
||||
}
|
||||
|
||||
private Object[] toArray(List value) {
|
||||
protected Object[] toArray(List value) {
|
||||
return value.toArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyType;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* H2 database support for DB ARRAY.
|
||||
*/
|
||||
class ScalarTypeArrayListH2 extends ScalarTypeArrayList {
|
||||
|
||||
private static ScalarTypeArrayListH2 UUID = new ScalarTypeArrayListH2("uuid", DocPropertyType.UUID, ArrayElementConverter.UUID);
|
||||
private static ScalarTypeArrayListH2 LONG = new ScalarTypeArrayListH2("bigint", DocPropertyType.LONG, ArrayElementConverter.LONG);
|
||||
private static ScalarTypeArrayListH2 INTEGER = new ScalarTypeArrayListH2("integer", DocPropertyType.INTEGER, ArrayElementConverter.INTEGER);
|
||||
private static ScalarTypeArrayListH2 DOUBLE = new ScalarTypeArrayListH2("double", DocPropertyType.DOUBLE, ArrayElementConverter.DOUBLE);
|
||||
private static ScalarTypeArrayListH2 STRING = new ScalarTypeArrayListH2("varchar", DocPropertyType.STRING, ArrayElementConverter.STRING);
|
||||
|
||||
static PlatformArrayTypeFactory factory() {
|
||||
return new ScalarTypeArrayListH2.Factory();
|
||||
}
|
||||
|
||||
static class Factory implements PlatformArrayTypeFactory {
|
||||
|
||||
/**
|
||||
* Return the ScalarType to use based on the List's generic parameter type.
|
||||
*/
|
||||
public ScalarTypeArrayListH2 typeFor(Type valueType) {
|
||||
if (valueType.equals(java.util.UUID.class)) {
|
||||
return UUID;
|
||||
}
|
||||
if (valueType.equals(Long.class)) {
|
||||
return LONG;
|
||||
}
|
||||
if (valueType.equals(Integer.class)) {
|
||||
return INTEGER;
|
||||
}
|
||||
if (valueType.equals(Double.class)) {
|
||||
return DOUBLE;
|
||||
}
|
||||
if (valueType.equals(String.class)) {
|
||||
return STRING;
|
||||
}
|
||||
throw new IllegalArgumentException("Type [" + valueType + "] not supported for @DbArray mapping");
|
||||
}
|
||||
}
|
||||
|
||||
private ScalarTypeArrayListH2(String arrayType, DocPropertyType docPropertyType, ArrayElementConverter converter) {
|
||||
super(arrayType, docPropertyType, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDbColumnDefn() {
|
||||
return "array";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(DataBind bind, List value) throws SQLException {
|
||||
if (value == null) {
|
||||
bind.setNull(Types.ARRAY);
|
||||
} else {
|
||||
bind.setObject(toArray(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user