diff --git a/src/main/java/com/avaje/ebean/config/DbTypeConfig.java b/src/main/java/com/avaje/ebean/config/DbTypeConfig.java new file mode 100644 index 000000000..64c45ade4 --- /dev/null +++ b/src/main/java/com/avaje/ebean/config/DbTypeConfig.java @@ -0,0 +1,123 @@ +package com.avaje.ebean.config; + +import com.avaje.ebean.config.dbplatform.DbType; +import com.avaje.ebean.config.dbplatform.IdType; + +import java.util.ArrayList; +import java.util.List; + +/** + * Configuration for DB types such as UUID, Geometry etc. + */ +public class DbTypeConfig { + + /** + * The Geometry SRID value (default 4326). + */ + private int geometrySRID = 4326; + + /** + * Set for DB's that support both Sequence and Identity (and the default choice is not desired). + */ + private IdType idType; + + /** + * Setting to indicate if UUID should be stored as binary(16) or varchar(40) or native DB type (for H2 and Postgres). + */ + private ServerConfig.DbUuid dbUuid = ServerConfig.DbUuid.AUTO_VARCHAR; + + /** + * Modify the default mapping of standard types such as default precision for DECIMAL etc. + */ + private List customDbTypeMappings = new ArrayList<>(); + + /** + * Return the Geometry SRID. + */ + public int getGeometrySRID() { + return geometrySRID; + } + + /** + * Set the Geometry SRID. + */ + public void setGeometrySRID(int geometrySRID) { + this.geometrySRID = geometrySRID; + } + + /** + * Return the DB type used to store UUID. + */ + public ServerConfig.DbUuid getDbUuid() { + return dbUuid; + } + + /** + * Set the DB type used to store UUID. + */ + public void setDbUuid(ServerConfig.DbUuid dbUuid) { + this.dbUuid = dbUuid; + } + + /** + * Return the IdType to use (or null for the default choice). + */ + public IdType getIdType() { + return idType; + } + + /** + * Set the IdType to use (when the DB supports both SEQUENCE and IDENTITY and the default is not desired). + */ + public void setIdType(IdType idType) { + this.idType = idType; + } + + /** + * Add a custom type mapping. + *

+ *

{@code
+   *
+   *   // set the default mapping for BigDecimal.class/decimal
+   *   serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
+   *
+   *   // set the default mapping for String.class/varchar but only for Postgres
+   *   serverConfig.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES);
+   *
+   * }
+ * + * @param type The DB type this mapping should apply to + * @param columnDefinition The column definition that should be used + * @param platform Optionally specify the platform this mapping should apply to. + */ + public void addCustomMapping(DbType type, String columnDefinition, Platform platform) { + customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition, platform)); + } + + /** + * Add a custom type mapping that applies to all platforms. + *

+ *

{@code
+   *
+   *   // set the default mapping for BigDecimal/decimal
+   *   serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
+   *
+   *   // set the default mapping for String/varchar
+   *   serverConfig.addCustomMapping(DbType.VARCHAR, "text");
+   *
+   * }
+ * + * @param type The DB type this mapping should apply to + * @param columnDefinition The column definition that should be used + */ + public void addCustomMapping(DbType type, String columnDefinition) { + customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition)); + } + + /** + * Return the list of custom type mappings. + */ + public List getCustomTypeMappings() { + return customDbTypeMappings; + } +} diff --git a/src/main/java/com/avaje/ebean/config/ServerConfig.java b/src/main/java/com/avaje/ebean/config/ServerConfig.java index 7ca2590ea..7bc138f82 100644 --- a/src/main/java/com/avaje/ebean/config/ServerConfig.java +++ b/src/main/java/com/avaje/ebean/config/ServerConfig.java @@ -91,8 +91,6 @@ public class ServerConfig { private ContainerConfig containerConfig; - private List customDbTypeMappings = new ArrayList<>(); - /** * The underlying properties that were used during configuration. */ @@ -118,11 +116,6 @@ public class ServerConfig { */ private boolean disableClasspathSearch; - /** - * The Geometry SRID value (default 4326). - */ - private int geometrySRID = 4326; - /** * List of interesting classes such as entities, embedded, ScalarTypes, * Listeners, Finders, Controllers etc. @@ -332,10 +325,9 @@ public class ServerConfig { private boolean updatesDeleteMissingChildren = true; /** - * Setting to indicate if UUID should be stored as binary(16) or varchar(40) or native DB type (for H2 and Postgres). + * Database type configuration. */ - private DbUuid dbUuid = DbUuid.AUTO_VARCHAR; - + private DbTypeConfig dbTypeConfig = new DbTypeConfig(); private List idGenerators = new ArrayList<>(); private List findControllers = new ArrayList<>(); @@ -912,14 +904,14 @@ public class ServerConfig { * Return the Geometry SRID. */ public int getGeometrySRID() { - return geometrySRID; + return dbTypeConfig.getGeometrySRID(); } /** * Set the Geometry SRID. */ public void setGeometrySRID(int geometrySRID) { - this.geometrySRID = geometrySRID; + dbTypeConfig.setGeometrySRID(geometrySRID); } /** @@ -1568,17 +1560,17 @@ public class ServerConfig { } /** - * Return the DB type used to store UUID. + * Return the configuration for DB types (such as UUID and custom mappings). */ - public DbUuid getDbUuid() { - return dbUuid; + public DbTypeConfig getDbTypeConfig() { + return dbTypeConfig; } /** * Set the DB type used to store UUID. */ public void setDbUuid(DbUuid dbUuid) { - this.dbUuid = dbUuid; + this.dbTypeConfig.setDbUuid(dbUuid); } /** @@ -2006,7 +1998,7 @@ public class ServerConfig { * @param platform Optionally specify the platform this mapping should apply to. */ public void addCustomMapping(DbType type, String columnDefinition, Platform platform) { - customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition, platform)); + dbTypeConfig.addCustomMapping(type, columnDefinition, platform); } /** @@ -2026,14 +2018,7 @@ public class ServerConfig { * @param columnDefinition The column definition that should be used */ public void addCustomMapping(DbType type, String columnDefinition) { - customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition)); - } - - /** - * Return the list of custom type mappings. - */ - public List getCustomTypeMappings() { - return customDbTypeMappings; + dbTypeConfig.addCustomMapping(type, columnDefinition); } /** @@ -2414,7 +2399,11 @@ public class ServerConfig { } loadDocStoreSettings(p); - geometrySRID = p.getInt("geometrySRID", geometrySRID); + int srid = p.getInt("geometrySRID", 0); + if (srid > 0) { + dbTypeConfig.setGeometrySRID(srid); + } + disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache); explicitTransactionBeginMode = p.getBoolean("explicitTransactionBeginMode", explicitTransactionBeginMode); autoCommitMode = p.getBoolean("autoCommitMode", autoCommitMode); @@ -2474,9 +2463,13 @@ public class ServerConfig { databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue); databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse); databasePlatformName = p.get("databasePlatformName", databasePlatformName); - dbUuid = p.getEnum(DbUuid.class, "dbuuid", dbUuid); + + DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null); + if (dbUuid != null) { + dbTypeConfig.setDbUuid(dbUuid); + } if (p.getBoolean("uuidStoreAsBinary", false)) { - dbUuid = DbUuid.BINARY; + dbTypeConfig.setDbUuid(DbUuid.BINARY); } localTimeWithNanos = p.getBoolean("localTimeWithNanos", localTimeWithNanos); jodaLocalTimeMode = p.get("jodaLocalTimeMode", jodaLocalTimeMode); 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 97671b6ed..951f0fb53 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java @@ -3,6 +3,7 @@ package com.avaje.ebean.config.dbplatform; import com.avaje.ebean.BackgroundExecutor; import com.avaje.ebean.Query; import com.avaje.ebean.config.CustomDbTypeMapping; +import com.avaje.ebean.config.DbTypeConfig; import com.avaje.ebean.config.PersistBatch; import com.avaje.ebean.config.Platform; import com.avaje.ebean.config.ServerConfig; @@ -180,15 +181,27 @@ public class DatabasePlatform { /** * Configure UUID Storage etc based on ServerConfig settings. */ - public void configure(ServerConfig serverConfig) { - dbTypeMap.config(nativeUuidType, serverConfig.getDbUuid()); - for (CustomDbTypeMapping mapping : serverConfig.getCustomTypeMappings()) { + public void configure(DbTypeConfig config) { + addGeoTypes(config.getGeometrySRID()); + configureIdType(config.getIdType()); + dbTypeMap.config(nativeUuidType, config.getDbUuid()); + for (CustomDbTypeMapping mapping : config.getCustomTypeMappings()) { if (platformMatch(mapping.getPlatform())) { dbTypeMap.put(mapping.getType(), parse(mapping.getColumnDefinition())); } } } + protected void configureIdType(IdType idType) { + if (idType != null) { + this.dbIdentity.setIdType(idType); + } + } + + protected void addGeoTypes(int srid) { + // default has no geo type support + } + private DbPlatformType parse(String columnDefinition) { return DbPlatformType.parse(columnDefinition); } diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/DbPlatformTypeMapping.java b/src/main/java/com/avaje/ebean/config/dbplatform/DbPlatformTypeMapping.java index c2c2d791c..27b90996b 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/DbPlatformTypeMapping.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/DbPlatformTypeMapping.java @@ -103,7 +103,8 @@ public class DbPlatformTypeMapping { put(DbType.JSONCLOB, JSON_CLOB_PLACEHOLDER); put(DbType.JSONBLOB, JSON_BLOB_PLACEHOLDER); put(DbType.JSONVARCHAR, JSON_VARCHAR_PLACEHOLDER); - put(DbType.UUID, UUID_PLACEHOLDER); + // use reasonable default of varchar(40) - ideally set via DatabasePlatform.configure(DbTypeConfig) + put(DbType.UUID, get(DbType.VARCHAR).withLength(40)); } } diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java b/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java index 25ba2073d..a1e0949fe 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java @@ -30,20 +30,7 @@ public class H2Platform extends DatabasePlatform { // escape clause for now noting that backslash is an escape char for like in H2 this.likeClause = "like ?"; - // H2 data types match default JDBC types - // so no changes to dbTypeMap required - } - - @Override - public void configure(ServerConfig serverConfig) { - super.configure(serverConfig); - Properties properties = serverConfig.getProperties(); - if (properties != null) { - String idType = properties.getProperty("ebean.h2.idtype"); - if (idType != null) { - this.dbIdentity.setIdType(IdType.valueOf(idType)); - } - } + dbTypeMap.put(DbType.UUID, new DbPlatformType("uuid", false)); } /** diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java index 18aa77446..97a6323ec 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java @@ -7,7 +7,6 @@ import com.avaje.ebean.dbmigration.ddlgeneration.platform.PostgresDdl; import javax.sql.DataSource; import java.sql.Types; -import java.util.Properties; /** * Postgres v9 specific platform. @@ -44,6 +43,7 @@ public class PostgresPlatform extends DatabasePlatform { DbPlatformType dbTypeText = new DbPlatformType("text"); DbPlatformType dbBytea = new DbPlatformType("bytea", false); + dbTypeMap.put(DbType.UUID, new DbPlatformType("uuid", false)); dbTypeMap.put(DbType.HSTORE, new DbPlatformType("hstore", false)); dbTypeMap.put(DbType.JSON, new DbPlatformType("json", false)); dbTypeMap.put(DbType.JSONB, new DbPlatformType("jsonb", false)); @@ -63,21 +63,7 @@ public class PostgresPlatform extends DatabasePlatform { dbTypeMap.put(DbType.LONGVARCHAR, dbTypeText); } - @Override - public void configure(ServerConfig serverConfig) { - super.configure(serverConfig); - Properties properties = serverConfig.getProperties(); - if (properties != null) { - String tsType = properties.getProperty("ebean.postgres.timestamp"); - if (tsType != null) { - // set timestamp type to "timestamp" without time zone - dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType(tsType)); - } - } - addGeoTypes(serverConfig.getGeometrySRID()); - } - - private void addGeoTypes(int srid) { + protected void addGeoTypes(int srid) { dbTypeMap.put(DbType.POINT, geoType("point",srid)); dbTypeMap.put(DbType.POLYGON, geoType("polygon",srid)); dbTypeMap.put(DbType.LINESTRING, geoType("linestring",srid)); diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java index 38e781d70..e6c9df9dd 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java @@ -238,7 +238,7 @@ public class DefaultContainer implements SpiContainer { if (dbPlatform == null) { DatabasePlatformFactory factory = new DatabasePlatformFactory(); DatabasePlatform db = factory.create(config); - db.configure(config); + db.configure(config.getDbTypeConfig()); config.setDatabasePlatform(db); logger.info("DatabasePlatform name:{} platform:{}", config.getName(), db.getName()); } 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 ef5753f74..3aed66650 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java @@ -1013,7 +1013,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable { nativeMap.put(Types.BIT, booleanType); } - ServerConfig.DbUuid dbUuid = config.getDbUuid(); + ServerConfig.DbUuid dbUuid = config.getDbTypeConfig().getDbUuid(); if (offlineMigrationGeneration || (databasePlatform.isNativeUuidType() && dbUuid.useNativeType())) { typeMap.put(UUID.class, new ScalarTypeUUIDNative()); diff --git a/src/test/java/com/avaje/ebean/config/ServerConfigTest.java b/src/test/java/com/avaje/ebean/config/ServerConfigTest.java index 01c1b4029..9b95de0e7 100644 --- a/src/test/java/com/avaje/ebean/config/ServerConfigTest.java +++ b/src/test/java/com/avaje/ebean/config/ServerConfigTest.java @@ -8,7 +8,6 @@ import static org.junit.Assert.*; public class ServerConfigTest { - @Test public void testLoadFromEbeanProperties() { @@ -41,7 +40,7 @@ public class ServerConfigTest { assertTrue(serverConfig.isH2ProductionMode()); assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatch()); assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatchOnCascade()); - assertEquals(ServerConfig.DbUuid.BINARY, serverConfig.getDbUuid()); + assertEquals(ServerConfig.DbUuid.BINARY, serverConfig.getDbTypeConfig().getDbUuid()); assertEquals(42, serverConfig.getJdbcFetchSizeFindEach()); assertEquals(43, serverConfig.getJdbcFetchSizeFindList()); assertEquals(4, serverConfig.getBackgroundExecutorSchedulePoolSize()); @@ -60,4 +59,4 @@ public class ServerConfigTest { assertEquals(PersistBatch.ALL, serverConfig.getPersistBatch()); assertEquals(PersistBatch.ALL, serverConfig.getPersistBatchOnCascade()); } -} \ No newline at end of file +} diff --git a/src/test/java/com/avaje/ebean/config/dbplatform/DatabasePlatformTest.java b/src/test/java/com/avaje/ebean/config/dbplatform/DatabasePlatformTest.java index 923834382..e185b7413 100644 --- a/src/test/java/com/avaje/ebean/config/dbplatform/DatabasePlatformTest.java +++ b/src/test/java/com/avaje/ebean/config/dbplatform/DatabasePlatformTest.java @@ -1,10 +1,10 @@ package com.avaje.ebean.config.dbplatform; +import com.avaje.ebean.config.DbTypeConfig; import com.avaje.ebean.config.Platform; -import com.avaje.ebean.config.ServerConfig; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class DatabasePlatformTest { @@ -19,19 +19,19 @@ public class DatabasePlatformTest { @Test public void configure_customType() throws Exception { - ServerConfig serverConfig = new ServerConfig(); - serverConfig.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES); - serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(24,4)"); + DbTypeConfig config = new DbTypeConfig(); + config.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES); + config.addCustomMapping(DbType.DECIMAL, "decimal(24,4)"); // PG renders custom decimal and varchar PostgresPlatform pgPlatform = new PostgresPlatform(); - pgPlatform.configure(serverConfig); + pgPlatform.configure(config); assertEquals(defaultDecimalDefn(pgPlatform), "decimal(24,4)"); assertEquals(defaultDefn(DbType.VARCHAR, pgPlatform), "text"); // H2 only renders custom decimal H2Platform h2Platform = new H2Platform(); - h2Platform.configure(serverConfig); + h2Platform.configure(config); assertEquals(defaultDecimalDefn(h2Platform), "decimal(24,4)"); assertEquals(defaultDefn(DbType.VARCHAR, h2Platform), "varchar(255)"); } @@ -43,4 +43,4 @@ public class DatabasePlatformTest { private String defaultDefn(DbType type, DatabasePlatform dbPlatform) { return dbPlatform.getDbTypeMap().get(type).renderType(0, 0); } -} \ No newline at end of file +} diff --git a/src/test/java/com/avaje/ebean/config/dbplatform/MySqlPlatformTest.java b/src/test/java/com/avaje/ebean/config/dbplatform/MySqlPlatformTest.java index bbf77fa0c..df2c16960 100644 --- a/src/test/java/com/avaje/ebean/config/dbplatform/MySqlPlatformTest.java +++ b/src/test/java/com/avaje/ebean/config/dbplatform/MySqlPlatformTest.java @@ -1,5 +1,6 @@ package com.avaje.ebean.config.dbplatform; +import com.avaje.ebean.config.DbTypeConfig; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl; import org.junit.Test; @@ -25,7 +26,7 @@ public class MySqlPlatformTest { public void uuid_default() { MySqlPlatform platform = new MySqlPlatform(); - platform.configure(new ServerConfig()); + platform.configure(new DbTypeConfig()); DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID); assertThat(dbType.renderType(0, 0)).isEqualTo("varchar(40)"); @@ -36,12 +37,12 @@ public class MySqlPlatformTest { public void uuid_as_binary() { MySqlPlatform platform = new MySqlPlatform(); - ServerConfig serverConfig = new ServerConfig(); - serverConfig.setDbUuid(ServerConfig.DbUuid.AUTO_BINARY); - platform.configure(serverConfig); + DbTypeConfig config = new DbTypeConfig(); + config.setDbUuid(ServerConfig.DbUuid.AUTO_BINARY); + platform.configure(config); DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID); assertThat(dbType.renderType(0, 0)).isEqualTo("binary(16)"); } -} \ No newline at end of file +} diff --git a/src/test/java/com/avaje/ebean/config/dbplatform/OraclePlatformTest.java b/src/test/java/com/avaje/ebean/config/dbplatform/OraclePlatformTest.java index 5fd5c9fe7..3633fc2e0 100644 --- a/src/test/java/com/avaje/ebean/config/dbplatform/OraclePlatformTest.java +++ b/src/test/java/com/avaje/ebean/config/dbplatform/OraclePlatformTest.java @@ -1,5 +1,6 @@ package com.avaje.ebean.config.dbplatform; +import com.avaje.ebean.config.DbTypeConfig; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl; import org.junit.Test; @@ -34,7 +35,7 @@ public class OraclePlatformTest { public void uuid_default() { OraclePlatform platform = new OraclePlatform(); - platform.configure(new ServerConfig()); + platform.configure(new DbTypeConfig()); DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID); assertThat(dbType.renderType(0, 0)).isEqualTo("varchar2(40)"); @@ -45,12 +46,12 @@ public class OraclePlatformTest { public void uuid_as_binary() { OraclePlatform platform = new OraclePlatform(); - ServerConfig serverConfig = new ServerConfig(); - serverConfig.setDbUuid(ServerConfig.DbUuid.AUTO_BINARY); + DbTypeConfig config = new DbTypeConfig(); + config.setDbUuid(ServerConfig.DbUuid.AUTO_BINARY); - platform.configure(serverConfig); + platform.configure(config); DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID); assertThat(dbType.renderType(0, 0)).isEqualTo("raw(16)"); } -} \ No newline at end of file +} diff --git a/src/test/java/com/avaje/ebean/config/dbplatform/PostgresPlatformTest.java b/src/test/java/com/avaje/ebean/config/dbplatform/PostgresPlatformTest.java index 41577423f..9078e53f2 100644 --- a/src/test/java/com/avaje/ebean/config/dbplatform/PostgresPlatformTest.java +++ b/src/test/java/com/avaje/ebean/config/dbplatform/PostgresPlatformTest.java @@ -1,6 +1,6 @@ package com.avaje.ebean.config.dbplatform; -import com.avaje.ebean.config.ServerConfig; +import com.avaje.ebean.config.DbTypeConfig; import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl; import org.junit.Test; @@ -36,7 +36,7 @@ public class PostgresPlatformTest { public void testUuidType() { PostgresPlatform platform = new PostgresPlatform(); - platform.configure(new ServerConfig()); + platform.configure(new DbTypeConfig()); DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID); String columnDefn = dbType.renderType(0, 0); @@ -44,4 +44,4 @@ public class PostgresPlatformTest { assertThat(columnDefn).isEqualTo("uuid"); } -} \ No newline at end of file +}