Support schema in history-entities

This commit is contained in:
Roland Praml
2022-03-22 09:42:19 +01:00
parent baddc76961
commit 4fe8ef2b23
7 changed files with 99 additions and 93 deletions
@@ -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());
@@ -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();
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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";
}
}