#877 - DBMigration Generates wrong ddl for UUID type

This commit is contained in:
Rob Bygrave
2016-11-15 22:12:54 +13:00
parent 01f551a951
commit b41f3e9d1f
13 changed files with 192 additions and 88 deletions
@@ -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<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;
}
}
@@ -91,8 +91,6 @@ public class ServerConfig {
private ContainerConfig containerConfig;
private List<CustomDbTypeMapping> 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<IdGenerator> idGenerators = new ArrayList<>();
private List<BeanFindController> 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<CustomDbTypeMapping> 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);
@@ -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);
}
@@ -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));
}
}
@@ -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));
}
/**
@@ -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));
@@ -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());
}
@@ -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());