Date: Fri, 4 Nov 2016 01:16:32 +1300
Subject: [PATCH 06/10] #836 - ENH: Add support for @DbArray even for H2 db
---
.../config/dbplatform/DatabasePlatform.java | 7 ++
.../server/type/ArrayElementConverter.java | 19 +++++-
.../server/type/DefaultTypeManager.java | 22 +++++-
.../server/type/PlatformArrayTypeFactory.java | 15 +++++
.../server/type/ScalarTypeArrayList.java | 48 +++++++------
.../server/type/ScalarTypeArrayListH2.java | 67 +++++++++++++++++++
.../server/type/ScalarTypeArrayListTest.java | 3 +-
.../avaje/tests/model/array/EArrayBean.java | 11 +++
.../tests/model/array/TestDbArray_basic.java | 6 ++
9 files changed, 173 insertions(+), 25 deletions(-)
create mode 100644 src/main/java/com/avaje/ebeaninternal/server/type/PlatformArrayTypeFactory.java
create mode 100644 src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListH2.java
diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java
index 6289dd810..97671b6ed 100644
--- a/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java
+++ b/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java
@@ -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.
*
diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ArrayElementConverter.java b/src/main/java/com/avaje/ebeaninternal/server/type/ArrayElementConverter.java
index 0899fa40a..9bd2d23b7 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/type/ArrayElementConverter.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/type/ArrayElementConverter.java
@@ -5,7 +5,7 @@ import java.util.UUID;
/**
* Type conversion for use with ScalarTypeArrayList.
*/
-public interface ArrayElementConverter {
+interface ArrayElementConverter {
/**
* Convert the array element to the logical type.
@@ -32,6 +32,11 @@ public interface ArrayElementConverter {
*/
ArrayElementConverter INTEGER = new IntegerConverter();
+ /**
+ * The Double converter implementation.
+ */
+ ArrayElementConverter DOUBLE = new DoubleConverter();
+
class LongConverter implements ArrayElementConverter {
@Override
@@ -56,6 +61,18 @@ public interface ArrayElementConverter {
}
}
+ class DoubleConverter implements ArrayElementConverter {
+
+ @Override
+ public Double toElement(Object rawValue) {
+ if (rawValue instanceof Double) {
+ return (Double) rawValue;
+ } else {
+ return ((Number) rawValue).doubleValue();
+ }
+ }
+ }
+
/**
* String converter (noop based).
*/
diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java b/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java
index c299d45e1..6ef22fba2 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java
@@ -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)));
diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/PlatformArrayTypeFactory.java b/src/main/java/com/avaje/ebeaninternal/server/type/PlatformArrayTypeFactory.java
new file mode 100644
index 000000000..ba6a9fe17
--- /dev/null
+++ b/src/main/java/com/avaje/ebeaninternal/server/type/PlatformArrayTypeFactory.java
@@ -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);
+
+}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayList.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayList.java
index 0e7b693db..4aa61b15a 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayList.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayList.java
@@ -22,30 +22,38 @@ import java.util.UUID;
public class ScalarTypeArrayList extends ScalarTypeJsonCollection {
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 {
return new ModifyAwareList(list);
}
- private Object[] toArray(List value) {
+ protected Object[] toArray(List value) {
return value.toArray();
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListH2.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListH2.java
new file mode 100644
index 000000000..b9b4175d8
--- /dev/null
+++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListH2.java
@@ -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));
+ }
+ }
+}
diff --git a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListTest.java b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListTest.java
index 9a60004e5..22398359e 100644
--- a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListTest.java
+++ b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeArrayListTest.java
@@ -14,8 +14,7 @@ public class ScalarTypeArrayListTest {
DataReader mock = Mockito.mock(DataReader.class);
Mockito.when(mock.getArray()).thenReturn(null);
- ScalarTypeArrayList scalarType = ScalarTypeArrayList.typeFor(Long.class);
+ ScalarType> scalarType = ScalarTypeArrayList.factory().typeFor(Long.class);
scalarType.read(mock);
-
}
}
\ No newline at end of file
diff --git a/src/test/java/com/avaje/tests/model/array/EArrayBean.java b/src/test/java/com/avaje/tests/model/array/EArrayBean.java
index a16670a8c..c16960592 100644
--- a/src/test/java/com/avaje/tests/model/array/EArrayBean.java
+++ b/src/test/java/com/avaje/tests/model/array/EArrayBean.java
@@ -27,6 +27,9 @@ public class EArrayBean {
@DbArray
List otherIds = new ArrayList();
+ @DbArray
+ List doubs;
+
@Version
Long version;
@@ -70,6 +73,14 @@ public class EArrayBean {
this.otherIds = otherIds;
}
+ public List getDoubs() {
+ return doubs;
+ }
+
+ public void setDoubs(List doubs) {
+ this.doubs = doubs;
+ }
+
public Long getVersion() {
return version;
}
diff --git a/src/test/java/com/avaje/tests/model/array/TestDbArray_basic.java b/src/test/java/com/avaje/tests/model/array/TestDbArray_basic.java
index 21b945bc2..405cbdfa7 100644
--- a/src/test/java/com/avaje/tests/model/array/TestDbArray_basic.java
+++ b/src/test/java/com/avaje/tests/model/array/TestDbArray_basic.java
@@ -28,11 +28,17 @@ public class TestDbArray_basic extends BaseTestCase {
phNumbers.add("4321");
phNumbers.add("9823");
+
+ List doubles = new ArrayList();
+ doubles.add(1.3);
+ doubles.add(2.4);
+
bean.getUids().add(UUID.randomUUID());
bean.getUids().add(UUID.randomUUID());
bean.getOtherIds().add(95L);
bean.getOtherIds().add(96L);
bean.getOtherIds().add(97L);
+ bean.setDoubs(doubles);
Ebean.save(bean);
From c911c710d5be7de170f2d3840e6d8657b8ba8a40 Mon Sep 17 00:00:00 2001
From: Rob Bygrave
Date: Fri, 4 Nov 2016 01:17:08 +1300
Subject: [PATCH 07/10] Bump pom to 8.8.1-SNAPSHOT
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 88c36e185..2eaad2be5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
org.avaje.ebean
ebean
- 8.7.2-SNAPSHOT
+ 8.8.1-SNAPSHOT
jar
ebean
From 9c74520a4bdfd50b999f9640a9c2d8e233ec050a Mon Sep 17 00:00:00 2001
From: Rob Bygrave
Date: Fri, 4 Nov 2016 19:19:02 +1300
Subject: [PATCH 08/10] [maven-release-plugin] prepare release ebean-8.8.1
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 2eaad2be5..bf03fcb2f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
org.avaje.ebean
ebean
- 8.8.1-SNAPSHOT
+ 8.8.1
jar
ebean
@@ -37,7 +37,7 @@
scm:git:https://github.com/ebean-orm/ebean.git
- HEAD
+ ebean-8.8.1
From 78c4dbb44d0904d635925731da279ea0da5999d9 Mon Sep 17 00:00:00 2001
From: Rob Bygrave
Date: Fri, 4 Nov 2016 19:19:11 +1300
Subject: [PATCH 09/10] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index bf03fcb2f..28515cd59 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
org.avaje.ebean
ebean
- 8.8.1
+ 8.8.2-SNAPSHOT
jar
ebean
@@ -37,7 +37,7 @@
scm:git:https://github.com/ebean-orm/ebean.git
- ebean-8.8.1
+ HEAD
From fad8358a9d0bf837aceb4b6783b536a31191c16c Mon Sep 17 00:00:00 2001
From: Rob Bygrave
Date: Fri, 4 Nov 2016 20:04:25 +1300
Subject: [PATCH 10/10] Bump to java8-parent, update to Java8 LongAdder
---
pom.xml | 32 +-
.../autotune/service/ProfileOriginQuery.java | 2 +-
.../server/cache/DefaultServerCache.java | 4 +-
.../core/CObjectGraphNodeStatistics.java | 2 +-
.../server/query/CQueryPlanStats.java | 20 +-
.../ebeaninternal/server/util/LongAdder.java | 201 ----------
.../server/util/LongMaxUpdater.java | 184 ----------
.../ebeaninternal/server/util/Stripped64.java | 342 ------------------
8 files changed, 17 insertions(+), 770 deletions(-)
delete mode 100644 src/main/java/com/avaje/ebeaninternal/server/util/LongAdder.java
delete mode 100644 src/main/java/com/avaje/ebeaninternal/server/util/LongMaxUpdater.java
delete mode 100644 src/main/java/com/avaje/ebeaninternal/server/util/Stripped64.java
diff --git a/pom.xml b/pom.xml
index 28515cd59..485139656 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,13 +3,13 @@
org.avaje
- oss-parent
+ java8-parent
1.1
org.avaje.ebean
ebean
- 8.8.2-SNAPSHOT
+ 9.1.1-SNAPSHOT
jar
ebean
@@ -19,22 +19,6 @@
UTF-8
-
-
- The Apache Software License, Version 2.0
- http://www.apache.org/licenses/LICENSE-2.0.txt
- repo
-
-
-
-
-
- rbygrave
- Rob Bygrave
- robin.bygrave@gmail.com
-
-
-
scm:git:https://github.com/ebean-orm/ebean.git
HEAD
@@ -236,16 +220,6 @@
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.2
-
- 1.6
- 1.6
-
-
-
org.avaje.ebean
ebean-maven-plugin
@@ -303,7 +277,7 @@
maven-javadoc-plugin
2.9.1
- Ebean 8
+ Ebean 9
src/main/java/com/avaje/ebean/overview.html
1.8
org.avaje.doclet.PygmentsDoclet
diff --git a/src/main/java/com/avaje/ebeaninternal/server/autotune/service/ProfileOriginQuery.java b/src/main/java/com/avaje/ebeaninternal/server/autotune/service/ProfileOriginQuery.java
index 4c1c2044e..b0a938393 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/autotune/service/ProfileOriginQuery.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/autotune/service/ProfileOriginQuery.java
@@ -1,9 +1,9 @@
package com.avaje.ebeaninternal.server.autotune.service;
import com.avaje.ebeaninternal.server.autotune.AutoTuneCollection;
-import com.avaje.ebeaninternal.server.util.LongAdder;
import java.io.Serializable;
+import java.util.concurrent.atomic.LongAdder;
/**
* Used to accumulate query execution statistics for paths relative to the origin query.
diff --git a/src/main/java/com/avaje/ebeaninternal/server/cache/DefaultServerCache.java b/src/main/java/com/avaje/ebeaninternal/server/cache/DefaultServerCache.java
index f6444b840..8a5dc8a32 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/cache/DefaultServerCache.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/cache/DefaultServerCache.java
@@ -4,7 +4,7 @@ import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.cache.ServerCache;
import com.avaje.ebean.cache.ServerCacheOptions;
import com.avaje.ebean.cache.ServerCacheStatistics;
-import com.avaje.ebeaninternal.server.util.LongAdder;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -16,6 +16,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
/**
* The default cache implementation.
@@ -38,7 +39,6 @@ public class DefaultServerCache implements ServerCache {
*/
protected final Map