diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/BaseTableDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/BaseTableDdl.java index 010733734..6e62cb704 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/BaseTableDdl.java +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/BaseTableDdl.java @@ -17,6 +17,7 @@ import com.avaje.ebean.dbmigration.migration.DropColumn; import com.avaje.ebean.dbmigration.migration.DropHistoryTable; import com.avaje.ebean.dbmigration.migration.DropTable; import com.avaje.ebean.dbmigration.migration.ForeignKey; +import com.avaje.ebean.dbmigration.migration.UniqueConstraint; import com.avaje.ebean.dbmigration.model.MTable; import java.io.IOException; @@ -58,8 +59,8 @@ public class BaseTableDdl implements TableDdl { protected int countIndex; /** - * Base tables that have associated history tables that need their triggers - * regenerated as columns have been added or removed. + * Base tables that have associated history tables that need their triggers/functions regenerated as + * columns have been added, removed, included or excluded. */ protected Map regenerateHistoryTriggers = new LinkedHashMap(); @@ -69,8 +70,9 @@ public class BaseTableDdl implements TableDdl { public BaseTableDdl(ServerConfig serverConfig, PlatformDdl platformDdl) { this.namingConvention = serverConfig.getNamingConvention(); this.naming = serverConfig.getConstraintNaming(); - this.platformDdl = platformDdl; this.historyTableSuffix = serverConfig.getHistoryTableSuffix(); + this.platformDdl = platformDdl; + this.platformDdl.configure(serverConfig); } /** @@ -253,21 +255,17 @@ public class BaseTableDdl implements TableDdl { if (indexName != null) { // no matching unique constraint so add the index - fkeyBuffer.append("create index ").append(indexName).append(" on ").append(tableName); - appendColumns(columns, fkeyBuffer); - fkeyBuffer.endOfStatement(); + fkeyBuffer.append(platformDdl.createIndex(indexName, tableName, columns)).endOfStatement(); } fkeyBuffer.end(); write.rollbackForeignKeys() - .append(platformDdl.alterTableDropForeignKey(tableName, fkName)) - .endOfStatement(); + .append(platformDdl.alterTableDropForeignKey(tableName, fkName)).endOfStatement(); if (indexName != null) { write.rollbackForeignKeys() - .append(platformDdl.dropIndex(indexName, tableName)) - .endOfStatement(); + .append(platformDdl.dropIndex(indexName, tableName)).endOfStatement(); } write.rollbackForeignKeys().end(); @@ -276,17 +274,7 @@ public class BaseTableDdl implements TableDdl { protected void alterTableAddForeignKey(DdlBuffer buffer, String fkName, String tableName, String[] columns, String refTable, String[] refColumns) throws IOException { - buffer - .append("alter table ").append(tableName) - .append(" add constraint ").append(fkName) - .append(" foreign key"); - appendColumns(columns, buffer); - buffer - .append(" references ") - .append(lowerName(refTable)); - appendColumns(refColumns, buffer); - buffer.appendWithSpace(platformDdl.getForeignKeyRestrict()) - .endOfStatement(); + buffer.append(platformDdl.alterTableAddForeignKey(tableName, fkName, columns, refTable, refColumns)).endOfStatement(); } protected void appendColumns(String[] columns, DdlBuffer buffer) throws IOException { @@ -335,8 +323,17 @@ public class BaseTableDdl implements TableDdl { buffer.append(" ").append(checkConstraint); } - protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) { - //TODO: Write compound unique constraints + protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { + + String tableName = createTable.getName(); + + List uniqueConstraints = createTable.getUniqueConstraint(); + for (UniqueConstraint uniqueConstraint : uniqueConstraints) { + String[] columns = toColumnNamesSplit(uniqueConstraint.getColumnNames()); + apply + .append(platformDdl.alterTableAddUniqueConstraint(tableName, uniqueConstraint.getName(), columns)) + .endOfStatement(); + } } /** @@ -715,8 +712,7 @@ public class BaseTableDdl implements TableDdl { protected void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException { - buffer.append("alter table ").append(tableName) - .append(" drop column ").append(columnName) + buffer.append("alter table ").append(tableName).append(" drop column ").append(columnName) .endOfStatement(); } diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java index d76784044..b8d5b31f8 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java @@ -1,5 +1,6 @@ package com.avaje.ebean.dbmigration.ddlgeneration.platform; +import com.avaje.ebean.config.DbConstraintNaming; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.config.dbplatform.DbIdentity; import com.avaje.ebean.config.dbplatform.DbTypeMap; @@ -53,7 +54,6 @@ public class PlatformDdl { protected String dropIndexIfExists = "drop index if exists "; - protected String alterColumn = "alter column"; protected String dropUniqueConstraint = "drop constraint"; @@ -73,16 +73,25 @@ public class PlatformDdl { */ protected boolean inlineUniqueOneToOne = true; + protected DbConstraintNaming naming; + public PlatformDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) { this.dbIdentity = dbIdentity; this.typeConverter = new PlatformTypeConverter(platformTypes); } + /** + * Set configuration options. + */ + public void configure(ServerConfig serverConfig) { + historyDdl.configure(serverConfig); + naming = serverConfig.getConstraintNaming(); + } + /** * Create a DdlHandler for the specific database platform. */ public DdlHandler createDdlHandler(ServerConfig serverConfig) { - historyDdl.configure(serverConfig); return new BaseDdlHandler(serverConfig, this); } @@ -102,13 +111,6 @@ public class PlatformDdl { return columnDefn + identitySuffix; } - /** - * Return the foreign key on delete on update restrict clause. - */ - public String getForeignKeyRestrict() { - return foreignKeyRestrict; - } - /** * Return the drop foreign key clause. */ @@ -192,6 +194,38 @@ public class PlatformDdl { return dropIndexIfExists + indexName; } + /** + * Return the create index statement. + */ + public String createIndex(String indexName, String tableName, String[] columns) { + + StringBuilder buffer = new StringBuilder(); + buffer.append("create index ").append(indexName).append(" on ").append(tableName); + appendColumns(columns, buffer); + + return buffer.toString(); + } + + /** + * Add foreign key. + */ + public String alterTableAddForeignKey(String tableName, String fkName, String[] columns, String refTable, String[] refColumns) { + + StringBuilder buffer = new StringBuilder(90); + buffer + .append("alter table ").append(tableName) + .append(" add constraint ").append(fkName) + .append(" foreign key"); + appendColumns(columns, buffer); + buffer + .append(" references ") + .append(lowerName(refTable)); + appendColumns(refColumns, buffer); + appendWithSpace(foreignKeyRestrict, buffer); + + return buffer.toString(); + } + /** * Drop a unique constraint from the table. */ @@ -206,15 +240,10 @@ public class PlatformDdl { */ public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns) { - String base = "alter table " + tableName + " add constraint " + uqName + " unique ("; - for (int i = 0; i < columns.length; i++) { - if (i > 0) { - base += ","; - } - base += columns[i]; - } - base += ")"; - return base; + StringBuilder buffer = new StringBuilder(90); + buffer.append("alter table ").append(tableName).append(" add constraint ").append(uqName).append(" unique "); + appendColumns(columns, buffer); + return buffer.toString(); } /** @@ -276,4 +305,32 @@ public class PlatformDdl { return null; } + protected void appendColumns(String[] columns, StringBuilder buffer) { + buffer.append(" ("); + for (int i = 0; i < columns.length; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(lowerName(columns[i].trim())); + } + buffer.append(")"); + } + + protected void appendWithSpace(String content, StringBuilder buffer) { + if (content != null && !content.isEmpty()) { + buffer.append(" ").append(content); + } + } + + /** + * Convert the table or column name to lower case. + *

+ * This is passed up to the platformDdl to override as desired. + * Generally lower case with underscore is a good cross database + * choice for column/table names. + */ + protected String lowerName(String name) { + return naming.lowerName(name); + } + }