diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java index 60b22552c..f9c238d5d 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java @@ -4,7 +4,6 @@ import io.ebean.annotation.Platform; import io.ebean.config.DatabaseConfig; import io.ebean.config.DbConstraintNaming; import io.ebean.config.NamingConvention; -import io.ebean.config.dbplatform.DbHistorySupport; import io.ebean.config.dbplatform.IdType; import io.ebean.util.StringHelper; import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; @@ -61,7 +60,7 @@ public class BaseTableDdl implements TableDdl { private final boolean strictMode; - private final boolean alterHistoryTables; + private final PlatformHistoryDdl.TableBased tableHistory; /** * Helper class that is used to execute the migration ddl before and after the migration action. @@ -180,11 +179,10 @@ public class BaseTableDdl implements TableDdl { this.platformDdl = platformDdl; this.platformDdl.configure(config); this.strictMode = config.isDdlStrictMode(); - DbHistorySupport hist = platformDdl.getPlatform().getHistorySupport(); - if (hist == null) { - this.alterHistoryTables = false; + if (platformDdl.historyDdl instanceof PlatformHistoryDdl.TableBased) { + this.tableHistory = (PlatformHistoryDdl.TableBased) platformDdl.historyDdl; } else { - this.alterHistoryTables = platformDdl.historyDdl.alterHistoryTables(); + this.tableHistory = null; } } @@ -617,8 +615,8 @@ public class BaseTableDdl implements TableDdl { if (isTrue(addColumn.isWithHistory())) { platformDdl.regenerateHistoryTriggers(writer, tableName); // make same changes to the history table - if (alterHistoryTables) { - String historyTable = historyTable(tableName); + if (tableHistory != null) { + String historyTable = tableHistory.historyTableName(tableName); for (Column column : columns) { alterTableAddColumn(writer, historyTable, column, true, true); } @@ -658,8 +656,8 @@ public class BaseTableDdl implements TableDdl { if (isTrue(dropColumn.isWithHistory())) { platformDdl.regenerateHistoryTriggers(writer, tableName); // also drop from the history table - if (alterHistoryTables) { - alterTableDropColumn(writer, historyTable(tableName), dropColumn.getColumnName()); + if (tableHistory != null) { + alterTableDropColumn(writer, tableHistory.historyTableName(tableName), dropColumn.getColumnName()); } } } @@ -737,13 +735,6 @@ public class BaseTableDdl implements TableDdl { platformDdl.addColumnComment(writer.applyPostAlter(), alterColumn.getTableName(), alterColumn.getColumnName(), alterColumn.getComment()); } - /** - * Return the name of the history table given the base table name. - */ - protected String historyTable(String baseTable) { - return naming.normaliseTable(baseTable) + historyTableSuffix; - } - /** * alter all the base attributes (type/default/notnull) of the column together. * Some platforms (like mysql/sqlserver/hana) must do that in one statement, @@ -764,9 +755,9 @@ public class BaseTableDdl implements TableDdl { } if (applyToHistory) { platformDdl.regenerateHistoryTriggers(writer, alter.getTableName()); - if (alterHistoryTables) { + if (tableHistory != null) { AlterColumn alterHistoryColumn = new AlterColumn(); - alterHistoryColumn.setTableName(historyTable(alter.getTableName())); + alterHistoryColumn.setTableName(tableHistory.historyTableName(alter.getTableName())); alterHistoryColumn.setColumnName(alter.getColumnName()); // ignore default value (not needed on history tables) alterHistoryColumn.setCurrentType(alter.getCurrentType()); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/Db2HistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/Db2HistoryDdl.java index 17855e8fa..b1fcbcc55 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/Db2HistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/Db2HistoryDdl.java @@ -1,7 +1,6 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; import io.ebean.config.DatabaseConfig; -import io.ebean.config.DbConstraintNaming; import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable; import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite; @@ -14,29 +13,24 @@ import io.ebeaninternal.dbmigration.model.MTable; * * @author Roland Praml, FOCONIS AG */ -public class Db2HistoryDdl implements PlatformHistoryDdl { +public class Db2HistoryDdl extends DbTableBasedHistoryDdl implements PlatformHistoryDdl { private String systemPeriodStart; private String systemPeriodEnd; private String transactionId; - private PlatformDdl platformDdl; - private DbConstraintNaming constraintNaming; - private String historySuffix; @Override public void configure(DatabaseConfig config, PlatformDdl platformDdl) { + super.configure(config, platformDdl); this.systemPeriodStart = config.getAsOfSysPeriod() + "_start"; this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end"; this.transactionId = config.getAsOfSysPeriod() + "_txn"; // required for DB2 - this.platformDdl = platformDdl; - this.constraintNaming = config.getConstraintNaming(); - this.historySuffix = config.getHistoryTableSuffix(); } @Override public void createWithHistory(DdlWrite writer, MTable table) { String tableName = table.getName(); - String historyTableName = historyTable(tableName); + String historyTableName = historyTableName(tableName); // DB2 requires an EXACT copy (same column types with null/non-null, same order) addSysPeriodColumns(writer, tableName); @@ -74,7 +68,7 @@ public class Db2HistoryDdl implements PlatformHistoryDdl { platformDdl.alterTableDropColumn(writer, baseTable, transactionId); // drop the history table - writer.applyPostAlter().append("drop table ").append(historyTable(baseTable)).endOfStatement(); + writer.applyPostAlter().append("drop table ").append(historyTableName(baseTable)).endOfStatement(); } @Override @@ -86,10 +80,6 @@ public class Db2HistoryDdl implements PlatformHistoryDdl { createWithHistory(writer, table); } - @Override - public boolean alterHistoryTables() { - return true; - } @Override public void updateTriggers(DdlWrite writer, String tableName) { @@ -107,11 +97,7 @@ public class Db2HistoryDdl implements PlatformHistoryDdl { } public void enableSystemVersioning(DdlBuffer apply, String tableName) { - apply.append("alter table ").append(tableName).append(" add versioning use history table ").append(historyTable(tableName)).endOfStatement(); - } - - protected String historyTable(String tableName) { - return constraintNaming.normaliseTable(tableName) + historySuffix; + apply.append("alter table ").append(tableName).append(" add versioning use history table ").append(historyTableName(tableName)).endOfStatement(); } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTableBasedHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTableBasedHistoryDdl.java new file mode 100644 index 000000000..4d7b0deca --- /dev/null +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTableBasedHistoryDdl.java @@ -0,0 +1,44 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import io.ebean.config.DatabaseConfig; +import io.ebean.config.DbConstraintNaming; + +/** + * Base implementation for all histories, where we must maintain history table (trigger based, db2 and hana) + * + * @author Roland Praml, FOCONIS AG + * + */ +public abstract class DbTableBasedHistoryDdl implements PlatformHistoryDdl.TableBased { + + private DbConstraintNaming constraintNaming; + private String historySuffix; + protected PlatformDdl platformDdl; + + @Override + public void configure(DatabaseConfig config, PlatformDdl platformDdl) { + this.platformDdl = platformDdl; + this.historySuffix = config.getHistoryTableSuffix(); + this.constraintNaming = config.getConstraintNaming(); + } + + @Override + public String historyTableName(String baseTableName) { + return normalise(baseTableName, historySuffix); + } + + protected String normalise(String tableName, String suffix) { + String normalized = quote(normalise(tableName) + suffix); + int lastPeriod = tableName.lastIndexOf('.'); + return tableName.substring(0, lastPeriod + 1) + normalized; + } + + protected String normalise(String tableName) { + return constraintNaming.normaliseTable(tableName); + } + + protected String quote(String dbName) { + return platformDdl.quote(dbName); + } + +} diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java index f46dd6977..33167deac 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java @@ -1,7 +1,6 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; import io.ebean.config.DatabaseConfig; -import io.ebean.config.DbConstraintNaming; import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable; import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite; @@ -15,18 +14,14 @@ import java.util.List; /** * Uses DB triggers to maintain a history table. */ -public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl { - - protected DbConstraintNaming constraintNaming; - - protected PlatformDdl platformDdl; +public abstract class DbTriggerBasedHistoryDdl extends DbTableBasedHistoryDdl implements PlatformHistoryDdl { protected String sysPeriod; protected String sysPeriodStart; protected String sysPeriodEnd; protected String viewSuffix; - protected String historySuffix; + protected String sysPeriodType = "datetime(6)"; protected String now = "now(6)"; @@ -37,11 +32,9 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl { @Override public void configure(DatabaseConfig config, PlatformDdl platformDdl) { - this.platformDdl = platformDdl; + super.configure(config, platformDdl); this.sysPeriod = config.getAsOfSysPeriod(); this.viewSuffix = config.getAsOfViewSuffix(); - this.historySuffix = config.getHistoryTableSuffix(); - this.constraintNaming = config.getConstraintNaming(); this.sysPeriodStart = sysPeriod + "_start"; this.sysPeriodEnd = sysPeriod + "_end"; @@ -121,33 +114,24 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl { protected abstract void dropTriggers(DdlBuffer buffer, String baseTable); - - protected String normalise(String tableName) { - return constraintNaming.normaliseTable(tableName); - } - - protected String historyTableName(String baseTableName) { - return quote(normalise(baseTableName) + historySuffix); - } - protected String historyViewName(String baseTableName) { - return quote(normalise(baseTableName) + viewSuffix); + return normalise(baseTableName, viewSuffix); } protected String procedureName(String baseTableName) { - return normalise(baseTableName) + "_history_version"; + return normalise(baseTableName, "_history_version"); } protected String triggerName(String baseTableName) { - return normalise(baseTableName) + "_history_upd"; + return normalise(baseTableName, "_history_upd"); } protected String updateTriggerName(String baseTableName) { - return normalise(baseTableName) + "_history_upd"; + return normalise(baseTableName, "_history_upd"); } protected String deleteTriggerName(String baseTableName) { - return normalise(baseTableName) + "_history_del"; + return normalise(baseTableName, "_history_del"); } protected void addSysPeriodColumns(DdlWrite writer, String baseTableName, String whenCreatedColumn) { @@ -264,12 +248,5 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl { return table.allHistoryColumns(true); } - @Override - public boolean alterHistoryTables() { - return true; - } - protected String quote(String dbName) { - return platformDdl.quote(dbName); - } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java index d8877e596..742f23c45 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java @@ -1,7 +1,6 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; import io.ebean.config.DatabaseConfig; -import io.ebean.config.DbConstraintNaming; import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable; import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite; @@ -12,21 +11,16 @@ import io.ebeaninternal.dbmigration.model.MTable; import java.util.Collection; -public class HanaHistoryDdl implements PlatformHistoryDdl { +public class HanaHistoryDdl extends DbTableBasedHistoryDdl implements PlatformHistoryDdl { private String systemPeriodStart; private String systemPeriodEnd; - private PlatformDdl platformDdl; - private DbConstraintNaming constraintNaming; - private String historySuffix; @Override public void configure(DatabaseConfig config, PlatformDdl platformDdl) { + super.configure(config, platformDdl); this.systemPeriodStart = config.getAsOfSysPeriod() + "_start"; this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end"; - this.platformDdl = platformDdl; - this.constraintNaming = config.getConstraintNaming(); - this.historySuffix = config.getHistoryTableSuffix(); } @Override @@ -95,11 +89,6 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { createWithHistory(writer, table); } - @Override - public boolean alterHistoryTables() { - return true; - } - @Override public void updateTriggers(DdlWrite writer, String tableName) { DdlAlterTable alter = platformDdl.alterTable(writer, tableName); @@ -140,8 +129,5 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { apply.endOfStatement(); } - protected String historyTableName(String tableName) { - return constraintNaming.normaliseTable(tableName) + historySuffix; - } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformHistoryDdl.java index 4dd1dec6d..dc027055e 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformHistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformHistoryDdl.java @@ -31,14 +31,6 @@ public interface PlatformHistoryDdl { */ void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable); - /** - * Returns true, if alters on the live tables should be applied also to the history tables. This is required for DbTriggerBased - * histories or on platforms like Hana, which are not SQL2011 history compatible (at least from DDL perspective) - */ - default boolean alterHistoryTables() { - return false; - } - /** * Regenerate the history triggers/stored function due to column added/dropped/included or excluded. * @@ -47,4 +39,15 @@ public interface PlatformHistoryDdl { default void updateTriggers(DdlWrite writer, String tableName) { // nop } + + /** + * When history is table based, then alters on the live tables are applied also to the history tables. This is required for + * DbTriggerBased histories or on platforms like Hana, which are not SQL2011 history compatible (at least from DDL perspective) + */ + interface TableBased extends PlatformHistoryDdl { + /** + * Returns the history table name with propert quotes. + */ + public String historyTableName(String baseTableName); + } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java index 4a54edd92..3aace9f58 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java @@ -107,4 +107,23 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { buffer.append(");").newLine(); } + @Override + protected String procedureName(String baseTableName) { + return normalise(baseTableName) + "_history_version"; + } + + @Override + protected String triggerName(String baseTableName) { + return normalise(baseTableName) + "_history_upd"; + } + + @Override + protected String updateTriggerName(String baseTableName) { + return normalise(baseTableName) + "_history_upd"; + } + + @Override + protected String deleteTriggerName(String baseTableName) { + return normalise(baseTableName) + "_history_del"; + } }