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 de29da880..c3bc5f791 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 @@ -741,7 +741,7 @@ public class BaseTableDdl implements TableDdl { * Return the name of the history table given the base table name. */ protected String historyTable(String baseTable) { - return baseTable + historyTableSuffix; + return naming.normaliseTable(baseTable) + historyTableSuffix; } /** 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 c1d6601d1..d8877e596 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,6 +1,7 @@ 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; @@ -16,6 +17,7 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { private String systemPeriodStart; private String systemPeriodEnd; private PlatformDdl platformDdl; + private DbConstraintNaming constraintNaming; private String historySuffix; @Override @@ -23,13 +25,14 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { this.systemPeriodStart = config.getAsOfSysPeriod() + "_start"; this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end"; 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 = tableName + historySuffix; + String historyTableName = historyTableName(tableName); DdlBuffer apply = writer.applyPostAlter(); apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName).append(" (").newLine(); @@ -66,7 +69,7 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { @Override public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) { dropHistoryTable(writer.applyDropDependencies(), dropHistoryTable.getBaseTable(), - dropHistoryTable.getBaseTable() + historySuffix); + historyTableName(dropHistoryTable.getBaseTable())); } protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) { @@ -130,11 +133,15 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { } public void enableSystemVersioning(DdlBuffer apply, String tableName, boolean validated) { - apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(tableName).append(historySuffix); + apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(historyTableName(tableName)); if (!validated) { apply.append(" not validated"); } 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/PostgresHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java index 135324899..4a54edd92 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 @@ -21,7 +21,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { */ @Override protected void createHistoryTable(DdlBuffer apply, MTable table) { - apply.append("create table ").append(table.getName()).append(historySuffix) + apply.append("create table ").append(historyTableName(table.getName())) .append("(like ").append(table.getName()).append(")").endOfStatement(); } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdl.java index c0b1eaebc..e2faa5ace 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdl.java @@ -1,6 +1,7 @@ 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; @@ -17,12 +18,17 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl { private String systemPeriodStart; private String systemPeriodEnd; private PlatformDdl platformDdl; + protected DbConstraintNaming constraintNaming; + protected String historySuffix; @Override public void configure(DatabaseConfig config, PlatformDdl platformDdl) { this.systemPeriodStart = config.getAsOfSysPeriod() + "From"; this.systemPeriodEnd = config.getAsOfSysPeriod() + "To"; this.platformDdl = platformDdl; + + this.constraintNaming = config.getConstraintNaming(); + this.historySuffix = config.getHistoryTableSuffix(); } @Override @@ -31,18 +37,6 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl { enableSystemVersioning(writer, baseTable); } - String getHistoryTable(String baseTable) { - String historyTable = baseTable + "_history"; - if (baseTable.startsWith("[")) { - historyTable = historyTable.replace("]", "") + "]"; - } - if (historyTable.indexOf('.') == -1) { - // history must contain schema, add the default schema if none was specified - historyTable = "dbo." + historyTable; - } - return historyTable; - } - private void enableSystemVersioning(DdlWrite writer, String baseTable) { DdlBuffer apply = writer.applyPostAlter(); apply.append("alter table ").append(baseTable).newLine() @@ -51,11 +45,12 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl { .append("period for system_time (").append(systemPeriodStart).append(", ").append(systemPeriodEnd).append(")").endOfStatement(); apply.append("alter table ").append(baseTable).append(" set (system_versioning = on (history_table=") - .append(getHistoryTable(baseTable)).append("))").endOfStatement(); + .append(historyTableWithSchema(baseTable)).append("))").endOfStatement(); DdlBuffer drop = writer.dropAll(); drop.append("IF OBJECT_ID('").append(baseTable).append("', 'U') IS NOT NULL alter table ").append(baseTable).append(" set (system_versioning = off)").endOfStatement(); - drop.append("IF OBJECT_ID('").append(baseTable).append("_history', 'U') IS NOT NULL drop table ").append(baseTable).append("_history").endOfStatement(); + drop.append("IF OBJECT_ID('").append(historyTableName(baseTable)).append("', 'U') IS NOT NULL drop table ") + .append(historyTableName(baseTable)).endOfStatement(); } @Override @@ -79,7 +74,7 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl { // now drop tables & columns, they will go to alter table/post alter buffers platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodStart); platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodEnd); - writer.applyPostAlter().appendStatement(platformDdl.dropTable(baseTable + "_history")); + writer.applyPostAlter().appendStatement(platformDdl.dropTable(historyTableName(baseTable))); } @Override @@ -96,12 +91,31 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl { // SQL Server 2016 does not need triggers DdlBuffer apply = writer.apply(); apply.append("-- alter table ").append(tableName).append(" set (system_versioning = off (history_table=") - .append(getHistoryTable(tableName)).append("))").endOfStatement(); + .append(historyTableWithSchema(tableName)).append("))").endOfStatement(); apply.append("-- history migration goes here").newLine(); apply.append("-- alter table ").append(tableName).append(" set (system_versioning = on (history_table=") - .append(getHistoryTable(tableName)).append("))").endOfStatement(); + .append(historyTableWithSchema(tableName)).append("))").endOfStatement(); } alter.setHistoryHandled(); } + protected String normalise(String tableName) { + return constraintNaming.normaliseTable(tableName); + } + + protected String historyTableName(String baseTableName) { + return normalise(baseTableName) + historySuffix; + } + + protected String historyTableWithSchema(String baseTableName) { + String historyTable = historyTableName(baseTableName); + int lastPeriod = baseTableName.lastIndexOf('.'); + if (lastPeriod == -1) { + // history must contain schema, add the default schema if none was specified + return "dbo." + historyTable; + } else { + return baseTableName.substring(0, lastPeriod + 1) + historyTable; + } + } + } diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdlTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdlTest.java index 73dd7c57f..0cc69865e 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdlTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerHistoryDdlTest.java @@ -2,6 +2,9 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; import org.junit.jupiter.api.Test; +import io.ebean.config.DatabaseConfig; +import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform; + import static org.assertj.core.api.Assertions.assertThat; public class SqlServerHistoryDdlTest { @@ -10,8 +13,12 @@ public class SqlServerHistoryDdlTest { public void getHistoryTable() { SqlServerHistoryDdl ddl = new SqlServerHistoryDdl(); - assertThat(ddl.getHistoryTable("foo")).isEqualTo("dbo.foo_history"); - assertThat(ddl.getHistoryTable("bar.foo")).isEqualTo("bar.foo_history"); - assertThat(ddl.getHistoryTable("[Foo]")).isEqualTo("dbo.[Foo_history]"); + ddl.configure(new DatabaseConfig(), new SqlServerDdl(new SqlServer17Platform())); + assertThat(ddl.historyTableWithSchema("foo")).isEqualTo("dbo.foo_history"); + assertThat(ddl.historyTableWithSchema("bar.foo")).isEqualTo("bar.foo_history"); + // test with reserved keywords in quotes + assertThat(ddl.historyTableWithSchema("[select]")).isEqualTo("dbo.select_history"); + assertThat(ddl.historyTableWithSchema("\"select\"")).isEqualTo("dbo.select_history"); + assertThat(ddl.historyTableWithSchema("`select`")).isEqualTo("dbo.select_history"); } }