mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
DbMigration update - constraints up front
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
package com.avaje.ebean.config;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Provides some base implementation for NamingConventions.
|
||||
*
|
||||
@@ -14,28 +12,39 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public abstract class AbstractNamingConvention implements NamingConvention {
|
||||
|
||||
/** The Constant logger. */
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractNamingConvention.class);
|
||||
|
||||
/** The Constant DEFAULT_SEQ_FORMAT. */
|
||||
/**
|
||||
* The Constant DEFAULT_SEQ_FORMAT.
|
||||
*/
|
||||
public static final String DEFAULT_SEQ_FORMAT = "{table}_seq";
|
||||
|
||||
/** Sequence Format that includes the Primary Key column */
|
||||
/**
|
||||
* Sequence Format that includes the Primary Key column
|
||||
*/
|
||||
public static final String TABLE_PKCOLUMN_SEQ_FORMAT = "{table}_{column}_seq";
|
||||
|
||||
/** The catalog. */
|
||||
/**
|
||||
* The catalog.
|
||||
*/
|
||||
private String catalog;
|
||||
|
||||
/** The schema. */
|
||||
/**
|
||||
* The schema.
|
||||
*/
|
||||
private String schema;
|
||||
|
||||
/** The sequence format. */
|
||||
/**
|
||||
* The sequence format.
|
||||
*/
|
||||
private String sequenceFormat;
|
||||
|
||||
/** The database platform. */
|
||||
/**
|
||||
* The database platform.
|
||||
*/
|
||||
protected DatabasePlatform databasePlatform;
|
||||
|
||||
/** Used to trim off extra prefix for M2M. */
|
||||
/**
|
||||
* Used to trim off extra prefix for M2M.
|
||||
*/
|
||||
protected int rhsPrefixLength = 3;
|
||||
|
||||
protected boolean useForeignKeyPrefix;
|
||||
@@ -59,8 +68,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with the default sequence format ("{table}_seq") and
|
||||
* useForeignKeyPrefix as true.
|
||||
* Construct with the default sequence format ("{table}_seq") and useForeignKeyPrefix as true.
|
||||
*/
|
||||
public AbstractNamingConvention() {
|
||||
this(DEFAULT_SEQ_FORMAT);
|
||||
@@ -233,7 +241,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
|
||||
if (t != null && !isEmpty(t.name())) {
|
||||
// Note: empty catalog and schema are converted to null
|
||||
// Only need to convert quoted identifiers from annotations
|
||||
return new TableName(quoteIdentifiers(t.catalog()), quoteIdentifiers(t.schema()), quoteIdentifiers(t.name()));
|
||||
return new TableName(quoteIdentifiers(t.catalog()), quoteIdentifiers(t.schema()), quoteIdentifiers(t.name()));
|
||||
}
|
||||
|
||||
// No annotation
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.avaje.ebean.config;
|
||||
|
||||
/**
|
||||
* Naming convention used for constraint names.
|
||||
* <p>
|
||||
* Note that these constraint names are trimmed in the PlatformDdl which can be overridden
|
||||
* but provides a decent default implementation.
|
||||
* </p>
|
||||
*/
|
||||
public class DbConstraintNaming {
|
||||
|
||||
protected String pkPrefix = "pk_";
|
||||
protected String pkSuffix = "";
|
||||
|
||||
protected String fkPrefix = "fk_";
|
||||
protected String fkMiddle = "_";
|
||||
protected String fkSuffix = "";
|
||||
|
||||
protected String fkIndexPrefix = "ix_";
|
||||
protected String fkIndexMiddle = "_";
|
||||
protected String fkIndexSuffix = "";
|
||||
|
||||
protected String uqPrefix = "uq_";
|
||||
protected String uqSuffix = "";
|
||||
|
||||
protected String ckPrefix = "ck_";
|
||||
protected String ckSuffix = "";
|
||||
|
||||
protected boolean lowerCaseNames = true;
|
||||
|
||||
protected DbConstraintNormalise normalise = new DbConstraintNormalise();
|
||||
|
||||
public DbConstraintNaming() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary key constraint name.
|
||||
*/
|
||||
public String primaryKeyName(String tableName) {
|
||||
|
||||
return pkPrefix + normaliseTable(tableName) + pkSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
public String foreignKeyConstraintName(String tableName, String columnName) {
|
||||
return fkPrefix + normaliseTable(tableName) + fkMiddle + normaliseColumn(columnName) + fkSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index name associated with a foreign key constraint given a single column foreign key.
|
||||
*/
|
||||
public String foreignKeyIndexName(String tableName, String[] columns) {
|
||||
|
||||
String colPart = joinColumnNames(columns);
|
||||
return fkIndexPrefix + normaliseTable(tableName) + fkIndexMiddle + colPart + fkIndexSuffix;
|
||||
}
|
||||
|
||||
public String foreignKeyIndexName(String tableName, String column) {
|
||||
|
||||
String colPart = normaliseTable(column);
|
||||
return fkIndexPrefix + normaliseTable(tableName) + fkIndexMiddle + colPart + fkIndexSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join the column names together with underscores.
|
||||
*/
|
||||
protected String joinColumnNames(String[] columns) {
|
||||
|
||||
if (columns.length == 1) {
|
||||
return normaliseColumn(columns[0]);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append("_");
|
||||
}
|
||||
sb.append(normaliseColumn(columns[i]));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
public String uniqueConstraintName(String tableName, String columnName) {
|
||||
|
||||
return uqPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + uqSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
public String uniqueConstraintName(String tableName, String[] columns) {
|
||||
|
||||
String colPart = joinColumnNames(columns);
|
||||
return uqPrefix + normaliseTable(tableName) + "_" + colPart + uqSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the check constraint name.
|
||||
*/
|
||||
public String checkConstraintName(String tableName, String columnName) {
|
||||
|
||||
return ckPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + ckSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise the table name by trimming catalog and schema and removing any
|
||||
* quoted identifier characters (",',[,] etc).
|
||||
*/
|
||||
public String normaliseTable(String tableName) {
|
||||
|
||||
return normalise.normaliseTable(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise the column name by removing any quoted identifier characters (",',[,] etc).
|
||||
*/
|
||||
public String normaliseColumn(String tableName) {
|
||||
|
||||
return normalise.normaliseColumn(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower case the table or column name checking for quoted identifiers.
|
||||
*/
|
||||
public String lowerName(String tableName) {
|
||||
if (lowerCaseNames && normalise.notQuoted(tableName)) {
|
||||
return tableName.toLowerCase();
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
}
|
||||
+30
-13
@@ -1,24 +1,19 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.util.DbQuotes;
|
||||
package com.avaje.ebean.config;
|
||||
|
||||
/**
|
||||
* Used to normalise table and column names which means stripping out
|
||||
* quoted identifier characters and any catalog or schema prefix.
|
||||
*/
|
||||
public class DdlNameNormalise {
|
||||
public class DbConstraintNormalise {
|
||||
|
||||
protected final String[] quotedIdentifiers;
|
||||
|
||||
protected boolean lowerCaseTables = true;
|
||||
|
||||
protected boolean lowerCaseColumns = true;
|
||||
|
||||
protected DbQuotes quotes = new DbQuotes();
|
||||
|
||||
public DdlNameNormalise() {
|
||||
}
|
||||
|
||||
public boolean notQuoted(String tableName) {
|
||||
return quotes.notQuoted(tableName);
|
||||
public DbConstraintNormalise() {
|
||||
this.quotedIdentifiers = new String[]{"\"", "'", "[", "]", "`"};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,9 +49,31 @@ public class DdlNameNormalise {
|
||||
/**
|
||||
* Trim off the platform quoted identifier quotes like [ ' and ".
|
||||
*/
|
||||
protected String trimQuotes(String tableName) {
|
||||
public boolean notQuoted(String tableName) {
|
||||
|
||||
return quotes.trimQuotes(tableName);
|
||||
// remove quoted identifier characters
|
||||
for (int i = 0; i < quotedIdentifiers.length; i++) {
|
||||
if (tableName.contains(quotedIdentifiers[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim off the platform quoted identifier quotes like [ ' and ".
|
||||
*/
|
||||
public String trimQuotes(String tableName) {
|
||||
|
||||
if (tableName == null) {
|
||||
return "";
|
||||
}
|
||||
// remove quoted identifier characters
|
||||
for (int i = 0; i < quotedIdentifiers.length; i++) {
|
||||
tableName = tableName.replace(quotedIdentifiers[i], "");
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -82,8 +82,7 @@ public interface NamingConvention {
|
||||
String getPropertyFromColumn(Class<?> beanClass, String dbColumnName);
|
||||
|
||||
/**
|
||||
* Return the sequence name given the table name (for DB's that use
|
||||
* sequences).
|
||||
* Return the sequence name given the table name (for DB's that use sequences).
|
||||
* <p>
|
||||
* Typically you might append "_seq" to the table name as an example.
|
||||
* </p>
|
||||
@@ -99,14 +98,14 @@ public interface NamingConvention {
|
||||
* Return true if a prefix should be used building a foreign key name.
|
||||
* <p>
|
||||
* This by default is true and this works well when the primary key column
|
||||
* names are simply "ID". In this case a prefix (such as "ORDER" and
|
||||
* "CUSTOMER" etc) is added to the foreign key column producing "ORDER_ID" and
|
||||
* "CUSTOMER_ID".
|
||||
* names are simply "id". In this case a prefix (such as "order" and
|
||||
* "customer" etc) is added to the foreign key column producing "order_id" and
|
||||
* "customer_id".
|
||||
* </p>
|
||||
* <p>
|
||||
* This should return false when your primary key columns are the same as the
|
||||
* foreign key columns. For example, when the primary key columns are
|
||||
* "ORDER_ID", "CUST_ID" etc ... and they are the same as the foreign key
|
||||
* "order_id", "cust_id" etc ... and they are the same as the foreign key
|
||||
* column names.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
@@ -239,6 +239,11 @@ public class ServerConfig {
|
||||
*/
|
||||
private NamingConvention namingConvention = new UnderscoreNamingConvention();
|
||||
|
||||
/**
|
||||
* Naming convention used in DDL generation for primary keys, foreign keys etc.
|
||||
*/
|
||||
private DbConstraintNaming constraintNaming = new DbConstraintNaming();
|
||||
|
||||
/**
|
||||
* Behaviour of update to include on the change properties.
|
||||
*/
|
||||
@@ -975,6 +980,20 @@ public class ServerConfig {
|
||||
this.namingConvention = namingConvention;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the constraint naming convention used in DDL generation.
|
||||
*/
|
||||
public DbConstraintNaming getConstraintNaming() {
|
||||
return constraintNaming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraint naming convention used in DDL generation.
|
||||
*/
|
||||
public void setConstraintNaming(DbConstraintNaming constraintNaming) {
|
||||
this.constraintNaming = constraintNaming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration for the Autofetch feature.
|
||||
*/
|
||||
|
||||
@@ -3,23 +3,26 @@ package com.avaje.ebean.config;
|
||||
/**
|
||||
* Converts between Camel Case and Underscore based names for both table and
|
||||
* column names (and is the default naming convention in Ebean).
|
||||
*
|
||||
*
|
||||
* @author emcgreal
|
||||
* @author rbygrave
|
||||
*/
|
||||
public class UnderscoreNamingConvention extends AbstractNamingConvention {
|
||||
|
||||
/** Force toUnderscore to return in upper case. */
|
||||
/**
|
||||
* Force toUnderscore to return in upper case.
|
||||
*/
|
||||
private boolean forceUpperCase = false;
|
||||
|
||||
/** The digits compressed. */
|
||||
/**
|
||||
* The digits compressed.
|
||||
*/
|
||||
private boolean digitsCompressed = true;
|
||||
|
||||
/**
|
||||
* Create with a given sequence format.
|
||||
*
|
||||
* @param sequenceFormat
|
||||
* the sequence format
|
||||
*
|
||||
* @param sequenceFormat the sequence format
|
||||
*/
|
||||
public UnderscoreNamingConvention(String sequenceFormat) {
|
||||
super(sequenceFormat);
|
||||
@@ -34,39 +37,30 @@ public class UnderscoreNamingConvention extends AbstractNamingConvention {
|
||||
|
||||
/**
|
||||
* Returns the last part of the class name.
|
||||
*
|
||||
* @param beanClass
|
||||
* the bean class
|
||||
*
|
||||
*
|
||||
* @param beanClass the bean class
|
||||
* @return the table name from class
|
||||
*/
|
||||
public TableName getTableNameByConvention(Class<?> beanClass) {
|
||||
|
||||
return new TableName(getCatalog(),
|
||||
getSchema(),
|
||||
toUnderscoreFromCamel(beanClass.getSimpleName()));
|
||||
return new TableName(getCatalog(), getSchema(), toUnderscoreFromCamel(beanClass.getSimpleName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Camel case property name to underscore based column name.
|
||||
*
|
||||
*
|
||||
* @return the column from property
|
||||
*/
|
||||
public String getColumnFromProperty(Class<?> beanClass, String propertyName) {// Field
|
||||
// field)
|
||||
// {
|
||||
public String getColumnFromProperty(Class<?> beanClass, String propertyName) {
|
||||
|
||||
return toUnderscoreFromCamel(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts underscore based column name to Camel case property name.
|
||||
*
|
||||
* @param beanClass
|
||||
* the bean class
|
||||
* @param dbColumnName
|
||||
* the db column name
|
||||
*
|
||||
*
|
||||
* @param beanClass the bean class
|
||||
* @param dbColumnName the db column name
|
||||
* @return the property from column
|
||||
*/
|
||||
public String getPropertyFromColumn(Class<?> beanClass, String dbColumnName) {
|
||||
@@ -110,7 +104,7 @@ public class UnderscoreNamingConvention extends AbstractNamingConvention {
|
||||
protected String toUnderscoreFromCamel(String camelCase) {
|
||||
|
||||
int lastUpper = -1;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder(camelCase.length()+4);
|
||||
for (int i = 0; i < camelCase.length(); i++) {
|
||||
char c = camelCase.charAt(i);
|
||||
|
||||
@@ -144,16 +138,11 @@ public class UnderscoreNamingConvention extends AbstractNamingConvention {
|
||||
}
|
||||
|
||||
/**
|
||||
* To camel from underscore.
|
||||
*
|
||||
* @param underscore
|
||||
* the underscore
|
||||
*
|
||||
* @return the string
|
||||
* Convert and return the from string from underscore to camel case.
|
||||
*/
|
||||
protected String toCamelFromUnderscore(String underscore) {
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
StringBuilder result = new StringBuilder(underscore.length());
|
||||
String[] vals = underscore.split("_");
|
||||
|
||||
for (int i = 0; i < vals.length; i++) {
|
||||
|
||||
@@ -15,6 +15,7 @@ public class DB2Platform extends DatabasePlatform {
|
||||
public DB2Platform() {
|
||||
super();
|
||||
this.name = "db2";
|
||||
this.maxTableNameLength = 18;
|
||||
this.sqlLimiter = new Db2SqlLimiter();
|
||||
this.platformDdl = new DB2Ddl(dbTypeMap, dbIdentity);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import javax.sql.DataSource;
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.Query;
|
||||
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import org.slf4j.Logger;
|
||||
@@ -145,6 +146,12 @@ public class DatabasePlatform {
|
||||
|
||||
protected PlatformDdl platformDdl;
|
||||
|
||||
/**
|
||||
* The maximum length of table names - used specifically when derived
|
||||
* default table names for intersection tables.
|
||||
*/
|
||||
protected int maxTableNameLength = 60;
|
||||
|
||||
/**
|
||||
* Instantiates a new database platform.
|
||||
*/
|
||||
@@ -169,7 +176,7 @@ public class DatabasePlatform {
|
||||
* </p>
|
||||
*/
|
||||
public int getMaxTableNameLength() {
|
||||
return platformDdl.getMaxTableNameLength();
|
||||
return maxTableNameLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,8 +189,8 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Create and return a DDL handler for generating DDL scripts.
|
||||
*/
|
||||
public DdlHandler createDdlHandler() {
|
||||
return platformDdl.createDdlHandler();
|
||||
public DdlHandler createDdlHandler(ServerConfig serverConfig) {
|
||||
return platformDdl.createDdlHandler(serverConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,7 @@ public class Oracle10Platform extends DatabasePlatform {
|
||||
public Oracle10Platform() {
|
||||
super();
|
||||
this.name = "oracle";
|
||||
this.maxIntersectionTableName = 30;
|
||||
// OnQueryOnly.CLOSE as a performance optimisation on Oracle
|
||||
this.onQueryOnly = OnQueryOnly.CLOSE;
|
||||
this.dbEncrypt = new Oracle10DbEncrypt();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PostgresDdl;
|
||||
|
||||
@@ -66,8 +67,8 @@ public class PostgresPlatform extends DatabasePlatform {
|
||||
/**
|
||||
* Return a DdlHandler instance for generating DDL for the specific platform.
|
||||
*/
|
||||
public DdlHandler createDdlHandler() {
|
||||
return this.platformDdl.createDdlHandler();
|
||||
public DdlHandler createDdlHandler(ServerConfig serverConfig) {
|
||||
return this.platformDdl.createDdlHandler(serverConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,8 +30,6 @@ public class DbMigration {
|
||||
this.migrationConfig = server.getServerConfig().getMigrationConfig();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void writeCurrent() {
|
||||
|
||||
CurrentModel currentModel = new CurrentModel(server);
|
||||
|
||||
@@ -97,10 +97,8 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
try {
|
||||
String c = generateDropDdl();
|
||||
writeFile(dropFile, c);
|
||||
|
||||
} catch (IOException e) {
|
||||
String msg = "Error generating Drop DDL";
|
||||
throw new PersistenceException(msg, e);
|
||||
throw new PersistenceException("Error generating Drop DDL", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +107,8 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
try {
|
||||
String c = generateCreateDdl();
|
||||
writeFile(createFile, c);
|
||||
|
||||
} catch (IOException e) {
|
||||
String msg = "Error generating Create DDL";
|
||||
throw new PersistenceException(msg, e);
|
||||
throw new PersistenceException("Error generating Create DDL", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,8 +209,7 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
t.commit();
|
||||
|
||||
} catch (Exception e) {
|
||||
String msg = "Error: " + e.getMessage();
|
||||
throw new PersistenceException(msg, e);
|
||||
throw new PersistenceException("Error: " + e.getMessage(), e);
|
||||
} finally {
|
||||
t.end();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration;
|
||||
|
||||
import com.avaje.ebean.config.DbConstraintNaming;
|
||||
import com.avaje.ebean.config.NamingConvention;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.BaseColumnDdl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.BaseTableDdl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.DdlNamingConvention;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
@@ -22,8 +23,8 @@ public class BaseDdlHandler implements DdlHandler {
|
||||
|
||||
protected final TableDdl tableDdl;
|
||||
|
||||
public BaseDdlHandler(DdlNamingConvention namingConvention, PlatformDdl platformDdl) {
|
||||
this.tableDdl = new BaseTableDdl(namingConvention, platformDdl);
|
||||
public BaseDdlHandler(NamingConvention namingConvention, DbConstraintNaming naming, PlatformDdl platformDdl) {
|
||||
this.tableDdl = new BaseTableDdl(namingConvention, naming, platformDdl);
|
||||
this.columnDdl = new BaseColumnDdl(platformDdl);
|
||||
}
|
||||
|
||||
|
||||
+25
-19
@@ -55,23 +55,22 @@ public class BaseColumnDdl implements ColumnDdl {
|
||||
historyIncludeColumn(writer, alterColumn);
|
||||
}
|
||||
|
||||
if (hasValue(alterColumn.getOldReferences())) {
|
||||
if (hasValue(alterColumn.getDropForeignKey())) {
|
||||
dropForeignKey(writer, alterColumn);
|
||||
}
|
||||
if (hasValue(alterColumn.getNewReferences())) {
|
||||
if (hasValue(alterColumn.getReferences())) {
|
||||
addForeignKey(writer, alterColumn);
|
||||
}
|
||||
|
||||
if (isTrue(alterColumn.isUnique())) {
|
||||
addUniqueConstraint(writer, alterColumn);
|
||||
} else if (isFalse(alterColumn.isUnique())) {
|
||||
if (hasValue(alterColumn.getDropUnique())) {
|
||||
dropUniqueConstraint(writer, alterColumn);
|
||||
}
|
||||
if (hasValue(alterColumn.getUnique())) {
|
||||
addUniqueConstraint(writer, alterColumn);
|
||||
}
|
||||
|
||||
if (isTrue(alterColumn.isUniqueOneToOne())) {
|
||||
if (hasValue(alterColumn.getUniqueOneToOne())) {
|
||||
addUniqueOneToOneConstraint(writer, alterColumn);
|
||||
} else if (isFalse(alterColumn.isUniqueOneToOne())) {
|
||||
dropUniqueOneToOneConstraint(writer, alterColumn);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -82,34 +81,41 @@ public class BaseColumnDdl implements ColumnDdl {
|
||||
|
||||
}
|
||||
|
||||
protected void dropForeignKey(DdlWrite writer, AlterColumn alterColumn) {
|
||||
protected void dropForeignKey(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String fkName = alter.getDropForeignKey();
|
||||
|
||||
writer.apply()
|
||||
.append(platformDdl.alterTableDropForeignKey(tableName, fkName))
|
||||
.endOfStatement();
|
||||
}
|
||||
|
||||
protected void dropUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alterColumn) {
|
||||
|
||||
}
|
||||
|
||||
protected void addUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alterColumn) {
|
||||
|
||||
}
|
||||
|
||||
protected void dropUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String uqName = platformDdl.namingConvention.uniqueConstraintName(tableName, columnName, 50);
|
||||
String uqName = alter.getDropUnique();
|
||||
|
||||
writer.apply()
|
||||
.append(platformDdl.dropIndex(uqName, tableName))
|
||||
.endOfStatement();
|
||||
}
|
||||
|
||||
protected void addUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
addUniqueConstraint(writer, alter, alter.getUniqueOneToOne());
|
||||
}
|
||||
|
||||
protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
addUniqueConstraint(writer, alter, alter.getUnique());
|
||||
}
|
||||
|
||||
protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter, String uqName) throws IOException {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String uqName = platformDdl.namingConvention.uniqueConstraintName(tableName, columnName, 50);
|
||||
|
||||
String[] cols = {columnName};
|
||||
writer.apply()
|
||||
|
||||
+53
-196
@@ -1,9 +1,13 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.DbConstraintNaming;
|
||||
import com.avaje.ebean.config.NamingConvention;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.config.dbplatform.IdType;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.TableDdl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.util.IndexSet;
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.ForeignKey;
|
||||
@@ -19,7 +23,9 @@ import java.util.List;
|
||||
*/
|
||||
public class BaseTableDdl implements TableDdl {
|
||||
|
||||
protected final DdlNamingConvention namingConvention;
|
||||
protected final DbConstraintNaming naming;
|
||||
|
||||
protected final NamingConvention namingConvention;
|
||||
|
||||
protected final PlatformDdl platformDdl;
|
||||
|
||||
@@ -32,7 +38,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Used when unique constraints specifically for OneToOne can't be created normally (MsSqlServer).
|
||||
*/
|
||||
protected IndexSet externalUnique = new IndexSet();
|
||||
protected List<Column> externalUnique = new ArrayList<Column>();
|
||||
|
||||
// counters used when constraint names are truncated due to maximum length
|
||||
// and these counters are used to keep the constraint name unique
|
||||
@@ -41,11 +47,16 @@ public class BaseTableDdl implements TableDdl {
|
||||
protected int countForeignKey;
|
||||
protected int countIndex;
|
||||
|
||||
public BaseTableDdl(ServerConfig serverConfig, PlatformDdl platformDdl) {
|
||||
this(serverConfig.getNamingConvention(), serverConfig.getConstraintNaming(), platformDdl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a naming convention and platform specific DDL.
|
||||
*/
|
||||
public BaseTableDdl(DdlNamingConvention namingConvention, PlatformDdl platformDdl) {
|
||||
public BaseTableDdl(NamingConvention namingConvention, DbConstraintNaming naming, PlatformDdl platformDdl) {
|
||||
this.namingConvention = namingConvention;
|
||||
this.naming = naming;
|
||||
this.platformDdl = platformDdl;
|
||||
}
|
||||
|
||||
@@ -74,7 +85,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
List<Column> columns = createTable.getColumn();
|
||||
List<Column> pk = determinePrimaryKeyColumns(columns);
|
||||
|
||||
boolean singleColumnPrimaryKey = pk.size() == 1;
|
||||
boolean singleColumnPrimaryKey = (pk.size() == 1);
|
||||
boolean useIdentity = false;
|
||||
boolean useSequence = false;
|
||||
|
||||
@@ -99,7 +110,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
writeCompoundUniqueConstraints(apply, createTable);
|
||||
if (!pk.isEmpty()) {
|
||||
// defined on the columns
|
||||
writePrimaryKeyConstraint(apply, tableName, toColumnNames(pk));
|
||||
writePrimaryKeyConstraint(apply, createTable.getPkName(), toColumnNames(pk));
|
||||
}
|
||||
|
||||
apply.newLine().append(")").endOfStatement();
|
||||
@@ -111,7 +122,8 @@ public class BaseTableDdl implements TableDdl {
|
||||
dropTable(writer.rollback(), tableName);
|
||||
|
||||
if (useSequence) {
|
||||
writeSequence(writer, createTable);
|
||||
String pkCol = singleColumnPrimaryKey ? pk.get(0).getName() : null;
|
||||
writeSequence(writer, createTable, pkCol);
|
||||
}
|
||||
|
||||
// add blank line for a bit of whitespace between tables
|
||||
@@ -133,30 +145,31 @@ public class BaseTableDdl implements TableDdl {
|
||||
private void writeUniqueOneToOneConstraints(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
|
||||
String tableName = createTable.getName();
|
||||
for (IndexColumns index : externalUnique.indexes) {
|
||||
String uqName = determineUniqueConstraintName(tableName, index.joinedNames());
|
||||
for (Column col : externalUnique) {
|
||||
String uqName = col.getUniqueOneToOne();
|
||||
String[] columnNames = {col.getName()};
|
||||
write.apply()
|
||||
.append(platformDdl.createExternalUniqueForOneToOne(uqName, tableName, index.columnsArray()))
|
||||
.append(platformDdl.createExternalUniqueForOneToOne(uqName, tableName, columnNames))
|
||||
.endOfStatement();
|
||||
|
||||
// register it so we check against effective duplication
|
||||
// when creating the foreign key indexes
|
||||
indexSet.add(index);
|
||||
|
||||
write.rollbackForeignKeys()
|
||||
.append(platformDdl.dropIndex(uqName, tableName))
|
||||
.endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSequence(DdlWrite writer, CreateTable createTable) throws IOException {
|
||||
private void writeSequence(DdlWrite writer, CreateTable createTable, String pk) throws IOException {
|
||||
|
||||
// explicit sequence use or platform decides
|
||||
String explicitSequenceName = createTable.getSequenceName();
|
||||
int initial = toInt(createTable.getSequenceInitial());
|
||||
int allocate = toInt(createTable.getSequenceAllocate());
|
||||
|
||||
String seqName = namingConvention.sequenceName(createTable.getName(), explicitSequenceName);
|
||||
String seqName = explicitSequenceName;
|
||||
if (seqName == null) {
|
||||
seqName = namingConvention.getSequenceName(createTable.getName(), pk);
|
||||
}
|
||||
|
||||
String createSeq = platformDdl.createSequence(seqName, initial, allocate);
|
||||
if (createSeq != null) {
|
||||
writer.apply().append(createSeq).newLine();
|
||||
@@ -177,7 +190,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
for (Column column : columns) {
|
||||
String references = column.getReferences();
|
||||
if (hasValue(references)) {
|
||||
writeForeignKey(write, tableName, column.getName(), references);
|
||||
writeForeignKey(write, tableName, column);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,19 +205,19 @@ public class BaseTableDdl implements TableDdl {
|
||||
for (ForeignKey key : foreignKey) {
|
||||
|
||||
String refTableName = key.getRefTableName();
|
||||
String fkName = determineForeignKeyConstraintName(tableName, refTableName);
|
||||
String fkName = key.getName();
|
||||
String[] cols = toColumnNamesSplit(key.getColumnNames());
|
||||
String[] refColumns = toColumnNamesSplit(key.getRefColumnNames());
|
||||
|
||||
writeForeignKey(write, fkName, tableName, cols, refTableName, refColumns);
|
||||
writeForeignKey(write, fkName, tableName, cols, refTableName, refColumns, key.getIndexName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, String tableName, String columnName, String references) throws IOException {
|
||||
|
||||
String fkName = determineForeignKeyConstraintName(tableName, columnName);
|
||||
protected void writeForeignKey(DdlWrite write, String tableName, Column column) throws IOException {
|
||||
|
||||
String fkName = column.getForeignKeyName();
|
||||
String references = column.getReferences();
|
||||
int pos = references.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
throw new IllegalStateException("Expecting period '.' character for table.column split but not found in [" + references + "]");
|
||||
@@ -212,13 +225,13 @@ public class BaseTableDdl implements TableDdl {
|
||||
String refTableName = references.substring(0, pos);
|
||||
String refColumnName = references.substring(pos + 1);
|
||||
|
||||
String[] cols = {columnName};
|
||||
String[] cols = {column.getName()};
|
||||
String[] refCols = {refColumnName};
|
||||
|
||||
writeForeignKey(write, fkName, tableName, cols, refTableName, refCols);
|
||||
writeForeignKey(write, fkName, tableName, cols, refTableName, refCols, column.getForeignKeyIndex());
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, String fkName, String tableName, String[] columns, String refTable, String[] refColumns) throws IOException {
|
||||
protected void writeForeignKey(DdlWrite write, String fkName, String tableName, String[] columns, String refTable, String[] refColumns, String indexName) throws IOException {
|
||||
|
||||
tableName = lowerName(tableName);
|
||||
DdlBuffer fkeyBuffer = write.applyForeignKeys();
|
||||
@@ -234,10 +247,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
fkeyBuffer.appendWithSpace(platformDdl.getForeignKeyRestrict())
|
||||
.endOfStatement();
|
||||
|
||||
String indexName = determineForeignKeyIndexName(tableName, columns);
|
||||
|
||||
boolean addIndex = indexSet.add(columns);
|
||||
if (addIndex) {
|
||||
if (indexName != null) {
|
||||
// no matching unique constraint so add the index
|
||||
fkeyBuffer.append("create index ").append(indexName).append(" on ").append(tableName);
|
||||
appendColumns(columns, fkeyBuffer);
|
||||
@@ -250,7 +260,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
.append(platformDdl.alterTableDropForeignKey(tableName, fkName))
|
||||
.endOfStatement();
|
||||
|
||||
if (addIndex) {
|
||||
if (indexName != null) {
|
||||
write.rollbackForeignKeys()
|
||||
.append(platformDdl.dropIndex(indexName, tableName))
|
||||
.endOfStatement();
|
||||
@@ -289,7 +299,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
for (Column column : columns) {
|
||||
String checkConstraint = column.getCheckConstraint();
|
||||
if (hasValue(checkConstraint)) {
|
||||
writeCheckConstraint(apply, createTable.getName(), column, checkConstraint);
|
||||
writeCheckConstraint(apply, column, checkConstraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,9 +307,9 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Write a check constraint.
|
||||
*/
|
||||
protected void writeCheckConstraint(DdlBuffer buffer, String tableName, Column column, String checkConstraint) throws IOException {
|
||||
protected void writeCheckConstraint(DdlBuffer buffer, Column column, String checkConstraint) throws IOException {
|
||||
|
||||
String ckName = determineCheckConstraintName(tableName, column.getName());
|
||||
String ckName = column.getCheckConstraintName();
|
||||
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(ckName);
|
||||
@@ -319,11 +329,11 @@ public class BaseTableDdl implements TableDdl {
|
||||
|
||||
List<Column> columns = createTable.getColumn();
|
||||
for (Column column : columns) {
|
||||
if (isTrue(column.isUnique()) || (inlineUniqueOneToOne && isTrue(column.isUniqueOneToOne()))) {
|
||||
if (hasValue(column.getUnique()) || (inlineUniqueOneToOne && hasValue(column.getUniqueOneToOne()))) {
|
||||
// normal mechanism for adding unique constraint
|
||||
inlineUniqueConstraintSingle(apply, createTable.getName(), column);
|
||||
indexSet.add(column);
|
||||
} else if (!inlineUniqueOneToOne && isTrue(column.isUniqueOneToOne())) {
|
||||
inlineUniqueConstraintSingle(apply, column);
|
||||
|
||||
} else if (!inlineUniqueOneToOne && hasValue(column.getUniqueOneToOne())) {
|
||||
// MsSqlServer specific mechanism for adding unique constraints (that allow nulls)
|
||||
externalUnique.add(column);
|
||||
}
|
||||
@@ -333,9 +343,12 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Write the unique constraint inline with the create table statement.
|
||||
*/
|
||||
protected void inlineUniqueConstraintSingle(DdlBuffer buffer, String tableName, Column column) throws IOException {
|
||||
protected void inlineUniqueConstraintSingle(DdlBuffer buffer, Column column) throws IOException {
|
||||
|
||||
String uqName = determineUniqueConstraintName(tableName, column.getName());
|
||||
String uqName = column.getUnique();
|
||||
if (uqName == null) {
|
||||
uqName = column.getUniqueOneToOne();
|
||||
}
|
||||
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(uqName).append(" unique ");
|
||||
@@ -347,9 +360,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Write the primary key constraint inline with the create table statement.
|
||||
*/
|
||||
protected void writePrimaryKeyConstraint(DdlBuffer buffer, String tableName, String[] pkColumns) throws IOException {
|
||||
|
||||
String pkName = determinePrimaryKeyName(tableName);
|
||||
protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) throws IOException {
|
||||
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(pkName).append(" primary key");
|
||||
@@ -383,7 +394,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
* choice for column/table names.
|
||||
*/
|
||||
protected String lowerName(String name) {
|
||||
return platformDdl.lowerName(name);
|
||||
return naming.lowerName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,46 +426,6 @@ public class BaseTableDdl implements TableDdl {
|
||||
return platformDdl.convert(type, identity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary key constraint name.
|
||||
*/
|
||||
protected String determinePrimaryKeyName(String tableName) {
|
||||
|
||||
return namingConvention.primaryKeyName(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
protected String determineForeignKeyConstraintName(String tableName, String columnName) {
|
||||
|
||||
return namingConvention.foreignKeyConstraintName(tableName, columnName, ++countForeignKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
protected String determineForeignKeyIndexName(String tableName, String[] columns) {
|
||||
|
||||
return namingConvention.foreignKeyIndexName(tableName, columns, ++countIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
protected String determineUniqueConstraintName(String tableName, String columnName) {
|
||||
|
||||
return namingConvention.uniqueConstraintName(tableName, columnName, ++countUnique);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the constraint name.
|
||||
*/
|
||||
protected String determineCheckConstraintName(String tableName, String columnName) {
|
||||
|
||||
return namingConvention.checkConstraintName(tableName, columnName, ++countCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of columns that make the primary key.
|
||||
*/
|
||||
@@ -489,118 +460,4 @@ public class BaseTableDdl implements TableDdl {
|
||||
return (value == null) ? 0 : value.intValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The indexes held on the table.
|
||||
* <p>
|
||||
* Used to detect when we don't need to add an index on the foreign key columns
|
||||
* when there is an existing unique constraint with the same columns.
|
||||
*/
|
||||
protected static class IndexSet {
|
||||
|
||||
private List<IndexColumns> indexes = new ArrayList<IndexColumns>();
|
||||
|
||||
/**
|
||||
* Clear the indexes (for each table).
|
||||
*/
|
||||
public void clear() {
|
||||
indexes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index for the given column.
|
||||
*/
|
||||
public void add(Column column) {
|
||||
indexes.add(new IndexColumns(column));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if an index should be added for the given columns.
|
||||
* <p>
|
||||
* Returning false indicates there is an existing index (unique constraint) with these columns
|
||||
* and that an extra index should not be added.
|
||||
* </p>
|
||||
*/
|
||||
public boolean add(String[] columns) {
|
||||
IndexColumns newIndex = new IndexColumns(columns);
|
||||
for (int i = 0; i < indexes.size(); i++) {
|
||||
if (indexes.get(i).isMatch(newIndex)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
indexes.add(newIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the externally created unique constraint here so that we check later if foreign key indexes
|
||||
* don't need to be created (as the columns match this unique constraint).
|
||||
*/
|
||||
public void add(IndexColumns index) {
|
||||
indexes.add(index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of columns making up a particular index (column order is important).
|
||||
*/
|
||||
protected static class IndexColumns {
|
||||
|
||||
List<String> columns = new ArrayList<String>(4);
|
||||
|
||||
/**
|
||||
* Construct representing as a single column index.
|
||||
*/
|
||||
public IndexColumns(Column column) {
|
||||
columns.add(column.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct representing index.
|
||||
*/
|
||||
public IndexColumns(String[] columnNames) {
|
||||
for (int i = 0; i < columnNames.length; i++) {
|
||||
columns.add(columnNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there this index match (same columns same order).
|
||||
*/
|
||||
public boolean isMatch(IndexColumns other) {
|
||||
return columns.equals(other.columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a unique index based on the single column.
|
||||
*/
|
||||
protected void add(String column) {
|
||||
columns.add(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the columns as a string array.
|
||||
*/
|
||||
public String[] columnsArray() {
|
||||
return columns.toArray(new String[columns.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column names all joined with underscore.
|
||||
*/
|
||||
public String joinedNames() {
|
||||
if (columns.size() == 1) {
|
||||
return columns.get(0);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
sb.append("_");
|
||||
}
|
||||
sb.append(columns.get(i));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public class DB2Ddl extends PlatformDdl {
|
||||
public DB2Ddl(DbTypeMap platformTypes, DbIdentity dbIdentity) {
|
||||
super(platformTypes, dbIdentity);
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
this.maxConstraintNameLength = 18;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
/**
|
||||
* Naming convention used for constraint names.
|
||||
*/
|
||||
public class DdlNamingConvention {
|
||||
|
||||
protected String pkPrefix = "pk_";
|
||||
protected String pkSuffix = "";
|
||||
|
||||
protected String fkPrefix = "fk_";
|
||||
protected String fkMiddle = "_";
|
||||
protected String fkSuffix = "";
|
||||
|
||||
protected String fkIndexPrefix = "ix_";
|
||||
protected String fkIndexMiddle = "_";
|
||||
protected String fkIndexSuffix = "";
|
||||
|
||||
protected String uqPrefix = "uq_";
|
||||
protected String uqSuffix = "";
|
||||
|
||||
protected String ckPrefix = "ck_";
|
||||
protected String ckSuffix = "";
|
||||
|
||||
protected int maxConstraintNameLength = 32;
|
||||
|
||||
protected boolean lowerCaseNames = true;
|
||||
|
||||
protected DdlNameNormalise normalise = new DdlNameNormalise();
|
||||
|
||||
public DdlNamingConvention() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary key constraint name.
|
||||
*/
|
||||
public String primaryKeyName(String tableName) {
|
||||
|
||||
return maxLength(pkPrefix + normaliseTable(tableName) + pkSuffix, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
public String foreignKeyConstraintName(String tableName, String columnName, int foreignKeyCount) {
|
||||
return maxLength(fkPrefix + normaliseTable(tableName) + fkMiddle + normaliseColumn(columnName) + fkSuffix, foreignKeyCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index name associated with a foreign key constraint given a single column foreign key.
|
||||
*/
|
||||
public String foreignKeyIndexName(String tableName, String[] columns, int indexCount) {
|
||||
|
||||
String colPart;
|
||||
if (columns.length == 1) {
|
||||
colPart = normaliseColumn(columns[0]);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append("_");
|
||||
}
|
||||
sb.append(normaliseColumn(columns[i]));
|
||||
}
|
||||
colPart = sb.toString();
|
||||
}
|
||||
return maxLength(fkIndexPrefix + normaliseTable(tableName) + fkIndexMiddle + colPart + fkIndexSuffix, indexCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
public String uniqueConstraintName(String tableName, String columnName, int indexCount) {
|
||||
|
||||
return maxLength(uqPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + uqSuffix, indexCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the check constraint name.
|
||||
*/
|
||||
public String checkConstraintName(String tableName, String columnName, int checkCount) {
|
||||
|
||||
return maxLength(ckPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + ckSuffix, checkCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sequence name. If it is explicitly provided return that but
|
||||
* otherwise derive the sequence name from the table name.
|
||||
*
|
||||
* @param tableName the table the sequence relates to
|
||||
* @param sequenceName an explicitly provided sequence name (typically null)
|
||||
* @return the sequence name to use
|
||||
*/
|
||||
public String sequenceName(String tableName, String sequenceName) {
|
||||
|
||||
return (sequenceName != null) ? lowerName(sequenceName) : normaliseTable(tableName) + "_seq";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum table name length.
|
||||
* <p>
|
||||
* This is used when deriving names of intersection tables.
|
||||
* </p>
|
||||
*/
|
||||
public int getMaxTableNameLength() {
|
||||
return maxConstraintNameLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a maximum length to the constraint name.
|
||||
*/
|
||||
protected String maxLength(String constraintName, int count) {
|
||||
if (constraintName.length() < maxConstraintNameLength) {
|
||||
return constraintName;
|
||||
}
|
||||
// add the count to ensure the constraint name is unique
|
||||
// (relying on the prefix having the table name to be globally unique)
|
||||
return constraintName.substring(0, maxConstraintNameLength - 3) + "_" + count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise the table name by trimming catalog and schema and removing any
|
||||
* quoted identifier characters (",',[,] etc).
|
||||
*/
|
||||
protected String normaliseTable(String tableName) {
|
||||
|
||||
return normalise.normaliseTable(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise the column name by removing any quoted identifier characters (",',[,] etc).
|
||||
*/
|
||||
protected String normaliseColumn(String tableName) {
|
||||
|
||||
return normalise.normaliseColumn(tableName);
|
||||
}
|
||||
|
||||
public String lowerName(String tableName) {
|
||||
if (lowerCaseNames && normalise.notQuoted(tableName)) {
|
||||
return tableName.toLowerCase();
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,6 @@ public class H2Ddl extends PlatformDdl {
|
||||
|
||||
public H2Ddl(DbTypeMap platformTypes, DbIdentity dbIdentity) {
|
||||
super(platformTypes, dbIdentity);
|
||||
this.historyDdl = new H2HistoryDdl();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class H2HistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
// does nothing, not supported yet
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ public class MsSqlServerDdl extends PlatformDdl {
|
||||
this.identitySuffix = " identity(1,1)";
|
||||
this.foreignKeyRestrict = "";
|
||||
this.inlineUniqueOneToOne = false;
|
||||
this.namingConvention.maxConstraintNameLength = 62; //Actually 128
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,6 @@ public class MySqlDdl extends PlatformDdl {
|
||||
|
||||
public MySqlDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) {
|
||||
super(platformTypes, dbIdentity);
|
||||
this.namingConvention.maxConstraintNameLength = 64;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,6 +23,7 @@ public class MySqlDdl extends PlatformDdl {
|
||||
/**
|
||||
* Return the drop foreign key clause.
|
||||
*/
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return "alter table " + tableName + " drop foreign key " + fkName;
|
||||
}
|
||||
|
||||
+6
-1
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
@@ -12,8 +13,12 @@ import java.io.IOException;
|
||||
public class NoHistorySupportDdl implements PlatformHistoryDdl {
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
public void configure(ServerConfig serverConfig) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
// does nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,10 @@ public class Oracle10Ddl extends PlatformDdl {
|
||||
|
||||
public Oracle10Ddl(DbTypeMap platformTypes, DbIdentity dbIdentity) {
|
||||
super(platformTypes, dbIdentity);
|
||||
this.historyDdl = new H2HistoryDdl();
|
||||
this.dropTableIfExists = "drop table ";
|
||||
this.dropSequenceIfExists = "drop sequence ";
|
||||
this.dropTableCascade = " cascade constraints purge";
|
||||
this.namingConvention.maxConstraintNameLength = 30;
|
||||
this.maxConstraintNameLength = 30;
|
||||
this.foreignKeyRestrict = "";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.config.dbplatform.DbIdentity;
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
import com.avaje.ebean.config.dbplatform.IdType;
|
||||
@@ -7,6 +8,7 @@ import com.avaje.ebean.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.util.PlatformTypeConverter;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.util.VowelRemover;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.IdentityType;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
@@ -20,8 +22,6 @@ public class PlatformDdl {
|
||||
|
||||
protected PlatformHistoryDdl historyDdl = new NoHistorySupportDdl();
|
||||
|
||||
protected DdlNamingConvention namingConvention = new DdlNamingConvention();
|
||||
|
||||
/**
|
||||
* Converter for logical/standard types to platform specific types. (eg. clob -> text)
|
||||
*/
|
||||
@@ -48,18 +48,50 @@ public class PlatformDdl {
|
||||
|
||||
protected String identitySuffix = " auto_increment";
|
||||
|
||||
protected String dropConstraintIfExists = "drop constraint if exists";
|
||||
|
||||
protected String dropIndexIfExists = "drop index if exists ";
|
||||
|
||||
/**
|
||||
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
|
||||
*/
|
||||
protected boolean inlineUniqueOneToOne = true;
|
||||
|
||||
/**
|
||||
* A value of 60 is a reasonable default for all databases except
|
||||
* Oracle (limited to 30) and DB2 (limited to 18).
|
||||
*/
|
||||
protected int maxConstraintNameLength = 60;
|
||||
|
||||
public PlatformDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) {
|
||||
this.dbIdentity = dbIdentity;
|
||||
this.typeConverter = new PlatformTypeConverter(platformTypes);
|
||||
}
|
||||
|
||||
public DdlHandler createDdlHandler() {
|
||||
return new BaseDdlHandler(namingConvention, this);
|
||||
public DdlHandler createDdlHandler(ServerConfig serverConfig) {
|
||||
historyDdl.configure(serverConfig);
|
||||
return new BaseDdlHandler(serverConfig.getNamingConvention(), serverConfig.getConstraintNaming(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a maximum length to the constraint name.
|
||||
* <p>
|
||||
* This implementation should work well apart from perhaps DB2 where the limit is 18.
|
||||
*/
|
||||
public String maxLength(String constraintName, int count) {
|
||||
if (constraintName.length() < maxConstraintNameLength) {
|
||||
return constraintName;
|
||||
}
|
||||
if (maxConstraintNameLength < 60) {
|
||||
// trim out vowels for Oracle / DB2 with short max lengths
|
||||
constraintName = VowelRemover.trim(constraintName, 4);
|
||||
if (constraintName.length() < maxConstraintNameLength) {
|
||||
return constraintName;
|
||||
}
|
||||
}
|
||||
// add the count to ensure the constraint name is unique
|
||||
// (relying on the prefix having the table name to be globally unique)
|
||||
return constraintName.substring(0, maxConstraintNameLength - 3) + "_" + count;
|
||||
}
|
||||
|
||||
public IdType useIdentityType(IdentityType modelIdentityType) {
|
||||
@@ -85,7 +117,7 @@ public class PlatformDdl {
|
||||
* Return the drop foreign key clause.
|
||||
*/
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return "alter table " + tableName + " drop constraint " + fkName;
|
||||
return "alter table " + tableName + " " + dropConstraintIfExists + " " + fkName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,28 +172,9 @@ public class PlatformDdl {
|
||||
* Return the drop index statement.
|
||||
*/
|
||||
public String dropIndex(String indexName, String tableName) {
|
||||
return "drop index "+indexName;
|
||||
return dropIndexIfExists + indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support lower naming tables and columns in DDL generation.
|
||||
* Tables/Columns with quoted identifiers are exempt.
|
||||
*/
|
||||
public String lowerName(String name) {
|
||||
return namingConvention.lowerName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum table name length.
|
||||
* <p>
|
||||
* This is used when deriving names of intersection tables.
|
||||
* </p>
|
||||
*/
|
||||
public int getMaxTableNameLength() {
|
||||
return namingConvention.getMaxTableNameLength();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if unique constraints for OneToOne can be inlined as normal.
|
||||
* Returns false for MsSqlServer due to it's null handling for unique constraints.
|
||||
|
||||
+8
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
@@ -10,8 +11,15 @@ import java.io.IOException;
|
||||
*/
|
||||
public interface PlatformHistoryDdl {
|
||||
|
||||
/**
|
||||
* Configure typically reading the
|
||||
* @param serverConfig
|
||||
*/
|
||||
void configure(ServerConfig serverConfig);
|
||||
|
||||
/**
|
||||
* Add history support to the table using platform specific mechanism.
|
||||
*/
|
||||
void createWithHistory(DdlWrite writer, MTable table) throws IOException;
|
||||
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ public class PostgresDdl extends PlatformDdl {
|
||||
|
||||
public PostgresDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) {
|
||||
super(platformTypes, dbIdentity);
|
||||
this.historyDdl = new PostgresHistoryDdl(this.namingConvention.normalise);
|
||||
this.historyDdl = new PostgresHistoryDdl();
|
||||
this.dropTableCascade = " cascade";
|
||||
this.namingConvention.maxConstraintNameLength = 62;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+38
-25
@@ -1,5 +1,7 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.DbConstraintNaming;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MColumn;
|
||||
@@ -9,18 +11,38 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
*
|
||||
* Uses DB triggers to maintain a history table.
|
||||
*/
|
||||
public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
private final DdlNameNormalise normalise;
|
||||
private DbConstraintNaming constraintNaming;
|
||||
|
||||
public PostgresHistoryDdl(DdlNameNormalise normalise) {
|
||||
this.normalise = normalise;
|
||||
private String sysPeriod;
|
||||
|
||||
private String viewSuffix;
|
||||
|
||||
private String historySuffix = "_history";
|
||||
|
||||
public PostgresHistoryDdl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(ServerConfig serverConfig) {
|
||||
this.sysPeriod = serverConfig.getAsOfSysPeriod();
|
||||
this.viewSuffix = serverConfig.getAsOfViewSuffix();
|
||||
this.constraintNaming = serverConfig.getConstraintNaming();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
addHistoryTable(writer, table);
|
||||
addStoredFunction(writer, table);
|
||||
addTrigger(writer, table);
|
||||
}
|
||||
|
||||
protected String historyTableName(String baseTableName) {
|
||||
return baseTableName + "_history";
|
||||
return baseTableName + historySuffix;
|
||||
}
|
||||
|
||||
protected String procedureName(String baseTableName) {
|
||||
@@ -31,42 +53,33 @@ public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
return baseTableName + "_history_upd";
|
||||
}
|
||||
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
// naming convention
|
||||
|
||||
addHistoryTable(writer, table);
|
||||
addStoredFunction(writer, table);
|
||||
addTrigger(writer, table);
|
||||
}
|
||||
|
||||
public void addHistoryTable(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = this.normalise.normaliseTable(table.getName());
|
||||
String baseTableName = constraintNaming.normaliseTable(table.getName());
|
||||
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
|
||||
buffer
|
||||
.append("alter table ").append(baseTableName)
|
||||
.append(" add column sys_period tstzrange not null")
|
||||
.append(" add column ").append(sysPeriod).append(" tstzrange not null")
|
||||
.endOfStatement().end();
|
||||
|
||||
buffer
|
||||
.append("create table ").append(baseTableName).append("_history")
|
||||
.append("create table ").append(baseTableName).append(historySuffix)
|
||||
.append(" (like ").append(baseTableName).append(")")
|
||||
.endOfStatement().end();
|
||||
|
||||
buffer
|
||||
.append("create view ").append(baseTableName).append("_with_history")
|
||||
.append("create view ").append(baseTableName).append(viewSuffix)
|
||||
.append(" as select * from").append(baseTableName)
|
||||
.append(" union all select * from").append(baseTableName).append("_history")
|
||||
.append(" union all select * from").append(baseTableName).append(historySuffix)
|
||||
.endOfStatement().end();
|
||||
|
||||
}
|
||||
|
||||
public void addTrigger(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = this.normalise.normaliseTable(table.getName());
|
||||
String baseTableName = constraintNaming.normaliseTable(table.getName());
|
||||
String procedureName = procedureName(baseTableName);
|
||||
String triggerName = triggerName(baseTableName);
|
||||
|
||||
@@ -81,7 +94,7 @@ public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
public void addStoredFunction(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = this.normalise.normaliseTable(table.getName());
|
||||
String baseTableName = constraintNaming.normaliseTable(table.getName());
|
||||
String procedureName = procedureName(baseTableName);
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
|
||||
@@ -90,13 +103,13 @@ public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
.append("begin").newLine();
|
||||
buffer
|
||||
.append(" if (TG_OP = 'INSERT') then").newLine()
|
||||
.append(" NEW.sys_period = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" NEW.").append(sysPeriod).append(" = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" return new;").newLine().newLine();
|
||||
buffer
|
||||
.append(" elsif (TG_OP = 'UPDATE') then").newLine();
|
||||
appendInsertIntoHistory(buffer, table);
|
||||
buffer
|
||||
.append(" NEW.sys_period = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" NEW.").append(sysPeriod).append(" = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" return new;").newLine().newLine();
|
||||
buffer
|
||||
.append(" elsif (TG_OP = 'DELETE') then").newLine();
|
||||
@@ -116,9 +129,9 @@ public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
String historyTable = historyTableName(table.getName());
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (sys_period,");
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriod).append(",");
|
||||
appendColumnNames(buffer, table, "");
|
||||
buffer.append(") values (tstzrange(lower(OLD.sys_period), CURRENT_TIMESTAMP), ");
|
||||
buffer.append(") values (tstzrange(lower(OLD.").append(sysPeriod).append("), CURRENT_TIMESTAMP), ");
|
||||
appendColumnNames(buffer, table, "OLD.");
|
||||
buffer.append(");").newLine();
|
||||
}
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Set of columns making up a particular index (column order is important).
|
||||
*/
|
||||
public class IndexColumns {
|
||||
|
||||
List<String> columns = new ArrayList<String>(4);
|
||||
|
||||
/**
|
||||
* Construct representing as a single column index.
|
||||
*/
|
||||
public IndexColumns(String column) {
|
||||
columns.add(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct representing index.
|
||||
*/
|
||||
public IndexColumns(String[] columnNames) {
|
||||
for (int i = 0; i < columnNames.length; i++) {
|
||||
columns.add(columnNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this index matches (same single column).
|
||||
*/
|
||||
public boolean isMatch(String singleColumn) {
|
||||
return columns.size() == 1 && columns.get(0).equals(singleColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this index matches (same single column).
|
||||
*/
|
||||
public boolean isMatch(List<String> columnNames) {
|
||||
if (columns.size() != columnNames.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i <columns.size() ; i++) {
|
||||
if (!columns.get(i).equals(columnNames.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this index matches (same columns same order).
|
||||
*/
|
||||
public boolean isMatch(IndexColumns other) {
|
||||
return columns.equals(other.columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a unique index based on the single column.
|
||||
*/
|
||||
protected void add(String column) {
|
||||
columns.add(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the columns as a string array.
|
||||
*/
|
||||
public String[] columnsArray() {
|
||||
return columns.toArray(new String[columns.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column names all joined with underscore.
|
||||
*/
|
||||
public String joinedNames() {
|
||||
if (columns.size() == 1) {
|
||||
return columns.get(0);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
sb.append("_");
|
||||
}
|
||||
sb.append(columns.get(i));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform.util;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The indexes held on the table.
|
||||
* <p>
|
||||
* Used to detect when we don't need to add an index on the foreign key columns
|
||||
* when there is an existing unique constraint with the same columns.
|
||||
*/
|
||||
public class IndexSet {
|
||||
|
||||
private List<IndexColumns> indexes = new ArrayList<IndexColumns>();
|
||||
|
||||
/**
|
||||
* Clear the indexes (for each table).
|
||||
*/
|
||||
public void clear() {
|
||||
indexes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index for the given column.
|
||||
*/
|
||||
public void add(String column) {
|
||||
indexes.add(new IndexColumns(column));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if an index should be added for the given columns.
|
||||
* <p>
|
||||
* Returning false indicates there is an existing index (unique constraint) with these columns
|
||||
* and that an extra index should not be added.
|
||||
* </p>
|
||||
*/
|
||||
public boolean add(String[] columns) {
|
||||
IndexColumns newIndex = new IndexColumns(columns);
|
||||
for (int i = 0; i < indexes.size(); i++) {
|
||||
if (indexes.get(i).isMatch(newIndex)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
indexes.add(newIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the externally created unique constraint here so that we check later if foreign key indexes
|
||||
* don't need to be created (as the columns match this unique constraint).
|
||||
*/
|
||||
public void add(IndexColumns index) {
|
||||
indexes.add(index);
|
||||
}
|
||||
|
||||
public boolean contains(String column) {
|
||||
|
||||
for (IndexColumns index : indexes) {
|
||||
if (index.isMatch(column)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(List<String> columns) {
|
||||
|
||||
for (IndexColumns index : indexes) {
|
||||
if (index.isMatch(columns)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<IndexColumns> getIndexes() {
|
||||
return indexes;
|
||||
}
|
||||
|
||||
public void addIndex(Column column) {
|
||||
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform.util;
|
||||
|
||||
/**
|
||||
* Utility to remove vowels (from constraint names primarily for Oracle and DB2).
|
||||
*/
|
||||
public class VowelRemover {
|
||||
|
||||
/**
|
||||
* Trim a word by removing vowels skipping some initial characters.
|
||||
*/
|
||||
public static String trim(String word, int skipChars) {
|
||||
|
||||
if (word.length() < skipChars) {
|
||||
return word;
|
||||
}
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
res.append(word.substring(0, skipChars));
|
||||
|
||||
for (int i = skipChars; i < word.length(); i++) {
|
||||
char ch = word.charAt(i);
|
||||
if (!isVowel(ch)) {
|
||||
res.append(ch);
|
||||
}
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
private static boolean isVowel(char ch) {
|
||||
ch = Character.toLowerCase(ch);
|
||||
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
|
||||
}
|
||||
}
|
||||
@@ -20,16 +20,20 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <attribute name="columnName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="defaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="oldDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="oldCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="oldReferences" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newReferences" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="checkConstraintName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropUnique" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="references" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyIndex" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropForeignKey" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropForeignKeyIndex" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
@@ -48,26 +52,34 @@ public class AlterColumn {
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "type")
|
||||
protected String type;
|
||||
@XmlAttribute(name = "defaultValue")
|
||||
protected String defaultValue;
|
||||
@XmlAttribute(name = "notnull")
|
||||
protected Boolean notnull;
|
||||
@XmlAttribute(name = "historyExclude")
|
||||
protected Boolean historyExclude;
|
||||
@XmlAttribute(name = "checkConstraint")
|
||||
protected String checkConstraint;
|
||||
@XmlAttribute(name = "checkConstraintName")
|
||||
protected String checkConstraintName;
|
||||
@XmlAttribute(name = "dropCheckConstraint")
|
||||
protected String dropCheckConstraint;
|
||||
@XmlAttribute(name = "unique")
|
||||
protected Boolean unique;
|
||||
protected String unique;
|
||||
@XmlAttribute(name = "uniqueOneToOne")
|
||||
protected Boolean uniqueOneToOne;
|
||||
@XmlAttribute(name = "oldDefaultValue")
|
||||
protected String oldDefaultValue;
|
||||
@XmlAttribute(name = "newDefaultValue")
|
||||
protected String newDefaultValue;
|
||||
@XmlAttribute(name = "oldCheckConstraint")
|
||||
protected String oldCheckConstraint;
|
||||
@XmlAttribute(name = "newCheckConstraint")
|
||||
protected String newCheckConstraint;
|
||||
@XmlAttribute(name = "oldReferences")
|
||||
protected String oldReferences;
|
||||
@XmlAttribute(name = "newReferences")
|
||||
protected String newReferences;
|
||||
protected String uniqueOneToOne;
|
||||
@XmlAttribute(name = "dropUnique")
|
||||
protected String dropUnique;
|
||||
@XmlAttribute(name = "references")
|
||||
protected String references;
|
||||
@XmlAttribute(name = "foreignKeyName")
|
||||
protected String foreignKeyName;
|
||||
@XmlAttribute(name = "foreignKeyIndex")
|
||||
protected String foreignKeyIndex;
|
||||
@XmlAttribute(name = "dropForeignKey")
|
||||
protected String dropForeignKey;
|
||||
@XmlAttribute(name = "dropForeignKeyIndex")
|
||||
protected String dropForeignKeyIndex;
|
||||
|
||||
/**
|
||||
* Gets the value of the columnName property.
|
||||
@@ -141,6 +153,30 @@ public class AlterColumn {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the defaultValue property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the defaultValue property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setDefaultValue(String value) {
|
||||
this.defaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the notnull property.
|
||||
*
|
||||
@@ -189,15 +225,87 @@ public class AlterColumn {
|
||||
this.historyExclude = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraint property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraint property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCheckConstraint(String value) {
|
||||
this.checkConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraintName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCheckConstraintName() {
|
||||
return checkConstraintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraintName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCheckConstraintName(String value) {
|
||||
this.checkConstraintName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dropCheckConstraint property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getDropCheckConstraint() {
|
||||
return dropCheckConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dropCheckConstraint property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setDropCheckConstraint(String value) {
|
||||
this.dropCheckConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the unique property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public Boolean isUnique() {
|
||||
public String getUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
@@ -206,10 +314,10 @@ public class AlterColumn {
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setUnique(Boolean value) {
|
||||
public void setUnique(String value) {
|
||||
this.unique = value;
|
||||
}
|
||||
|
||||
@@ -218,10 +326,10 @@ public class AlterColumn {
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public Boolean isUniqueOneToOne() {
|
||||
public String getUniqueOneToOne() {
|
||||
return uniqueOneToOne;
|
||||
}
|
||||
|
||||
@@ -230,155 +338,155 @@ public class AlterColumn {
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setUniqueOneToOne(Boolean value) {
|
||||
public void setUniqueOneToOne(String value) {
|
||||
this.uniqueOneToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the oldDefaultValue property.
|
||||
* Gets the value of the dropUnique property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getOldDefaultValue() {
|
||||
return oldDefaultValue;
|
||||
public String getDropUnique() {
|
||||
return dropUnique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldDefaultValue property.
|
||||
* Sets the value of the dropUnique property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setOldDefaultValue(String value) {
|
||||
this.oldDefaultValue = value;
|
||||
public void setDropUnique(String value) {
|
||||
this.dropUnique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newDefaultValue property.
|
||||
* Gets the value of the references property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getNewDefaultValue() {
|
||||
return newDefaultValue;
|
||||
public String getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newDefaultValue property.
|
||||
* Sets the value of the references property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setNewDefaultValue(String value) {
|
||||
this.newDefaultValue = value;
|
||||
public void setReferences(String value) {
|
||||
this.references = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the oldCheckConstraint property.
|
||||
* Gets the value of the foreignKeyName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getOldCheckConstraint() {
|
||||
return oldCheckConstraint;
|
||||
public String getForeignKeyName() {
|
||||
return foreignKeyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldCheckConstraint property.
|
||||
* Sets the value of the foreignKeyName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setOldCheckConstraint(String value) {
|
||||
this.oldCheckConstraint = value;
|
||||
public void setForeignKeyName(String value) {
|
||||
this.foreignKeyName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newCheckConstraint property.
|
||||
* Gets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getNewCheckConstraint() {
|
||||
return newCheckConstraint;
|
||||
public String getForeignKeyIndex() {
|
||||
return foreignKeyIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newCheckConstraint property.
|
||||
* Sets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setNewCheckConstraint(String value) {
|
||||
this.newCheckConstraint = value;
|
||||
public void setForeignKeyIndex(String value) {
|
||||
this.foreignKeyIndex = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the oldReferences property.
|
||||
* Gets the value of the dropForeignKey property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getOldReferences() {
|
||||
return oldReferences;
|
||||
public String getDropForeignKey() {
|
||||
return dropForeignKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldReferences property.
|
||||
* Sets the value of the dropForeignKey property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setOldReferences(String value) {
|
||||
this.oldReferences = value;
|
||||
public void setDropForeignKey(String value) {
|
||||
this.dropForeignKey = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newReferences property.
|
||||
* Gets the value of the dropForeignKeyIndex property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getNewReferences() {
|
||||
return newReferences;
|
||||
public String getDropForeignKeyIndex() {
|
||||
return dropForeignKeyIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newReferences property.
|
||||
* Sets the value of the dropForeignKeyIndex property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setNewReferences(String value) {
|
||||
this.newReferences = value;
|
||||
public void setDropForeignKeyIndex(String value) {
|
||||
this.dropForeignKeyIndex = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,13 +22,16 @@ import javax.xml.bind.annotation.XmlValue;
|
||||
* <attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="defaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="primaryKey" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="identity" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="checkConstraintName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="references" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyIndex" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="comment" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
@@ -54,20 +57,26 @@ public class Column {
|
||||
protected String defaultValue;
|
||||
@XmlAttribute(name = "notnull")
|
||||
protected Boolean notnull;
|
||||
@XmlAttribute(name = "checkConstraint")
|
||||
protected String checkConstraint;
|
||||
@XmlAttribute(name = "historyExclude")
|
||||
protected Boolean historyExclude;
|
||||
@XmlAttribute(name = "unique")
|
||||
protected Boolean unique;
|
||||
@XmlAttribute(name = "uniqueOneToOne")
|
||||
protected Boolean uniqueOneToOne;
|
||||
@XmlAttribute(name = "primaryKey")
|
||||
protected Boolean primaryKey;
|
||||
@XmlAttribute(name = "identity")
|
||||
protected Boolean identity;
|
||||
@XmlAttribute(name = "checkConstraint")
|
||||
protected String checkConstraint;
|
||||
@XmlAttribute(name = "checkConstraintName")
|
||||
protected String checkConstraintName;
|
||||
@XmlAttribute(name = "unique")
|
||||
protected String unique;
|
||||
@XmlAttribute(name = "uniqueOneToOne")
|
||||
protected String uniqueOneToOne;
|
||||
@XmlAttribute(name = "references")
|
||||
protected String references;
|
||||
@XmlAttribute(name = "foreignKeyName")
|
||||
protected String foreignKeyName;
|
||||
@XmlAttribute(name = "foreignKeyIndex")
|
||||
protected String foreignKeyIndex;
|
||||
@XmlAttribute(name = "comment")
|
||||
protected String comment;
|
||||
|
||||
@@ -191,30 +200,6 @@ public class Column {
|
||||
this.notnull = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraint property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraint property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCheckConstraint(String value) {
|
||||
this.checkConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the historyExclude property.
|
||||
*
|
||||
@@ -239,54 +224,6 @@ public class Column {
|
||||
this.historyExclude = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the unique property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the unique property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setUnique(Boolean value) {
|
||||
this.unique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isUniqueOneToOne() {
|
||||
return uniqueOneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setUniqueOneToOne(Boolean value) {
|
||||
this.uniqueOneToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the primaryKey property.
|
||||
*
|
||||
@@ -335,6 +272,102 @@ public class Column {
|
||||
this.identity = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraint property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraint property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCheckConstraint(String value) {
|
||||
this.checkConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraintName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCheckConstraintName() {
|
||||
return checkConstraintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraintName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCheckConstraintName(String value) {
|
||||
this.checkConstraintName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the unique property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the unique property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setUnique(String value) {
|
||||
this.unique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getUniqueOneToOne() {
|
||||
return uniqueOneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setUniqueOneToOne(String value) {
|
||||
this.uniqueOneToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the references property.
|
||||
*
|
||||
@@ -359,6 +392,54 @@ public class Column {
|
||||
this.references = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getForeignKeyName() {
|
||||
return foreignKeyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setForeignKeyName(String value) {
|
||||
this.foreignKeyName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getForeignKeyIndex() {
|
||||
return foreignKeyIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setForeignKeyIndex(String value) {
|
||||
this.foreignKeyIndex = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the comment property.
|
||||
*
|
||||
|
||||
@@ -34,6 +34,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <attribute name="sequenceName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="sequenceInitial" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="sequenceAllocate" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="pkName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
@@ -68,6 +69,8 @@ public class CreateTable {
|
||||
@XmlAttribute(name = "sequenceAllocate")
|
||||
@XmlSchemaType(name = "positiveInteger")
|
||||
protected BigInteger sequenceAllocate;
|
||||
@XmlAttribute(name = "pkName")
|
||||
protected String pkName;
|
||||
@XmlAttribute(name = "tablespace")
|
||||
protected String tablespace;
|
||||
@XmlAttribute(name = "indexTablespace")
|
||||
@@ -306,6 +309,30 @@ public class CreateTable {
|
||||
this.sequenceAllocate = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the pkName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getPkName() {
|
||||
return pkName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the pkName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setPkName(String value) {
|
||||
this.pkName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tablespace property.
|
||||
*
|
||||
|
||||
@@ -17,9 +17,11 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="refColumnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="refTableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="indexName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
@@ -32,12 +34,40 @@ import javax.xml.bind.annotation.XmlType;
|
||||
@XmlRootElement(name = "foreignKey")
|
||||
public class ForeignKey {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "columnNames", required = true)
|
||||
protected String columnNames;
|
||||
@XmlAttribute(name = "refColumnNames", required = true)
|
||||
protected String refColumnNames;
|
||||
@XmlAttribute(name = "refTableName", required = true)
|
||||
protected String refTableName;
|
||||
@XmlAttribute(name = "indexName")
|
||||
protected String indexName;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columnNames property.
|
||||
@@ -111,4 +141,28 @@ public class ForeignKey {
|
||||
this.refTableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the indexName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setIndexName(String value) {
|
||||
this.indexName = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="constraintName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
@@ -31,10 +31,34 @@ import javax.xml.bind.annotation.XmlType;
|
||||
@XmlRootElement(name = "uniqueConstraint")
|
||||
public class UniqueConstraint {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "columnNames", required = true)
|
||||
protected String columnNames;
|
||||
@XmlAttribute(name = "constraintName")
|
||||
protected String constraintName;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columnNames property.
|
||||
@@ -60,28 +84,4 @@ public class UniqueConstraint {
|
||||
this.columnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the constraintName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getConstraintName() {
|
||||
return constraintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the constraintName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setConstraintName(String value) {
|
||||
this.constraintName = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.config.DbConstraintNaming;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
import com.avaje.ebean.dbmigration.migrationreader.MigrationXmlWriter;
|
||||
@@ -21,6 +23,10 @@ public class CurrentModel {
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
private final DbConstraintNaming constraintNaming;
|
||||
|
||||
private final PlatformDdl platformDdl;
|
||||
|
||||
private ModelContainer model;
|
||||
|
||||
private ChangeSet changeSet;
|
||||
@@ -32,6 +38,8 @@ public class CurrentModel {
|
||||
*/
|
||||
public CurrentModel(SpiEbeanServer server) {
|
||||
this.server = server;
|
||||
this.platformDdl = server.getDatabasePlatform().getPlatformDdl();
|
||||
this.constraintNaming = server.getServerConfig().getConstraintNaming();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +48,7 @@ public class CurrentModel {
|
||||
public ModelContainer read() {
|
||||
if (model == null) {
|
||||
model = new ModelContainer();
|
||||
ModelBuildContext context = new ModelBuildContext(model);
|
||||
ModelBuildContext context = new ModelBuildContext(model, constraintNaming, platformDdl);
|
||||
ModelBuildBeanVisitor visitor = new ModelBuildBeanVisitor(context);
|
||||
VisitAllUsing visit = new VisitAllUsing(visitor, server);
|
||||
visit.visitAllBeans();
|
||||
@@ -124,7 +132,7 @@ public class CurrentModel {
|
||||
* Return the platform specific DdlHandler (to generate DDL).
|
||||
*/
|
||||
private DdlHandler handler() {
|
||||
return server.getDatabasePlatform().createDdlHandler();
|
||||
return server.getDatabasePlatform().createDdlHandler(server.getServerConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,31 +11,39 @@ public class MColumn {
|
||||
private final String name;
|
||||
private final String type;
|
||||
private String checkConstraint;
|
||||
private String checkConstraintName;
|
||||
private String defaultValue;
|
||||
private String references;
|
||||
private String foreignKeyName;
|
||||
private String foreignKeyIndex;
|
||||
|
||||
private boolean historyExclude;
|
||||
private boolean notnull;
|
||||
private boolean primaryKey;
|
||||
private boolean identity;
|
||||
|
||||
private boolean unique;
|
||||
private String unique;
|
||||
|
||||
/**
|
||||
* Special unique for OneToOne as we need to handle that different
|
||||
* specifically for MsSqlServer.
|
||||
*/
|
||||
private boolean uniqueOneToOne;
|
||||
private String uniqueOneToOne;
|
||||
|
||||
public MColumn(Column column) {
|
||||
this.name = column.getName();
|
||||
this.type = column.getType();
|
||||
this.checkConstraint = column.getCheckConstraint();
|
||||
this.checkConstraintName = column.getCheckConstraintName();
|
||||
this.defaultValue = column.getDefaultValue();
|
||||
this.references = column.getReferences();
|
||||
this.foreignKeyName = column.getForeignKeyName();
|
||||
this.foreignKeyIndex = column.getForeignKeyIndex();
|
||||
this.notnull = Boolean.TRUE.equals(column.isNotnull());
|
||||
this.primaryKey = Boolean.TRUE.equals(column.isPrimaryKey());
|
||||
this.identity = Boolean.TRUE.equals(column.isIdentity());
|
||||
this.unique = Boolean.TRUE.equals(column.isUnique());
|
||||
this.unique = column.getUnique();
|
||||
this.uniqueOneToOne = column.getUniqueOneToOne();
|
||||
this.historyExclude = Boolean.TRUE.equals(column.isHistoryExclude());
|
||||
}
|
||||
|
||||
@@ -82,6 +90,30 @@ public class MColumn {
|
||||
this.checkConstraint = checkConstraint;
|
||||
}
|
||||
|
||||
public String getCheckConstraintName() {
|
||||
return checkConstraintName;
|
||||
}
|
||||
|
||||
public void setCheckConstraintName(String checkConstraintName) {
|
||||
this.checkConstraintName = checkConstraintName;
|
||||
}
|
||||
|
||||
public String getForeignKeyName() {
|
||||
return foreignKeyName;
|
||||
}
|
||||
|
||||
public void setForeignKeyName(String foreignKeyName) {
|
||||
this.foreignKeyName = foreignKeyName;
|
||||
}
|
||||
|
||||
public String getForeignKeyIndex() {
|
||||
return foreignKeyIndex;
|
||||
}
|
||||
|
||||
public void setForeignKeyIndex(String foreignKeyIndex) {
|
||||
this.foreignKeyIndex = foreignKeyIndex;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -114,11 +146,11 @@ public class MColumn {
|
||||
this.historyExclude = historyExclude;
|
||||
}
|
||||
|
||||
public void setUnique(boolean unique) {
|
||||
public void setUnique(String unique) {
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
public boolean isUnique() {
|
||||
public String getUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
@@ -126,14 +158,14 @@ public class MColumn {
|
||||
* Set unique specifically for OneToOne mapping.
|
||||
* We need special DDL for this case for MsSqlServer.
|
||||
*/
|
||||
public void setUniqueOneToOne(boolean uniqueOneToOne) {
|
||||
public void setUniqueOneToOne(String uniqueOneToOne) {
|
||||
this.uniqueOneToOne = uniqueOneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is unique for a OneToOne.
|
||||
*/
|
||||
public boolean isUniqueOneToOne() {
|
||||
public String getUniqueOneToOne() {
|
||||
return uniqueOneToOne;
|
||||
}
|
||||
|
||||
@@ -142,16 +174,20 @@ public class MColumn {
|
||||
Column c = new Column();
|
||||
c.setName(name);
|
||||
c.setType(type);
|
||||
|
||||
if (notnull) c.setNotnull(true);
|
||||
if (unique) c.setUnique(true);
|
||||
if (uniqueOneToOne) c.setUniqueOneToOne(true);
|
||||
if (primaryKey) c.setPrimaryKey(true);
|
||||
if (identity) c.setIdentity(true);
|
||||
if (historyExclude) c.setHistoryExclude(true);
|
||||
|
||||
c.setCheckConstraint(checkConstraint);
|
||||
c.setCheckConstraintName(checkConstraintName);
|
||||
c.setReferences(references);
|
||||
c.setForeignKeyName(foreignKeyName);
|
||||
c.setForeignKeyIndex(foreignKeyIndex);
|
||||
c.setDefaultValue(defaultValue);
|
||||
c.setUnique(unique);
|
||||
c.setUniqueOneToOne(uniqueOneToOne);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -160,6 +196,10 @@ public class MColumn {
|
||||
return (val1 == null) ? val2 != null : !val1.equals(val2);
|
||||
}
|
||||
|
||||
private boolean hasValue(String val) {
|
||||
return val != null && !val.isEmpty();
|
||||
}
|
||||
|
||||
AlterColumn alterColumn;
|
||||
|
||||
private AlterColumn getAlterColumn(String tableName) {
|
||||
@@ -175,6 +215,7 @@ public class MColumn {
|
||||
|
||||
String tableName = table.getName();
|
||||
|
||||
// set to null and check at the end
|
||||
this.alterColumn = null;
|
||||
|
||||
if (different(type, newColumn.type)) {
|
||||
@@ -188,27 +229,53 @@ public class MColumn {
|
||||
}
|
||||
if (different(defaultValue, newColumn.defaultValue)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
alter.setOldDefaultValue(defaultValue);
|
||||
alter.setNewDefaultValue(newColumn.defaultValue);
|
||||
}
|
||||
if (different(checkConstraint, newColumn.checkConstraint)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
alter.setOldCheckConstraint(checkConstraint);
|
||||
alter.setNewCheckConstraint(newColumn.checkConstraint);
|
||||
}
|
||||
if (different(references, newColumn.references)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
alter.setOldReferences(references);
|
||||
alter.setNewReferences(newColumn.references);
|
||||
alter.setDefaultValue(newColumn.defaultValue);
|
||||
}
|
||||
|
||||
if (unique != newColumn.unique) {
|
||||
if (different(checkConstraint, newColumn.checkConstraint)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
alter.setUnique(newColumn.unique);
|
||||
if (hasValue(checkConstraint)) {
|
||||
alter.setDropCheckConstraint(checkConstraintName);
|
||||
}
|
||||
if (hasValue(newColumn.checkConstraint)) {
|
||||
alter.setCheckConstraintName(newColumn.checkConstraintName);
|
||||
alter.setCheckConstraint(newColumn.checkConstraint);
|
||||
}
|
||||
}
|
||||
if (uniqueOneToOne != newColumn.uniqueOneToOne) {
|
||||
if (different(references, newColumn.references)) {
|
||||
// foreign key change
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
alter.setUniqueOneToOne(newColumn.uniqueOneToOne);
|
||||
if (hasValue(foreignKeyName)) {
|
||||
alter.setDropForeignKey(foreignKeyName);
|
||||
}
|
||||
if (hasValue(foreignKeyIndex)) {
|
||||
alter.setDropForeignKeyIndex(foreignKeyIndex);
|
||||
}
|
||||
if (hasValue(newColumn.references)) {
|
||||
// add new foreign key constraint
|
||||
alter.setReferences(newColumn.references);
|
||||
alter.setForeignKeyName(newColumn.foreignKeyName);
|
||||
alter.setForeignKeyIndex(newColumn.foreignKeyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (different(unique, newColumn.unique)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
if (hasValue(unique)) {
|
||||
alter.setDropUnique(unique);
|
||||
}
|
||||
if (hasValue(newColumn.unique)) {
|
||||
alter.setUnique(newColumn.unique);
|
||||
}
|
||||
}
|
||||
if (different(uniqueOneToOne, newColumn.uniqueOneToOne)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
if (hasValue(uniqueOneToOne)) {
|
||||
alter.setDropUnique(uniqueOneToOne);
|
||||
}
|
||||
if (hasValue(newColumn.uniqueOneToOne)) {
|
||||
alter.setUniqueOneToOne(newColumn.uniqueOneToOne);
|
||||
}
|
||||
}
|
||||
|
||||
if (alterColumn != null) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
import com.avaje.ebean.dbmigration.migration.ForeignKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -9,33 +8,60 @@ import java.util.List;
|
||||
/**
|
||||
* A unique constraint for multiple columns.
|
||||
* <p>
|
||||
* Note that unique constraint on a single column is instead
|
||||
* a boolean flag on the associated MColumn.
|
||||
* Note that unique constraint on a single column is instead
|
||||
* a boolean flag on the associated MColumn.
|
||||
* </p>
|
||||
*/
|
||||
public class MCompoundForeignKey {
|
||||
|
||||
private final String name;
|
||||
private final String referenceTable;
|
||||
private final List<String> columns = new ArrayList<String>();
|
||||
private final List<String> referenceColumns = new ArrayList<String>();
|
||||
private String indexName;
|
||||
|
||||
public MCompoundForeignKey(String referenceTable) {
|
||||
public MCompoundForeignKey(String name, String referenceTable, String indexName) {
|
||||
this.name = name;
|
||||
this.referenceTable = referenceTable;
|
||||
this.indexName = indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column pair of local and referenced column.
|
||||
*/
|
||||
public void addColumnPair(String dbCol, String refColumn) {
|
||||
columns.add(dbCol);
|
||||
referenceColumns.add(refColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return an ForeignKey migration element.
|
||||
*/
|
||||
public ForeignKey createForeignKey() {
|
||||
ForeignKey fk = new ForeignKey();
|
||||
fk.setName(name);
|
||||
fk.setIndexName(indexName);
|
||||
fk.setColumnNames(toColumnNames(columns));
|
||||
fk.setRefColumnNames(toColumnNames(referenceColumns));
|
||||
fk.setRefTableName(referenceTable);
|
||||
return fk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the columns making up the foreign key in order.
|
||||
*/
|
||||
public List<String> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the associated index name. Note that setting to null has the effect
|
||||
* of indicating an associated index should not be created for this foreign key.
|
||||
*/
|
||||
public void setIndexName(String indexName) {
|
||||
this.indexName = indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return as an array of string column names.
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,8 @@ package com.avaje.ebean.dbmigration.model;
|
||||
*/
|
||||
public class MCompoundUniqueConstraint {
|
||||
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Flag if true indicates this was specifically created for a OneToOne mapping.
|
||||
*/
|
||||
@@ -19,7 +21,8 @@ public class MCompoundUniqueConstraint {
|
||||
*/
|
||||
private final String[] columns;
|
||||
|
||||
public MCompoundUniqueConstraint(String[] columns, boolean oneToOne) {
|
||||
public MCompoundUniqueConstraint(String[] columns, boolean oneToOne, String name) {
|
||||
this.name = name;
|
||||
this.columns = columns;
|
||||
this.oneToOne = oneToOne;
|
||||
}
|
||||
@@ -38,4 +41,10 @@ public class MCompoundUniqueConstraint {
|
||||
return oneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the constraint name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ public class MTable {
|
||||
|
||||
private final String name;
|
||||
|
||||
private String pkName;
|
||||
|
||||
private String comment;
|
||||
|
||||
private String tablespace;
|
||||
@@ -65,6 +67,7 @@ public class MTable {
|
||||
*/
|
||||
public MTable(CreateTable createTable) {
|
||||
this.name = createTable.getName();
|
||||
this.pkName = createTable.getPkName();
|
||||
this.comment = createTable.getComment();
|
||||
this.tablespace = createTable.getTablespace();
|
||||
this.indexTablespace = createTable.getIndexTablespace();
|
||||
@@ -90,6 +93,7 @@ public class MTable {
|
||||
|
||||
CreateTable createTable = new CreateTable();
|
||||
createTable.setName(name);
|
||||
createTable.setPkName(pkName);
|
||||
createTable.setComment(comment);
|
||||
createTable.setTablespace(tablespace);
|
||||
createTable.setIndexTablespace(indexTablespace);
|
||||
@@ -165,6 +169,14 @@ public class MTable {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getPkName() {
|
||||
return pkName;
|
||||
}
|
||||
|
||||
public void setPkName(String pkName) {
|
||||
this.pkName = pkName;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
@@ -273,19 +285,19 @@ public class MTable {
|
||||
/**
|
||||
* Add a compound unique constraint.
|
||||
*/
|
||||
public void addCompoundUniqueConstraint(String[] columns, boolean oneToOne) {
|
||||
compoundUniqueConstraints.add(new MCompoundUniqueConstraint(columns, oneToOne));
|
||||
public void addCompoundUniqueConstraint(String[] columns, boolean oneToOne, String constraintName) {
|
||||
compoundUniqueConstraints.add(new MCompoundUniqueConstraint(columns, oneToOne, constraintName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a compound unique constraint.
|
||||
*/
|
||||
public void addCompoundUniqueConstraint(List<MColumn> columns, boolean oneToOne) {
|
||||
public void addCompoundUniqueConstraint(List<MColumn> columns, boolean oneToOne, String constraintName) {
|
||||
String[] cols = new String[columns.size()];
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
cols[i] = columns.get(i).getName();
|
||||
}
|
||||
addCompoundUniqueConstraint(cols, oneToOne);
|
||||
addCompoundUniqueConstraint(cols, oneToOne, constraintName);
|
||||
}
|
||||
|
||||
public void addForeignKey(MCompoundForeignKey compoundKey) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.BeanPropertyVisitor;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.BeanVisitor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.CompoundUniqueContraint;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
|
||||
/**
|
||||
@@ -52,14 +51,7 @@ public class ModelBuildBeanVisitor implements BeanVisitor {
|
||||
table.addColumn(new MColumn(discColumn, discDbType, true));
|
||||
}
|
||||
|
||||
CompoundUniqueContraint[] compoundUniqueConstraints = descriptor.getCompoundUniqueConstraints();
|
||||
if (compoundUniqueConstraints != null) {
|
||||
for (int i = 0; i < compoundUniqueConstraints.length; i++) {
|
||||
table.addCompoundUniqueConstraint(compoundUniqueConstraints[i].getColumns(), false);
|
||||
}
|
||||
}
|
||||
|
||||
return new ModelBuildPropertyVisitor(ctx, table);
|
||||
return new ModelBuildPropertyVisitor(ctx, table, descriptor.getCompoundUniqueConstraints());
|
||||
}
|
||||
|
||||
private void setIdentity(BeanDescriptor<?> descriptor, MTable table) {
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.avaje.ebean.dbmigration.model.build;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
import com.avaje.ebean.config.DbConstraintNaming;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.ModelContainer;
|
||||
@@ -20,14 +22,52 @@ public class ModelBuildContext {
|
||||
|
||||
private final ModelContainer model;
|
||||
|
||||
public ModelBuildContext(ModelContainer model) {
|
||||
private final DbConstraintNaming constraintNaming;
|
||||
|
||||
private final PlatformDdl platformDdl;
|
||||
|
||||
public ModelBuildContext(ModelContainer model, DbConstraintNaming constraintNaming, PlatformDdl platformDdl) {
|
||||
this.model = model;
|
||||
this.constraintNaming = constraintNaming;
|
||||
this.platformDdl = platformDdl;
|
||||
}
|
||||
|
||||
public String primaryKeyName(String tableName) {
|
||||
return maxLength(constraintNaming.primaryKeyName(tableName), 0);
|
||||
}
|
||||
|
||||
public String foreignKeyConstraintName(String tableName, String columnName, int foreignKeyCount) {
|
||||
return maxLength(constraintNaming.foreignKeyConstraintName(tableName, columnName), foreignKeyCount);
|
||||
}
|
||||
|
||||
public String foreignKeyIndexName(String tableName, String[] columns, int indexCount) {
|
||||
return maxLength(constraintNaming.foreignKeyIndexName(tableName, columns), indexCount);
|
||||
}
|
||||
|
||||
public String foreignKeyIndexName(String tableName, String column, int indexCount) {
|
||||
return maxLength(constraintNaming.foreignKeyIndexName(tableName, column), indexCount);
|
||||
}
|
||||
|
||||
public String uniqueConstraintName(String tableName, String columnName, int indexCount) {
|
||||
return maxLength(constraintNaming.uniqueConstraintName(tableName, columnName), indexCount);
|
||||
}
|
||||
|
||||
public String uniqueConstraintName(String tableName, String[] columnNames, int indexCount) {
|
||||
return maxLength(constraintNaming.uniqueConstraintName(tableName, columnNames), indexCount);
|
||||
}
|
||||
|
||||
public String checkConstraintName(String tableName, String columnName, int checkCount) {
|
||||
return maxLength(constraintNaming.checkConstraintName(tableName, columnName), checkCount);
|
||||
}
|
||||
|
||||
public void addTable(MTable table) {
|
||||
model.addTable(table);
|
||||
}
|
||||
|
||||
private String maxLength(String constraintName, int indexCount) {
|
||||
return platformDdl.maxLength(constraintName, indexCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the map used to determine the DB specific type
|
||||
* for a given bean property.
|
||||
@@ -57,12 +97,6 @@ public class ModelBuildContext {
|
||||
return dbTypeMap.get(jdbcType);
|
||||
}
|
||||
|
||||
// ScalarType<Object> scalarType = p.getScalarType();
|
||||
// if (scalarType == null) {
|
||||
// throw new RuntimeException("No scalarType for " + p.getFullBeanName());
|
||||
// }
|
||||
// return dbTypeMap.get(scalarType.getJdbcType());
|
||||
|
||||
// can be the logical JSON types (JSON, JSONB, JSONClob, JSONBlob, JSONVarchar)
|
||||
int dbType = p.getDbType();
|
||||
if (dbType == 0) {
|
||||
|
||||
+12
-39
@@ -23,6 +23,8 @@ public class ModelBuildIntersectionTable {
|
||||
|
||||
private MTable intersectionTable;
|
||||
|
||||
private int countForeignKey;
|
||||
|
||||
public ModelBuildIntersectionTable(ModelBuildContext ctx, BeanPropertyAssocMany<?> manyProp) {
|
||||
this.ctx = ctx;
|
||||
this.manyProp = manyProp;
|
||||
@@ -30,7 +32,7 @@ public class ModelBuildIntersectionTable {
|
||||
this.tableJoin = manyProp.getTableJoin();
|
||||
}
|
||||
|
||||
public void build() {
|
||||
public void build() {
|
||||
|
||||
intersectionTable = createTable();
|
||||
ctx.addTable(intersectionTable);
|
||||
@@ -42,66 +44,38 @@ public class ModelBuildIntersectionTable {
|
||||
|
||||
BeanDescriptor<?> localDesc = manyProp.getBeanDescriptor();
|
||||
buildFkConstraints(localDesc, intersectionTableJoin.columns(), true);
|
||||
//ctx.addIntersectionTableFk(fk1);
|
||||
|
||||
BeanDescriptor<?> targetDesc = manyProp.getTargetDescriptor();
|
||||
buildFkConstraints(targetDesc, tableJoin.columns(), false);
|
||||
//ctx.addIntersectionTableFk(fk2);
|
||||
}
|
||||
|
||||
|
||||
private void buildFkConstraints(BeanDescriptor<?> desc, TableJoinColumn[] columns, boolean direction) {
|
||||
|
||||
String tableName = intersectionTableJoin.getTable();
|
||||
String baseTable = desc.getBaseTable();
|
||||
|
||||
// String fkName = "fk_"+intersectionTableJoin.getTable()+"_"+desc.getBaseTable();
|
||||
//
|
||||
// fkName = getFkNameWithSuffix(fkName);
|
||||
String fkName = ctx.foreignKeyConstraintName(tableName, baseTable, ++countForeignKey);
|
||||
String fkIndex = ctx.foreignKeyIndexName(tableName, baseTable, countForeignKey);
|
||||
|
||||
MCompoundForeignKey foreignKey = new MCompoundForeignKey(desc.getBaseTable());
|
||||
MCompoundForeignKey foreignKey = new MCompoundForeignKey(fkName, desc.getBaseTable(), fkIndex);
|
||||
intersectionTable.addForeignKey(foreignKey);
|
||||
|
||||
|
||||
// fkBuf.append("alter table ");
|
||||
// fkBuf.append(intersectionTableJoin.getTable());
|
||||
// fkBuf.append(" add constraint ").append(fkName);
|
||||
//
|
||||
// fkBuf.append(" foreign key (");
|
||||
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
// if (i > 0) {
|
||||
// fkBuf.append(", ");
|
||||
// }
|
||||
String localCol = direction ? columns[i].getForeignDbColumn() : columns[i].getLocalDbColumn();
|
||||
String refCol = !direction ? columns[i].getForeignDbColumn() : columns[i].getLocalDbColumn();
|
||||
foreignKey.addColumnPair(localCol, refCol);
|
||||
}
|
||||
// fkBuf.append(") references ").append(desc.getBaseTable()).append(" (");
|
||||
//
|
||||
// for (int i = 0; i < columns.length; i++) {
|
||||
// if (i > 0) {
|
||||
// fkBuf.append(", ");
|
||||
// }
|
||||
// String col = !direction ? columns[i].getForeignDbColumn() : columns[i].getLocalDbColumn();
|
||||
// fkBuf.append(col);
|
||||
// }
|
||||
// fkBuf.append(")");
|
||||
//
|
||||
// String fkeySuffix = ctx.getDdlSyntax().getForeignKeySuffix();
|
||||
// if (fkeySuffix != null){
|
||||
// fkBuf.append(" ");
|
||||
// fkBuf.append(fkeySuffix);
|
||||
// }
|
||||
// fkBuf.append(";").append(NEW_LINE);
|
||||
//
|
||||
// return fkBuf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private MTable createTable() {
|
||||
|
||||
BeanDescriptor<?> localDesc = manyProp.getBeanDescriptor();
|
||||
BeanDescriptor<?> targetDesc = manyProp.getTargetDescriptor();
|
||||
|
||||
MTable table = new MTable(intersectionTableJoin.getTable());
|
||||
String tableName = intersectionTableJoin.getTable();
|
||||
MTable table = new MTable(tableName);
|
||||
table.setPkName(ctx.primaryKeyName(tableName));
|
||||
|
||||
TableJoinColumn[] columns = intersectionTableJoin.columns();
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
@@ -125,7 +99,6 @@ public class ModelBuildIntersectionTable {
|
||||
|
||||
MColumn col = new MColumn(column, ctx.getColumnDefn(p), true);
|
||||
col.setPrimaryKey(true);
|
||||
|
||||
table.addColumn(col);
|
||||
}
|
||||
|
||||
|
||||
+151
-11
@@ -1,15 +1,17 @@
|
||||
package com.avaje.ebean.dbmigration.model.build;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.util.IndexSet;
|
||||
import com.avaje.ebean.dbmigration.model.MColumn;
|
||||
import com.avaje.ebean.dbmigration.model.MCompoundForeignKey;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.BaseTablePropertyVisitor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound;
|
||||
import com.avaje.ebeaninternal.server.deploy.CompoundUniqueContraint;
|
||||
import com.avaje.ebeaninternal.server.deploy.TableJoinColumn;
|
||||
import com.avaje.ebeaninternal.server.deploy.id.ImportedId;
|
||||
import com.avaje.ebean.dbmigration.model.MColumn;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.BaseTablePropertyVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -20,17 +22,69 @@ import java.util.List;
|
||||
*/
|
||||
public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
|
||||
private final ModelBuildContext ctx;
|
||||
protected final ModelBuildContext ctx;
|
||||
|
||||
private final MTable table;
|
||||
|
||||
private final IndexSet indexSet = new IndexSet();
|
||||
|
||||
private MColumn lastColumn;
|
||||
|
||||
public ModelBuildPropertyVisitor(ModelBuildContext ctx, MTable table) {
|
||||
private int countForeignKey;
|
||||
private int countIndex;
|
||||
private int countUnique;
|
||||
private int countCheck;
|
||||
|
||||
|
||||
public ModelBuildPropertyVisitor(ModelBuildContext ctx, MTable table, CompoundUniqueContraint[] compoundUniqueConstraints) {
|
||||
this.ctx = ctx;
|
||||
this.table = table;
|
||||
|
||||
addCompoundUniqueConstraint(compoundUniqueConstraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add unique constraints defined via JPA UniqueConstraint annotations.
|
||||
*/
|
||||
private void addCompoundUniqueConstraint(CompoundUniqueContraint[] compoundUniqueConstraints) {
|
||||
|
||||
if (compoundUniqueConstraints != null) {
|
||||
for (int i = 0; i < compoundUniqueConstraints.length; i++) {
|
||||
String[] columns = compoundUniqueConstraints[i].getColumns();
|
||||
String uqName = determineUniqueConstraintName(columns);
|
||||
table.addCompoundUniqueConstraint(columns, false, uqName);
|
||||
indexSet.add(columns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
|
||||
// set the primary key name
|
||||
table.setPkName(determinePrimaryKeyName());
|
||||
|
||||
// check if indexes on foreign keys should be suppressed
|
||||
for (MColumn column : table.getColumns().values()) {
|
||||
if (hasValue(column.getForeignKeyIndex())) {
|
||||
if (indexSet.contains(column.getName())) {
|
||||
// suppress index on foreign key as there is already
|
||||
// effectively an index (probably via unique constraint)
|
||||
column.setForeignKeyIndex(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (MCompoundForeignKey compoundKey : table.getCompoundKeys()) {
|
||||
if (indexSet.contains(compoundKey.getColumns())) {
|
||||
// suppress index on foreign key as there is already
|
||||
// effectively an index (probably via unique constraint)
|
||||
compoundKey.setIndexName(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitMany(BeanPropertyAssocMany<?> p) {
|
||||
if (p.isManyToMany()) {
|
||||
@@ -85,7 +139,9 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
if (columns.length > 1) {
|
||||
// compound foreign key
|
||||
String refTable = p.getTargetDescriptor().getBaseTable();
|
||||
compoundKey = new MCompoundForeignKey(refTable);
|
||||
String fkName = determineForeignKeyConstraintName(p.getName());
|
||||
String fkIndex = determineForeignKeyIndexName(p.getName());
|
||||
compoundKey = new MCompoundForeignKey(fkName, refTable, fkIndex);
|
||||
table.addForeignKey(compoundKey);
|
||||
}
|
||||
|
||||
@@ -109,6 +165,8 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
refTable = p.getTargetDescriptor().getBaseTable();
|
||||
}
|
||||
col.setReferences(refTable + "." + refColumn);
|
||||
col.setForeignKeyName(determineForeignKeyConstraintName(col.getName()));
|
||||
col.setForeignKeyIndex(determineForeignKeyIndexName(col.getName()));
|
||||
} else {
|
||||
compoundKey.addColumnPair(dbCol, refColumn);
|
||||
}
|
||||
@@ -119,14 +177,19 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
// adding the unique constraint restricts the cardinality from OneToMany down to OneToOne
|
||||
// for MsSqlServer we need different DDL to handle NULL values on this constraint
|
||||
if (modelColumns.size() == 1) {
|
||||
modelColumns.get(0).setUniqueOneToOne(true);
|
||||
MColumn col = modelColumns.get(0);
|
||||
col.setUniqueOneToOne(determineUniqueConstraintName(col.getName()));
|
||||
indexSetAdd(col.getName());
|
||||
|
||||
} else {
|
||||
table.addCompoundUniqueConstraint(modelColumns, true);
|
||||
String uqName = determineUniqueConstraintName(p.getName());
|
||||
table.addCompoundUniqueConstraint(modelColumns, true, uqName);
|
||||
indexSetAdd(modelColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void visitScalar(BeanProperty p) {
|
||||
|
||||
if (p.isSecondaryTable()) {
|
||||
@@ -146,12 +209,89 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
}
|
||||
|
||||
if (p.isUnique() && !p.isId()) {
|
||||
col.setUnique(true);
|
||||
col.setUnique(determineUniqueConstraintName(col.getName()));
|
||||
indexSetAdd(col.getName());
|
||||
}
|
||||
String checkConstraint = p.getDbConstraintExpression();
|
||||
if (checkConstraint != null) {
|
||||
col.setCheckConstraint(checkConstraint);
|
||||
col.setCheckConstraintName(determineCheckConstraintName(col.getName()));
|
||||
}
|
||||
col.setCheckConstraint(p.getDbConstraintExpression());
|
||||
|
||||
lastColumn = col;
|
||||
table.addColumn(col);
|
||||
}
|
||||
|
||||
|
||||
private void indexSetAdd(String column) {
|
||||
indexSet.add(column);
|
||||
}
|
||||
|
||||
private void indexSetAdd(List<MColumn> modelColumns) {
|
||||
String[] cols = new String[modelColumns.size()];
|
||||
for (int i = 0; i < modelColumns.size(); i++) {
|
||||
cols[i] = modelColumns.get(i).getName();
|
||||
}
|
||||
indexSet.add(cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary key constraint name.
|
||||
*/
|
||||
protected String determinePrimaryKeyName() {
|
||||
|
||||
return ctx.primaryKeyName(table.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
protected String determineForeignKeyConstraintName(String columnName) {
|
||||
|
||||
return ctx.foreignKeyConstraintName(table.getName(), columnName, ++countForeignKey);
|
||||
}
|
||||
|
||||
protected String determineForeignKeyIndexName(String column) {
|
||||
|
||||
String[] cols = {column};
|
||||
return determineForeignKeyIndexName(cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
protected String determineForeignKeyIndexName(String[] columns) {
|
||||
|
||||
return ctx.foreignKeyIndexName(table.getName(), columns, ++countIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
protected String determineUniqueConstraintName(String columnName) {
|
||||
|
||||
return ctx.uniqueConstraintName(table.getName(), columnName, ++countUnique);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
protected String determineUniqueConstraintName(String[] columnNames) {
|
||||
|
||||
return ctx.uniqueConstraintName(table.getName(), columnNames, ++countUnique);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the constraint name.
|
||||
*/
|
||||
protected String determineCheckConstraintName(String columnName) {
|
||||
|
||||
return ctx.checkConstraintName(table.getName(), columnName, ++countCheck);
|
||||
}
|
||||
|
||||
|
||||
private boolean hasValue(String val) {
|
||||
return val != null && !val.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,11 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound;
|
||||
*/
|
||||
public interface BeanPropertyVisitor {
|
||||
|
||||
/**
|
||||
* Completed visiting all the properties on the bean.
|
||||
*/
|
||||
void visitEnd();
|
||||
|
||||
/**
|
||||
* Visit a OneToMany or ManyToMany property.
|
||||
*/
|
||||
|
||||
@@ -13,4 +13,5 @@ public interface BeanVisitor {
|
||||
* property on the entity bean (return null to skip visiting this bean).
|
||||
*/
|
||||
BeanPropertyVisitor visitBean(BeanDescriptor<?> descriptor);
|
||||
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public class VisitAllUsing {
|
||||
}
|
||||
|
||||
visitInheritanceProperties(desc, propertyVisitor);
|
||||
propertyVisitor.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user