#1342 - Refactor and rename DbTypeConfig to Platform config to support multi-platform db migration

This commit is contained in:
Rob Bygrave
2018-03-08 23:23:50 +13:00
parent 4f327c2751
commit 2042bdf29a
21 changed files with 491 additions and 342 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>11.14.4-SNAPSHOT</version>
<version>11.15.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ebean</name>
@@ -1,124 +0,0 @@
package io.ebean.config;
import io.ebean.config.dbplatform.DbType;
import io.ebean.config.dbplatform.IdType;
import io.ebean.annotation.Platform;
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<CustomDbTypeMapping> 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.
* <p>
* <pre>{@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);
*
* }</pre>
*
* @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.
* <p>
* <pre>{@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");
*
* }</pre>
*
* @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<CustomDbTypeMapping> getCustomTypeMappings() {
return customDbTypeMappings;
}
}
@@ -0,0 +1,335 @@
package io.ebean.config;
import io.ebean.annotation.Platform;
import io.ebean.config.dbplatform.DbType;
import io.ebean.config.dbplatform.IdType;
import io.ebean.util.StringHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Configuration for DB types such as UUID, Geometry etc.
*/
public class PlatformConfig {
private boolean allQuotedIdentifiers;
/**
* The database boolean true value (typically either 1, T, or Y).
*/
private String databaseBooleanTrue;
/**
* The database boolean false value (typically either 0, F or N).
*/
private String databaseBooleanFalse;
/**
* For DB's using sequences this is the number of sequence values prefetched.
*/
private int databaseSequenceBatchSize = 20;
/**
* Set for DB's that support both Sequence and Identity (and the default choice is not desired).
*/
private IdType idType;
/**
* The Geometry SRID value (default 4326).
*/
private int geometrySRID = 4326;
/**
* Setting to indicate if UUID should be stored as binary(16) or varchar(40) or native DB type (for H2 and Postgres).
*/
private DbUuid dbUuid = DbUuid.AUTO_VARCHAR;
/**
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
*/
private List<CustomDbTypeMapping> customDbTypeMappings = new ArrayList<>();
/**
* Construct with defaults.
*/
public PlatformConfig() {
}
/**
* Construct based on given config - typically for DbMigration generation with many platforms.
*/
public PlatformConfig(PlatformConfig platformConfig) {
this.databaseBooleanFalse = platformConfig.databaseBooleanFalse;
this.databaseBooleanTrue = platformConfig.databaseBooleanTrue;
this.databaseSequenceBatchSize = platformConfig.databaseSequenceBatchSize;
this.idType = platformConfig.idType;
this.geometrySRID = platformConfig.geometrySRID;
this.dbUuid = platformConfig.dbUuid;
}
/**
* Return true if all DB column and table names should use quoted identifiers.
*/
public boolean isAllQuotedIdentifiers() {
return allQuotedIdentifiers;
}
/**
* Set to true if all DB column and table names should use quoted identifiers.
*/
public void setAllQuotedIdentifiers(boolean allQuotedIdentifiers) {
this.allQuotedIdentifiers = allQuotedIdentifiers;
}
/**
* Return a value used to represent TRUE in the database.
* <p>
* This is used for databases that do not support boolean natively.
* </p>
* <p>
* The value returned is either a Integer or a String (e.g. "1", or "T").
* </p>
*/
public String getDatabaseBooleanTrue() {
return databaseBooleanTrue;
}
/**
* Set the value to represent TRUE in the database.
* <p>
* This is used for databases that do not support boolean natively.
* </p>
* <p>
* The value set is either a Integer or a String (e.g. "1", or "T").
* </p>
*/
public void setDatabaseBooleanTrue(String databaseBooleanTrue) {
this.databaseBooleanTrue = databaseBooleanTrue;
}
/**
* Return a value used to represent FALSE in the database.
*/
public String getDatabaseBooleanFalse() {
return databaseBooleanFalse;
}
/**
* Set the value used to represent FALSE in the database.
*/
public void setDatabaseBooleanFalse(String databaseBooleanFalse) {
this.databaseBooleanFalse = databaseBooleanFalse;
}
/**
* Return the number of DB sequence values that should be preallocated.
*/
public int getDatabaseSequenceBatchSize() {
return databaseSequenceBatchSize;
}
/**
* Set the number of DB sequence values that should be preallocated.
*/
public void setDatabaseSequenceBatchSize(int databaseSequenceBatchSize) {
this.databaseSequenceBatchSize = databaseSequenceBatchSize;
}
/**
* 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 DbUuid getDbUuid() {
return dbUuid;
}
/**
* Set the DB type used to store UUID.
*/
public void setDbUuid(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.
* <p>
* <pre>{@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);
*
* }</pre>
*
* @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.
* <p>
* <pre>{@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");
*
* }</pre>
*
* @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<CustomDbTypeMapping> getCustomTypeMappings() {
return customDbTypeMappings;
}
public void loadSettings(PropertiesWrapper p) {
idType = p.getEnum(IdType.class, "idType", idType);
databaseSequenceBatchSize = p.getInt("databaseSequenceBatchSize", databaseSequenceBatchSize);
databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue);
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
if (dbUuid != null) {
setDbUuid(dbUuid);
}
if (p.getBoolean("uuidStoreAsBinary", false)) {
setDbUuid(DbUuid.BINARY);
}
int srid = p.getInt("geometrySRID", 0);
if (srid > 0) {
setGeometrySRID(srid);
}
// Mapping is specified in the form: BOOLEAN=int(1);BIT=int(1);
String mapping = p.get("mapping");
if (mapping != null && !mapping.isEmpty()) {
Map<String, String> map = StringHelper.delimitedToMap(mapping, ";", "=");
for (Entry<String, String> entry : map.entrySet()) {
addCustomMapping(DbType.valueOf(entry.getKey()), entry.getValue());
}
}
boolean quotedIdentifiers = p.getBoolean("allQuotedIdentifiers", allQuotedIdentifiers);
if (quotedIdentifiers != allQuotedIdentifiers) {
// potentially also set to use matching naming convention
setAllQuotedIdentifiers(quotedIdentifiers);
}
}
/**
* Specify how UUID is stored.
*/
public enum DbUuid {
/**
* Store using native UUID in H2 and Postgres and otherwise fallback to VARCHAR(40).
*/
AUTO_VARCHAR(true, false, false),
/**
* Store using native UUID in H2 and Postgres and otherwise fallback to BINARY(16).
*/
AUTO_BINARY(true, true, false),
/**
* Store using native UUID in H2 and Postgres and otherwise fallback to BINARY(16) with optimized packing.
*/
AUTO_BINARY_OPTIMIZED(true, true, true),
/**
* Store using DB VARCHAR(40).
*/
VARCHAR(false, false, false),
/**
* Store using DB BINARY(16).
*/
BINARY(false, true, false),
/**
* Store using DB BINARY(16).
*/
BINARY_OPTIMIZED(false, true, true);
boolean nativeType;
boolean binary;
boolean binaryOptimized;
DbUuid(boolean nativeType, boolean binary, boolean binaryOptimized) {
this.nativeType = nativeType;
this.binary = binary;
this.binaryOptimized = binaryOptimized;
}
/**
* Return true if native UUID type is preferred.
*/
public boolean useNativeType() {
return nativeType;
}
/**
* Return true if BINARY(16) storage is preferred over VARCHAR(40).
*/
public boolean useBinary() {
return binary;
}
/**
* Return true, if optimized packing should be used.
*/
public boolean useBinaryOptimized() {
return binaryOptimized;
}
}
}
@@ -10,20 +10,23 @@ public class PropertiesWrapper {
protected final String serverName;
private final ClassLoadConfig classLoadConfig;
/**
* Construct with a prefix, serverName and properties.
*/
public PropertiesWrapper(String prefix, String serverName, Properties properties) {
public PropertiesWrapper(String prefix, String serverName, Properties properties, ClassLoadConfig classLoadConfig) {
this.serverName = serverName;
this.prefix = prefix;
this.properties = properties;
this.classLoadConfig = classLoadConfig;
}
/**
* Construct without prefix of serverName.
*/
public PropertiesWrapper(Properties properties) {
this(null, null, properties);
public PropertiesWrapper(Properties properties, ClassLoadConfig classLoadConfig) {
this(null, null, properties, classLoadConfig);
}
/**
@@ -115,4 +118,30 @@ public class PropertiesWrapper {
return (level == null) ? defaultValue : Enum.valueOf(enumType, level.toUpperCase());
}
/**
* Return the instance to use (can be null) for the given plugin.
*
* @param pluginType the type of plugin
* @param key properties key
* @param instance existing instance
*/
public <T> T createInstance(Class<T> pluginType, String key, T instance) {
if (instance != null) {
return instance;
}
String classname = get(key, null);
return createInstance(pluginType, classname);
}
/**
* Return the instance to use (can be null) for the given plugin.
*
* @param pluginType the type of plugin
* @param classname the implementation class as per properties
*/
@SuppressWarnings("unchecked")
public <T> T createInstance(Class<T> pluginType, String classname) {
return classname == null ? null : (T) classLoadConfig.newInstance(classname);
}
}
+65 -169
View File
@@ -183,16 +183,6 @@ public class ServerConfig {
*/
private DatabasePlatform databasePlatform;
/**
* The preferred IdType (to override the default Platform type).
*/
private IdType idType;
/**
* For DB's using sequences this is the number of sequence values prefetched.
*/
private int databaseSequenceBatchSize = 20;
/**
* JDBC fetchSize hint when using findList. Defaults to 0 leaving it up to the JDBC driver.
*/
@@ -330,18 +320,6 @@ public class ServerConfig {
*/
private String dataSourceJndiName;
/**
* The database boolean true value (typically either 1, T, or Y).
*/
private String databaseBooleanTrue;
/**
* The database boolean false value (typically either 0, F or N).
*/
private String databaseBooleanFalse;
private boolean allQuotedIdentifiers;
/**
* The naming convention.
*/
@@ -368,9 +346,9 @@ public class ServerConfig {
private boolean updatesDeleteMissingChildren = true;
/**
* Database type configuration.
* Database platform configuration.
*/
private DbTypeConfig dbTypeConfig = new DbTypeConfig();
private PlatformConfig platformConfig = new PlatformConfig();
/**
* The UUID version to use.
@@ -946,7 +924,7 @@ public class ServerConfig {
* </p>
*/
public void setDatabaseSequenceBatchSize(int databaseSequenceBatchSize) {
this.databaseSequenceBatchSize = databaseSequenceBatchSize;
platformConfig.setDatabaseSequenceBatchSize(databaseSequenceBatchSize);
}
/**
@@ -1128,14 +1106,14 @@ public class ServerConfig {
* Return the Geometry SRID.
*/
public int getGeometrySRID() {
return dbTypeConfig.getGeometrySRID();
return platformConfig.getGeometrySRID();
}
/**
* Set the Geometry SRID.
*/
public void setGeometrySRID(int geometrySRID) {
dbTypeConfig.setGeometrySRID(geometrySRID);
platformConfig.setGeometrySRID(geometrySRID);
}
/**
@@ -1425,15 +1403,21 @@ public class ServerConfig {
* Return true if all DB column and table names should use quoted identifiers.
*/
public boolean isAllQuotedIdentifiers() {
return allQuotedIdentifiers;
return platformConfig.isAllQuotedIdentifiers();
}
/**
* Set to true if all DB column and table names should use quoted identifiers.
*/
public void setAllQuotedIdentifiers(boolean allQuotedIdentifiers) {
this.allQuotedIdentifiers = allQuotedIdentifiers;
if (allQuotedIdentifiers && namingConvention instanceof UnderscoreNamingConvention) {
platformConfig.setAllQuotedIdentifiers(allQuotedIdentifiers);
if (allQuotedIdentifiers) {
adjustNamingConventionForAllQuoted();
}
}
private void adjustNamingConventionForAllQuoted() {
if (namingConvention instanceof UnderscoreNamingConvention) {
// we need to use matching naming convention
this.namingConvention = new MatchingNamingConvention();
}
@@ -1648,7 +1632,7 @@ public class ServerConfig {
* </p>
*/
public String getDatabaseBooleanTrue() {
return databaseBooleanTrue;
return platformConfig.getDatabaseBooleanTrue();
}
/**
@@ -1661,7 +1645,7 @@ public class ServerConfig {
* </p>
*/
public void setDatabaseBooleanTrue(String databaseTrue) {
this.databaseBooleanTrue = databaseTrue;
platformConfig.setDatabaseBooleanTrue(databaseTrue);
}
/**
@@ -1674,7 +1658,7 @@ public class ServerConfig {
* </p>
*/
public String getDatabaseBooleanFalse() {
return databaseBooleanFalse;
return platformConfig.getDatabaseBooleanFalse();
}
/**
@@ -1687,14 +1671,14 @@ public class ServerConfig {
* </p>
*/
public void setDatabaseBooleanFalse(String databaseFalse) {
this.databaseBooleanFalse = databaseFalse;
this.platformConfig.setDatabaseBooleanFalse(databaseFalse);
}
/**
* Return the number of DB sequence values that should be preallocated.
*/
public int getDatabaseSequenceBatchSize() {
return databaseSequenceBatchSize;
return platformConfig.getDatabaseSequenceBatchSize();
}
/**
@@ -1713,7 +1697,7 @@ public class ServerConfig {
* </p>
*/
public void setDatabaseSequenceBatch(int databaseSequenceBatchSize) {
this.databaseSequenceBatchSize = databaseSequenceBatchSize;
this.platformConfig.setDatabaseSequenceBatchSize(databaseSequenceBatchSize);
}
/**
@@ -1769,14 +1753,14 @@ public class ServerConfig {
* Return the preferred DB platform IdType.
*/
public IdType getIdType() {
return idType;
return platformConfig.getIdType();
}
/**
* Set the preferred DB platform IdType.
*/
public void setIdType(IdType idType) {
this.idType = idType;
this.platformConfig.setIdType(idType);
}
/**
@@ -1889,15 +1873,22 @@ public class ServerConfig {
/**
* Return the configuration for DB types (such as UUID and custom mappings).
*/
public DbTypeConfig getDbTypeConfig() {
return dbTypeConfig;
public PlatformConfig getPlatformConfig() {
return platformConfig;
}
/**
* Set the configuration for DB platform (such as UUID and custom mappings).
*/
public void setPlatformConfig(PlatformConfig platformConfig) {
this.platformConfig = platformConfig;
}
/**
* Set the DB type used to store UUID.
*/
public void setDbUuid(DbUuid dbUuid) {
this.dbTypeConfig.setDbUuid(dbUuid);
public void setDbUuid(PlatformConfig.DbUuid dbUuid) {
this.platformConfig.setDbUuid(dbUuid);
}
/**
@@ -2353,7 +2344,7 @@ public class ServerConfig {
* @param platform Optionally specify the platform this mapping should apply to.
*/
public void addCustomMapping(DbType type, String columnDefinition, Platform platform) {
dbTypeConfig.addCustomMapping(type, columnDefinition, platform);
platformConfig.addCustomMapping(type, columnDefinition, platform);
}
/**
@@ -2373,7 +2364,7 @@ public class ServerConfig {
* @param columnDefinition The column definition that should be used
*/
public void addCustomMapping(DbType type, String columnDefinition) {
dbTypeConfig.addCustomMapping(type, columnDefinition);
platformConfig.addCustomMapping(type, columnDefinition);
}
/**
@@ -2660,7 +2651,7 @@ public class ServerConfig {
*/
private void configureFromProperties() {
autoConfiguration();
PropertiesWrapper p = new PropertiesWrapper("ebean", name, properties);
PropertiesWrapper p = new PropertiesWrapper("ebean", name, properties, classLoadConfig);
loadSettings(p);
}
@@ -2695,34 +2686,6 @@ public class ServerConfig {
return properties;
}
/**
* Return the instance to use (can be null) for the given plugin.
*
* @param properties the properties
* @param pluginType the type of plugin
* @param key properties key
* @param instance existing instance
*/
protected <T> T createInstance(PropertiesWrapper properties, Class<T> pluginType, String key, T instance) {
if (instance != null) {
return instance;
}
String classname = properties.get(key, null);
return createInstance(pluginType, classname);
}
/**
* Return the instance to use (can be null) for the given plugin.
*
* @param pluginType the type of plugin
* @param classname the implementation class as per properties
*/
@SuppressWarnings("unchecked")
protected <T> T createInstance(Class<T> pluginType, String classname) {
return classname == null ? null : (T) classLoadConfig.newInstance(classname);
}
/**
* loads the data source settings to preserve existing behaviour. IMHO, if someone has set the datasource config already,
* they don't want the settings to be reloaded and reset. This allows a descending class to override this behaviour and prevent it
@@ -2756,11 +2719,9 @@ public class ServerConfig {
profilingConfig.loadSettings(p, name);
migrationConfig.loadSettings(p, name);
boolean quotedIdentifiers = p.getBoolean("allQuotedIdentifiers", allQuotedIdentifiers);
if (quotedIdentifiers != allQuotedIdentifiers) {
// potentially also set to use matching naming convention
setAllQuotedIdentifiers(quotedIdentifiers);
platformConfig.loadSettings(p);
if (platformConfig.isAllQuotedIdentifiers()) {
adjustNamingConventionForAllQuoted();
}
namingConvention = createNamingConvention(p, namingConvention);
if (namingConvention != null) {
@@ -2781,11 +2742,6 @@ public class ServerConfig {
}
loadDocStoreSettings(p);
int srid = p.getInt("geometrySRID", 0);
if (srid > 0) {
dbTypeConfig.setGeometrySRID(srid);
}
queryPlanTTLSeconds = p.getInt("queryPlanTTLSeconds", queryPlanTTLSeconds);
slowQueryMillis = p.getLong("slowQueryMillis", slowQueryMillis);
docStoreOnly = p.getBoolean("docStoreOnly", docStoreOnly);
@@ -2800,14 +2756,14 @@ public class ServerConfig {
backgroundExecutorSchedulePoolSize = p.getInt("backgroundExecutorSchedulePoolSize", backgroundExecutorSchedulePoolSize);
backgroundExecutorShutdownSecs = p.getInt("backgroundExecutorShutdownSecs", backgroundExecutorShutdownSecs);
disableClasspathSearch = p.getBoolean("disableClasspathSearch", disableClasspathSearch);
currentUserProvider = createInstance(p, CurrentUserProvider.class, "currentUserProvider", currentUserProvider);
databasePlatform = createInstance(p, DatabasePlatform.class, "databasePlatform", databasePlatform);
encryptKeyManager = createInstance(p, EncryptKeyManager.class, "encryptKeyManager", encryptKeyManager);
encryptDeployManager = createInstance(p, EncryptDeployManager.class, "encryptDeployManager", encryptDeployManager);
encryptor = createInstance(p, Encryptor.class, "encryptor", encryptor);
dbEncrypt = createInstance(p, DbEncrypt.class, "dbEncrypt", dbEncrypt);
currentUserProvider = p.createInstance(CurrentUserProvider.class, "currentUserProvider", currentUserProvider);
databasePlatform = p.createInstance(DatabasePlatform.class, "databasePlatform", databasePlatform);
encryptKeyManager = p.createInstance(EncryptKeyManager.class, "encryptKeyManager", encryptKeyManager);
encryptDeployManager = p.createInstance(EncryptDeployManager.class, "encryptDeployManager", encryptDeployManager);
encryptor = p.createInstance(Encryptor.class, "encryptor", encryptor);
dbEncrypt = p.createInstance(DbEncrypt.class, "dbEncrypt", dbEncrypt);
dbOffline = p.getBoolean("dbOffline", dbOffline);
serverCachePlugin = createInstance(p, ServerCachePlugin.class, "serverCachePlugin", serverCachePlugin);
serverCachePlugin = p.createInstance(ServerCachePlugin.class, "serverCachePlugin", serverCachePlugin);
if (packages != null) {
String packagesProp = p.get("search.packages", p.get("packages", null));
@@ -2828,7 +2784,6 @@ public class ServerConfig {
throw new IllegalArgumentException("Property 'batch.mode' or 'persistBatching' is being set but no longer used. Please change to use 'persistBatchMode'");
}
idType = p.getEnum(IdType.class, "idType", idType);
persistBatch = p.getEnum(PersistBatch.class, "persistBatch", persistBatch);
persistBatchOnCascade = p.getEnum(PersistBatch.class, "persistBatchOnCascade", persistBatchOnCascade);
@@ -2849,20 +2804,9 @@ public class ServerConfig {
dataSourceJndiName = p.get("dataSourceJndiName", dataSourceJndiName);
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
databaseSequenceBatchSize = p.getInt("databaseSequenceBatchSize", databaseSequenceBatchSize);
databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue);
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
defaultOrderById = p.getBoolean("defaultOrderById", defaultOrderById);
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
if (dbUuid != null) {
dbTypeConfig.setDbUuid(dbUuid);
}
if (p.getBoolean("uuidStoreAsBinary", false)) {
dbTypeConfig.setDbUuid(DbUuid.BINARY);
}
uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
uuidStateFile = p.get("uuidStateFile", uuidStateFile);
@@ -2898,16 +2842,15 @@ public class ServerConfig {
}
}
currentTenantProvider = createInstance(p, CurrentTenantProvider.class, "tenant.currentTenantProvider", currentTenantProvider);
tenantCatalogProvider = createInstance(p, TenantCatalogProvider.class, "tenant.catalogProvider", tenantCatalogProvider);
tenantSchemaProvider = createInstance(p, TenantSchemaProvider.class, "tenant.schemaProvider", tenantSchemaProvider);
currentTenantProvider = p.createInstance(CurrentTenantProvider.class, "tenant.currentTenantProvider", currentTenantProvider);
tenantCatalogProvider = p.createInstance(TenantCatalogProvider.class, "tenant.catalogProvider", tenantCatalogProvider);
tenantSchemaProvider = p.createInstance(TenantSchemaProvider.class, "tenant.schemaProvider", tenantSchemaProvider);
tenantPartitionColumn = p.get("tenant.partitionColumn", tenantPartitionColumn);
classes = getClasses(p);
}
private NamingConvention createNamingConvention(PropertiesWrapper properties, NamingConvention namingConvention) {
NamingConvention nc = createInstance(properties, NamingConvention.class, "namingconvention", null);
NamingConvention nc = properties.createInstance(NamingConvention.class, "namingconvention", null);
return (nc != null) ? nc : namingConvention;
}
@@ -3098,71 +3041,24 @@ public class ServerConfig {
}
/**
* Specify how UUID is stored.
* Create a new PlatformConfig based of the one held but with overridden properties by reading
* properties with the given path and prefix.
* <p>
* Typically used in Db Migration generation for many platform targets that might have different
* configuration for IdType, UUID, quoted identifiers etc.
* </p>
*
* @param propertiesPath The properties path used for loading and setting properties
* @param platformPrefix The prefix used for loading and setting properties
* @return A copy of the PlatformConfig with overridden properties
*/
public enum DbUuid {
public PlatformConfig newPlatformConfig(String propertiesPath, String platformPrefix) {
PropertiesWrapper p = new PropertiesWrapper(propertiesPath, platformPrefix, properties, classLoadConfig);
/**
* Store using native UUID in H2 and Postgres and otherwise fallback to VARCHAR(40).
*/
AUTO_VARCHAR(true, false, false),
/**
* Store using native UUID in H2 and Postgres and otherwise fallback to BINARY(16).
*/
AUTO_BINARY(true, true, false),
/**
* Store using native UUID in H2 and Postgres and otherwise fallback to BINARY(16) with optimized packing.
*/
AUTO_BINARY_OPTIMIZED(true, true, true),
/**
* Store using DB VARCHAR(40).
*/
VARCHAR(false, false, false),
/**
* Store using DB BINARY(16).
*/
BINARY(false, true, false),
/**
* Store using DB BINARY(16).
*/
BINARY_OPTIMIZED(false, true, true);
boolean nativeType;
boolean binary;
boolean binaryOptimized;
DbUuid(boolean nativeType, boolean binary, boolean binaryOptimized) {
this.nativeType = nativeType;
this.binary = binary;
this.binaryOptimized = binaryOptimized;
}
/**
* Return true if native UUID type is preferred.
*/
public boolean useNativeType() {
return nativeType;
}
/**
* Return true if BINARY(16) storage is preferred over VARCHAR(40).
*/
public boolean useBinary() {
return binary;
}
/**
* Return true, if optimized packing should be used.
*/
public boolean useBinaryOptimized() {
return binaryOptimized;
}
PlatformConfig config = new PlatformConfig(platformConfig);
config.loadSettings(p);
return config;
}
public enum UuidVersion {
@@ -5,8 +5,7 @@ import io.ebean.Query;
import io.ebean.annotation.PersistBatch;
import io.ebean.annotation.Platform;
import io.ebean.config.CustomDbTypeMapping;
import io.ebean.config.DbTypeConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.util.JdbcClose;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -215,16 +214,16 @@ public class DatabasePlatform {
/**
* Configure the platform given the server configuration.
*/
public void configure(ServerConfig config) {
public void configure(PlatformConfig config) {
this.sequenceBatchSize = config.getDatabaseSequenceBatchSize();
configureIdType(config.getIdType());
configure(config.getDbTypeConfig(), config.isAllQuotedIdentifiers());
configure(config, config.isAllQuotedIdentifiers());
}
/**
* Configure UUID Storage etc based on ServerConfig settings.
*/
protected void configure(DbTypeConfig config, boolean allQuotedIdentifiers) {
protected void configure(PlatformConfig config, boolean allQuotedIdentifiers) {
this.allQuotedIdentifiers = allQuotedIdentifiers;
addGeoTypes(config.getGeometrySRID());
configureIdType(config.getIdType());
@@ -1,6 +1,6 @@
package io.ebean.config.dbplatform;
import io.ebean.config.ServerConfig;
import io.ebean.config.PlatformConfig;
import java.util.EnumMap;
import java.util.Map;
@@ -198,7 +198,7 @@ public class DbPlatformTypeMapping {
/**
* Map the UUID appropriately based on native DB support and ServerConfig.DbUuid.
*/
public void config(boolean nativeUuidType, ServerConfig.DbUuid dbUuid) {
public void config(boolean nativeUuidType, PlatformConfig.DbUuid dbUuid) {
if (nativeUuidType && dbUuid.useNativeType()) {
// native UUID already set by default
} else if (dbUuid.useBinary()) {
@@ -4,7 +4,7 @@ import io.ebean.BackgroundExecutor;
import io.ebean.Query;
import io.ebean.annotation.PersistBatch;
import io.ebean.annotation.Platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.config.dbplatform.DbType;
@@ -82,7 +82,7 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
}
@Override
public void configure(ServerConfig config) {
public void configure(PlatformConfig config) {
super.configure(config);
if (dbIdentity.getIdType() == IdType.SEQUENCE) {
this.persistBatchOnCascade = PersistBatch.ALL;
@@ -5,6 +5,7 @@ import io.ebean.EbeanServer;
import io.ebean.annotation.Platform;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.DbMigrationConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.db2.DB2Platform;
@@ -227,15 +228,17 @@ public class DefaultDbMigration implements DbMigration {
if (!online) {
DbOffline.setGenerateMigration();
if (databasePlatform == null && !platforms.isEmpty()) {
// for multiple platform generation set the general platform
// to H2 so that it runs offline without DB connection
// for multiple platform generation the first platform
// is used to generate the "logical" model diff
setPlatform(platforms.get(0).platform);
}
}
setDefaults();
if (!platforms.isEmpty()) {
configurePlatforms();
}
try {
Request request = createRequest();
if (platforms.isEmpty()) {
generateExtraDdl(request.migrationDir, databasePlatform);
}
@@ -254,6 +257,16 @@ public class DefaultDbMigration implements DbMigration {
}
}
/**
* Load the configuration for each of the target platforms.
*/
private void configurePlatforms() {
for (Pair pair : platforms) {
PlatformConfig config = serverConfig.newPlatformConfig("dbmigration.platform", pair.prefix);
pair.platform.configure(config);
}
}
/**
* Generate "repeatable" migration scripts.
* <p>
@@ -267,7 +267,7 @@ public class DefaultContainer implements SpiContainer {
config.setDatabasePlatform(platform);
}
logger.info("DatabasePlatform name:{} platform:{}", config.getName(), platform.getName());
platform.configure(config);
platform.configure(config.getPlatformConfig());
}
/**
@@ -304,7 +304,7 @@ public class InternalConfiguration {
}
public RelationalQueryEngine createRelationalQueryEngine() {
return new DefaultRelationalQueryEngine(binder, serverConfig.getDatabaseBooleanTrue(), serverConfig.getDbTypeConfig().getDbUuid().useBinaryOptimized());
return new DefaultRelationalQueryEngine(binder, serverConfig.getDatabaseBooleanTrue(), serverConfig.getPlatformConfig().getDbUuid().useBinaryOptimized());
}
public OrmQueryEngine createOrmQueryEngine() {
@@ -8,6 +8,7 @@ import io.ebean.annotation.DbEnumValue;
import io.ebean.annotation.EnumValue;
import io.ebean.annotation.Platform;
import io.ebean.config.JsonConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.ScalarTypeConverter;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
@@ -944,7 +945,7 @@ public final class DefaultTypeManager implements TypeManager {
nativeMap.put(Types.BIT, booleanType);
}
ServerConfig.DbUuid dbUuid = config.getDbTypeConfig().getDbUuid();
PlatformConfig.DbUuid dbUuid = config.getPlatformConfig().getDbUuid();
if (offlineMigrationGeneration || (databasePlatform.isNativeUuidType() && dbUuid.useNativeType())) {
addType(UUID.class, new ScalarTypeUUIDNative());
@@ -32,7 +32,7 @@ public class DbMigrationConfigTest {
properties.setProperty("ebean.migration.patchInsertOn", "1.3,my_views");
properties.setProperty("ebean.migration.patchResetChecksumOn", "foo");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties);
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties, null);
DbMigrationConfig migrationConfig = new DbMigrationConfig();
migrationConfig.loadSettings(wrapper, "db");
@@ -50,7 +50,7 @@ public class DbMigrationConfigTest {
properties.setProperty("datasource.db.username", "banana");
properties.setProperty("datasource.db.password", "apple");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties);
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties, null);
DbMigrationConfig migrationConfig = new DbMigrationConfig();
migrationConfig.loadSettings(wrapper, "db");
@@ -67,7 +67,7 @@ public class DbMigrationConfigTest {
properties.setProperty("datasource.db.adminusername", "banana");
properties.setProperty("datasource.db.adminpassword", "apple");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties);
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties, null);
DbMigrationConfig migrationConfig = new DbMigrationConfig();
migrationConfig.loadSettings(wrapper, "db");
@@ -5,7 +5,9 @@ import org.junit.Test;
import java.util.Properties;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class DocStoreConfigTest {
@@ -23,7 +25,7 @@ public class DocStoreConfigTest {
properties.setProperty("ebean.docstore.username", "fred");
properties.setProperty("ebean.docstore.password", "rock");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", null, properties);
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", null, properties, null);
config.loadSettings(wrapper);
@@ -47,7 +49,7 @@ public class DocStoreConfigTest {
properties.setProperty("ebean.docstore.generateMapping", "true");
properties.setProperty("ebean.docstore.dropCreate", "true");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", null, properties);
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", null, properties, null);
config.loadSettings(wrapper);
assertTrue(config.isGenerateMapping());
@@ -64,7 +66,7 @@ public class DocStoreConfigTest {
properties.setProperty("ebean.docstore.generateMapping", "true");
properties.setProperty("ebean.docstore.create", "true");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", null, properties);
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", null, properties, null);
config.loadSettings(wrapper);
assertTrue(config.isGenerateMapping());
@@ -20,7 +20,7 @@ public class MatchingNamingConventionTest {
SqlServer17Platform platform = new SqlServer17Platform();
ServerConfig config = new ServerConfig();
PlatformConfig config = new PlatformConfig();
config.setAllQuotedIdentifiers(true);
platform.configure(config);
@@ -15,7 +15,7 @@ public class PropertiesWrapperTest {
@Test
public void testGetServerName() {
PropertiesWrapper pw = new PropertiesWrapper(null, "myserver", new Properties());
PropertiesWrapper pw = new PropertiesWrapper(null, "myserver", new Properties(), null);
assertEquals("myserver", pw.getServerName());
}
@@ -25,7 +25,7 @@ public class PropertiesWrapperTest {
Properties properties = new Properties();
properties.put("platform", "postgres");
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", properties);
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", properties, null);
assertEquals(Platform.POSTGRES, pw.getEnum(Platform.class, "platform", Platform.H2));
assertEquals(Platform.H2, pw.getEnum(Platform.class, "junk", Platform.H2));
assertNull(pw.getEnum(Platform.class, "junk", null));
@@ -40,7 +40,7 @@ public class PropertiesWrapperTest {
properties.put("noTrimReqr", "jim");
properties.put("includeSpaces", " jim bob ");
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", properties);
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", properties, null);
assertEquals(" hello ", pw.get("someBasic"));
assertEquals(42, pw.getInt("someInt", 1));
assertNull(pw.get("doesNotExist", null));
@@ -62,14 +62,14 @@ public class PropertiesWrapperTest {
properties.put("someSystemProp", "/aaa/${java.io.tmpdir}/bbb");
Properties evalCopy = PropertiesLoader.eval(properties);
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", evalCopy);
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", evalCopy, null);
assertEquals(42, pw.getInt("someInt", 99));
assertEquals(Double.valueOf(5.5D), (Double.valueOf(pw.getDouble("someDouble", 99.9D))));
assertEquals(home + "/hello", pw.get("somePath", null));
assertEquals(tmpDir, "/aaa/" + tmpDir + "/bbb", pw.get("someSystemProp"));
pw = new PropertiesWrapper(evalCopy);
pw = new PropertiesWrapper(evalCopy, null);
assertEquals(42, pw.getInt("someInt", 99));
assertEquals(Double.valueOf(5.5D), (Double.valueOf(pw.getDouble("someDouble", 99.9D))));
@@ -75,7 +75,7 @@ public class ServerConfigTest {
assertEquals(IdType.SEQUENCE, serverConfig.getIdType());
assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatch());
assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatchOnCascade());
assertEquals(ServerConfig.DbUuid.BINARY, serverConfig.getDbTypeConfig().getDbUuid());
assertEquals(PlatformConfig.DbUuid.BINARY, serverConfig.getPlatformConfig().getDbUuid());
assertEquals(JsonConfig.DateTime.ISO8601, serverConfig.getJsonDateTime());
assertEquals(42, serverConfig.getJdbcFetchSizeFindEach());
@@ -1,8 +1,8 @@
package io.ebean.config.dbplatform;
import io.ebean.annotation.Platform;
import io.ebean.config.DbTypeConfig;
import io.ebean.config.MatchingNamingConvention;
import io.ebean.config.PlatformConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.h2.H2Platform;
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
@@ -21,7 +21,7 @@ public class DatabasePlatformTest {
config.setNamingConvention(new MatchingNamingConvention());
DatabasePlatform dbPlatform = new SqlServer17Platform();
dbPlatform.configure(config.getDbTypeConfig(), config.isAllQuotedIdentifiers());
dbPlatform.configure(config.getPlatformConfig(), config.isAllQuotedIdentifiers());
assertEquals(dbPlatform.convertQuotedIdentifiers("order"),"[order]");
assertEquals(dbPlatform.convertQuotedIdentifiers("`order`"),"[order]");
@@ -34,7 +34,7 @@ public class DatabasePlatformTest {
ServerConfig config = new ServerConfig();
DatabasePlatform dbPlatform = new SqlServer17Platform();
dbPlatform.configure(config.getDbTypeConfig(), config.isAllQuotedIdentifiers());
dbPlatform.configure(config.getPlatformConfig(), config.isAllQuotedIdentifiers());
assertEquals(dbPlatform.convertQuotedIdentifiers("order"),"order");
assertEquals(dbPlatform.convertQuotedIdentifiers("`order`"),"[order]");
@@ -56,7 +56,7 @@ public class DatabasePlatformTest {
@Test
public void configure_customType() throws Exception {
DbTypeConfig config = new DbTypeConfig();
PlatformConfig config = new PlatformConfig();
config.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES);
config.addCustomMapping(DbType.DECIMAL, "decimal(24,4)");
@@ -1,7 +1,6 @@
package io.ebean.config.dbplatform;
import io.ebean.config.DbTypeConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
import io.ebeaninternal.server.core.PlatformDdlBuilder;
@@ -28,7 +27,7 @@ public class MySqlPlatformTest {
public void uuid_default() {
MySqlPlatform platform = new MySqlPlatform();
platform.configure(new DbTypeConfig(), false);
platform.configure(new PlatformConfig(), false);
DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID);
assertThat(dbType.renderType(0, 0)).isEqualTo("varchar(40)");
@@ -39,8 +38,8 @@ public class MySqlPlatformTest {
public void uuid_as_binary() {
MySqlPlatform platform = new MySqlPlatform();
DbTypeConfig config = new DbTypeConfig();
config.setDbUuid(ServerConfig.DbUuid.AUTO_BINARY);
PlatformConfig config = new PlatformConfig();
config.setDbUuid(PlatformConfig.DbUuid.AUTO_BINARY);
platform.configure(config, false);
DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID);
@@ -1,7 +1,6 @@
package io.ebean.config.dbplatform;
import io.ebean.config.DbTypeConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.dbplatform.oracle.OraclePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
import io.ebeaninternal.server.core.PlatformDdlBuilder;
@@ -37,7 +36,7 @@ public class OraclePlatformTest {
public void uuid_default() {
OraclePlatform platform = new OraclePlatform();
platform.configure(new DbTypeConfig(), false);
platform.configure(new PlatformConfig(), false);
DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID);
assertThat(dbType.renderType(0, 0)).isEqualTo("varchar2(40)");
@@ -48,8 +47,8 @@ public class OraclePlatformTest {
public void uuid_as_binary() {
OraclePlatform platform = new OraclePlatform();
DbTypeConfig config = new DbTypeConfig();
config.setDbUuid(ServerConfig.DbUuid.AUTO_BINARY);
PlatformConfig config = new PlatformConfig();
config.setDbUuid(PlatformConfig.DbUuid.AUTO_BINARY);
platform.configure(config, false);
@@ -1,6 +1,6 @@
package io.ebean.config.dbplatform;
import io.ebean.config.DbTypeConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
import io.ebeaninternal.server.core.PlatformDdlBuilder;
@@ -37,7 +37,7 @@ public class PostgresPlatformTest {
public void testUuidType() {
PostgresPlatform platform = new PostgresPlatform();
platform.configure(new DbTypeConfig(), false);
platform.configure(new PlatformConfig(), false);
DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID);
String columnDefn = dbType.renderType(0, 0);