factory) {
+ return applyAlterTables.computeIfAbsent(tableName, factory);
+ }
+
/**
* Return the buffer that APPLY DDL is written to for foreign keys and their associated indexes.
*
@@ -103,20 +133,6 @@ public class DdlWrite {
return applyForeignKeys;
}
- /**
- * Return the buffer that apply history-view DDL is written to.
- */
- public DdlBuffer applyHistoryView() {
- return applyHistoryView;
- }
-
- /**
- * Return the buffer that apply history-trigger DDL is written to.
- */
- public DdlBuffer applyHistoryTrigger() {
- return applyHistoryTrigger;
- }
-
/**
* Return the buffer used for the 'drop all DDL' for dropping foreign keys and associated indexes.
*/
@@ -131,4 +147,61 @@ public class DdlWrite {
return dropAll;
}
+ /**
+ * Writes the apply ddl to the target.
+ */
+ public void writeApply(Appendable target) throws IOException {
+ if (!applyDropDependencies.isEmpty()) {
+ target.append("-- drop dependencies\n");
+ target.append(applyDropDependencies.getBuffer());
+ }
+ if (!apply.isEmpty()) {
+ target.append("-- apply changes\n");
+ target.append(apply.getBuffer());
+ }
+ if (!applyAlterTables.isEmpty()) {
+ target.append("-- apply alter tables\n");
+ for (DdlAlterTable alterTable : applyAlterTables.values()) {
+ alterTable.write(target);
+ }
+ }
+ if (!applyPostAlter.isEmpty()) {
+ target.append("-- apply post alter\n");
+ target.append(applyPostAlter.getBuffer());
+ }
+ if (!applyForeignKeys.isEmpty()) {
+ target.append("-- foreign keys and indices\n");
+ target.append(applyForeignKeys.getBuffer());
+ }
+ }
+
+ /**
+ * Writes the drop all ddl to the target.
+ */
+ public void writeDropAll(Appendable target) throws IOException {
+ if (!dropAllForeignKeys.isEmpty()) {
+ target.append("-- drop all foreign keys\n");
+ target.append(dropAllForeignKeys.getBuffer());
+ }
+ if (!dropAll.isEmpty()) {
+ target.append("-- drop all\n");
+ target.append(dropAll.getBuffer());
+ }
+ }
+
+ /**
+ * Returns all create statements. Mainly used for unit-tests
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ try {
+ writeDropAll(sb);
+ writeApply(sb);
+ } catch (IOException e) {
+ // can not happen
+ }
+ return sb.toString();
+ }
+
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/TableDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/TableDdl.java
index f88546b62..48143afe6 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/TableDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/TableDdl.java
@@ -14,8 +14,6 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.migration.DropIndex;
import io.ebeaninternal.dbmigration.migration.DropTable;
-import java.io.IOException;
-
/**
* Write table DDL.
*/
@@ -24,75 +22,75 @@ public interface TableDdl {
/**
* Generate the create table change.
*/
- void generate(DdlWrite writer, CreateTable createTable) throws IOException;
+ void generate(DdlWrite writer, CreateTable createTable);
/**
* Write the drop column change.
*/
- void generate(DdlWrite writer, DropTable dropTable) throws IOException;
+ void generate(DdlWrite writer, DropTable dropTable);
/**
* Write alter table changes.
*/
- void generate(DdlWrite writer, AlterTable dropTable) throws IOException;
+ void generate(DdlWrite writer, AlterTable dropTable);
/**
* Write the add column change.
*/
- void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
+ void generate(DdlWrite writer, AddColumn addColumn);
/**
* Write the alter column changes.
*/
- void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
+ void generate(DdlWrite writer, AlterColumn alterColumn);
/**
* Write the drop column change.
*/
- void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
+ void generate(DdlWrite writer, DropColumn dropColumn);
/**
* Write the AddTableComment change.
*/
- void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException;
+ void generate(DdlWrite writer, AddTableComment addTableComment);
/**
* Write the AddHistoryTable change.
*/
- void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
+ void generate(DdlWrite writer, AddHistoryTable addHistoryTable);
/**
* Write the DropHistoryTable change.
*/
- void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
+ void generate(DdlWrite writer, DropHistoryTable dropHistoryTable);
/**
* Generate the create index change.
*/
- void generate(DdlWrite writer, CreateIndex createIndex) throws IOException;
+ void generate(DdlWrite writer, CreateIndex createIndex);
/**
* Write the drop index change.
*/
- void generate(DdlWrite writer, DropIndex dropIndex) throws IOException;
+ void generate(DdlWrite writer, DropIndex dropIndex);
/**
* Write add unique constraint.
*/
- void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException;
+ void generate(DdlWrite writer, AddUniqueConstraint constraint);
/**
* Writes alter foreign key statements.
*/
- void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException;
+ void generate(DdlWrite writer, AlterForeignKey alterForeignKey);
/**
* Generate any extra DDL such as stored procedures or TableValueParameters.
*/
- void generateProlog(DdlWrite write) throws IOException;
+ void generateProlog(DdlWrite writer);
/**
* Generate any extra DDL such as regeneration of history triggers.
*/
- void generateEpilog(DdlWrite write) throws IOException;
+ void generateEpilog(DdlWrite writer);
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java
index f14c96762..69d0d2816 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java
@@ -1,14 +1,20 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbPlatformType;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
-import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -18,16 +24,13 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
public AbstractHanaDdl(DatabasePlatform platform) {
super(platform);
- this.addColumn = "add (";
- this.addColumnSuffix = ")";
- this.alterColumn = "alter (";
- this.alterColumnSuffix = ")";
- this.columnDropDefault = " default null";
- this.columnSetDefault = " default";
- this.columnSetNotnull = " not null";
+ this.addColumn = "add";
+ this.alterColumn = "alter";
+ this.columnDropDefault = "default null";
+ this.columnSetDefault = "default";
+ this.columnSetNotnull = "not null";
this.columnSetNull = " null";
- this.dropColumn = "drop (";
- this.dropColumnSuffix = ")";
+ this.dropColumn = "drop";
this.dropConstraintIfExists = "drop constraint ";
this.dropIndexIfExists = "drop index ";
this.dropSequenceIfExists = "drop sequence ";
@@ -39,7 +42,7 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
}
@Override
- public String alterColumnBaseAttributes(AlterColumn alter) {
+ public void alterColumn(DdlWrite writer, AlterColumn alter) {
String tableName = alter.getTableName();
String columnName = alter.getColumnName();
String currentType = alter.getCurrentType();
@@ -52,51 +55,21 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
: (alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue());
String defaultValueClause = (defaultValue == null || defaultValue.isEmpty()) ? "" : " default " + defaultValue;
- try {
- DdlBuffer buffer = new BaseDdlBuffer(null);
- if (!isConvertible(currentType, type)) {
- // add an intermediate conversion if possible
- if (isNumberType(currentType)) {
- // numbers can always be converted to decimal
- buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
- .append(" decimal ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix)
- .endOfStatement();
+ if (!isConvertible(currentType, type)) {
+ // add an intermediate conversion if possible
+ if (isNumberType(currentType)) {
+ // numbers can always be converted to decimal
+ alterTable(writer, tableName).append(alterColumn, columnName).append("decimal").append(notnullClause);
- } else if (isStringType(currentType)) {
- // strings can always be converted to nclob
- buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
- .append(" nclob ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix)
- .endOfStatement();
- }
+ } else if (isStringType(currentType)) {
+ // strings can always be converted to nclob
+ // Note: we do not add default clause here to avoid error[SAP DBTech JDBC: [336]: invalid default value:
+ // default value cannot be created on column of data type NCLOB
+ alterTable(writer, tableName).append(alterColumn, columnName).append("nclob").append(notnullClause);
}
-
- buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
- .append(" ").append(type).append(defaultValueClause).append(notnullClause).append(alterColumnSuffix);
-
- return buffer.getBuffer();
- } catch (IOException e) {
- throw new RuntimeException(e);
}
- }
- @Override
- public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
- return null;
- }
-
- @Override
- public DdlHandler createDdlHandler(DatabaseConfig config) {
- return new HanaDdlHandler(config, this);
- }
-
- @Override
- public String alterColumnType(String tableName, String columnName, String type) {
- return null;
+ alterTable(writer, tableName).append(alterColumn, columnName).append(type).append(defaultValueClause).append(notnullClause);
}
@Override
@@ -120,20 +93,17 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
@Override
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
- DdlBuffer buffer = new BaseDdlBuffer(null);
- try {
- buffer.append("delimiter $$").newLine();
- buffer.append("do").newLine();
- buffer.append("begin").newLine();
- buffer.append("declare exit handler for sql_error_code 397 begin end").endOfStatement();
- buffer.append("exec 'alter table ").append(tableName).append(" ").append(dropUniqueConstraint).append(" ")
- .append(maxConstraintName(uniqueConstraintName)).append("'").endOfStatement();
- buffer.append("end").endOfStatement();
- buffer.append("$$");
- return buffer.getBuffer();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ DdlBuffer buffer = new BaseDdlBuffer();
+
+ buffer.append("delimiter $$").newLine();
+ buffer.append("do").newLine();
+ buffer.append("begin").newLine();
+ buffer.append("declare exit handler for sql_error_code 397 begin end").endOfStatement();
+ buffer.append("exec 'alter table ").append(tableName).append(" ").append(dropUniqueConstraint).append(" ")
+ .append(maxConstraintName(uniqueConstraintName)).append("'").endOfStatement();
+ buffer.append("end").endOfStatement();
+ buffer.append("$$");
+ return buffer.getBuffer();
}
@Override
@@ -146,9 +116,8 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
* foreign keys. That's why we call a user stored procedure here
*/
@Override
- public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
- buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')")
- .endOfStatement();
+ public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
+ alterTable(writer, tableName).raw("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')");
}
/**
@@ -222,4 +191,71 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
return type != null
&& (type.startsWith("varchar") || type.startsWith("nvarchar") || "clob".equals(type) || "nclob".equals(type));
}
+
+ @Override
+ protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
+ return writer.applyAlterTable(tableName, HanaAlterTableWrite::new);
+ }
+
+ /**
+ * Joins alter table commands and add open/closing brackets for the alter statements
+ */
+ private static class HanaAlterTableWrite extends BaseAlterTableWrite {
+
+ public HanaAlterTableWrite(String tableName) {
+ super(tableName);
+ }
+
+ @Override
+ protected List postProcessCommands(List cmds) {
+ List newCmds = new ArrayList<>();
+ Map> batches = new LinkedHashMap<>();
+ Set columns = new HashSet<>();
+ for (AlterCmd cmd : cmds) {
+ switch (cmd.getOperation()) {
+ case "add":
+ case "alter":
+ case "drop":
+ if (cmd.getColumn() != null && !columns.add(cmd.getColumn())) {
+ // column already seen
+ flushBatches(newCmds, batches);
+ columns.clear();
+ }
+ batches.computeIfAbsent(cmd.getOperation(), k -> new ArrayList<>()).add(cmd);
+ break;
+ default:
+ flushBatches(newCmds, batches);
+ columns.clear();
+ newCmds.add(cmd);
+ }
+ }
+ flushBatches(newCmds, batches);
+ return newCmds;
+ }
+
+ /**
+ * Merges add/alter/drop commands into one statement.
+ */
+ private void flushBatches(List newCmds, Map> batches) {
+ for (Entry> entry : batches.entrySet()) {
+ AlterCmd raw = newRawCommand("alter table ").append(tableName()).append(" ")
+ .append(entry.getKey()).append(" (");
+ List cmds = entry.getValue();
+ for (int i = 0; i < cmds.size(); i++) {
+ AlterCmd cmd = cmds.get(i);
+ if (i > 0) {
+ raw.append(",\n ");
+ }
+ raw.append(cmd.getColumn());
+ if (!cmd.getAlternation().isEmpty()) {
+ raw.append(" ").append(cmd.getAlternation());
+ }
+ }
+ raw.append(")");
+ newCmds.add(raw);
+ }
+ batches.clear();
+ }
+ }
+
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseAlterTableWrite.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseAlterTableWrite.java
new file mode 100644
index 000000000..bd777d5a5
--- /dev/null
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseAlterTableWrite.java
@@ -0,0 +1,152 @@
+package io.ebeaninternal.dbmigration.ddlgeneration.platform;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
+
+/**
+ * Contains alter statements per table.
+ *
+ * @author Roland Praml, FOCONIS AG
+ */
+public class BaseAlterTableWrite implements DdlAlterTable {
+
+ protected static final String RAW_OPERATION = "$RAW";
+
+ public class AlterCmd {
+ // the command (e.g. "alter", "modify"
+ private final String operation;
+ // the affected column (note: each column can only be altered once on MariaDB)
+ private final String column;
+
+ private final DdlBuffer alternationBuffer = new BaseDdlBuffer() {
+ @Override
+ public DdlBuffer endOfStatement() {
+ throw new UnsupportedOperationException();
+ };
+ };
+
+ protected AlterCmd(String operation, String column) {
+ this.operation = operation;
+ this.column = column;
+ }
+
+ public AlterCmd append(String content) {
+ alternationBuffer.append(content);
+ return this;
+ }
+
+ public String getOperation() {
+ return operation;
+ }
+
+ public String getColumn() {
+ return column;
+ }
+
+ public String getAlternation() {
+ return alternationBuffer.getBuffer();
+ }
+
+ protected void write(Appendable target) throws IOException {
+ if (operation.equals(RAW_OPERATION)) {
+ // this is a raw command. e.g. an USP call. Must be done in the correct order
+ // of all alter commands
+ target.append(getAlternation());
+ } else {
+ target.append("alter table ").append(tableName).append(' ').append(operation);
+ if (column != null) {
+ target.append(' ').append(column);
+ }
+ if (!getAlternation().isEmpty()) {
+ target.append(' ').append(getAlternation());
+ }
+ }
+ }
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ try {
+ write(sb);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return sb.toString();
+ }
+ }
+
+ private final String tableName;
+
+ private List cmds = new ArrayList<>();
+
+ private boolean historyHandled;
+
+ public BaseAlterTableWrite(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String tableName() {
+ return tableName;
+ }
+
+ protected AlterCmd newRawCommand(String sql) {
+ AlterCmd cmd = new AlterCmd(RAW_OPERATION, null);
+ cmd.alternationBuffer.append(sql);
+ return cmd;
+ }
+
+ public AlterCmd newOperation(String operation, String column) {
+ return new AlterCmd(operation, column);
+ }
+
+ /**
+ * Adds a statement. The statement is prefixed with "alter table TABLENAME" and may be batched, if platform supports this. The
+ * returned StringBuilder can be used, to complete the statement
+ */
+ @Override
+ public DdlBuffer append(String operation, String column) {
+ AlterCmd cmd = new AlterCmd(operation, column);
+ cmds.add(cmd);
+ return cmd.alternationBuffer;
+ }
+
+ @Override
+ public DdlBuffer raw(String sql) {
+ AlterCmd cmd = newRawCommand(sql);
+ cmds.add(cmd);
+ return cmd.alternationBuffer;
+ }
+
+ /**
+ * Method can be overwritten to return a new list of commands. The given list must not be modified, but a new command list with
+ * modified commands can be returned (e.g. to handle DB2 reorg or special syntax in Hana)
+ */
+ protected List postProcessCommands(List cmds) {
+ return cmds;
+ }
+
+ /**
+ * Writes the DDL to target.
+ */
+ @Override
+ public void write(Appendable target) throws IOException {
+ for (AlterCmd cmd : postProcessCommands(Collections.unmodifiableList(cmds))) {
+ cmd.write(target);
+ target.append(";\n");
+ }
+ }
+
+ @Override
+ public boolean isHistoryHandled() {
+ return historyHandled;
+ }
+
+ @Override
+ public void setHistoryHandled() {
+ historyHandled = true;
+ }
+}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java
index e54e91ba0..674c07063 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java
@@ -1,45 +1,34 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import io.ebeaninternal.dbmigration.model.MConfiguration;
-import java.io.IOException;
-import java.io.StringWriter;
/**
* Base implementation of DdlBuffer using an underlying writer.
*/
public class BaseDdlBuffer implements DdlBuffer {
- protected final StringWriter writer;
+ protected final StringBuilder writer;
- protected final MConfiguration configuration;
-
- public BaseDdlBuffer(MConfiguration configuration) {
- this.configuration = configuration;
- this.writer = new StringWriter();
- }
-
- @Override
- public MConfiguration getConfiguration() {
- return configuration;
+ public BaseDdlBuffer() {
+ this.writer = new StringBuilder();
}
@Override
public boolean isEmpty() {
- return writer.getBuffer().length() == 0;
+ return writer.length() == 0;
}
@Override
- public DdlBuffer appendWithSpace(String foreignKeyRestrict) throws IOException {
- if (foreignKeyRestrict != null && !foreignKeyRestrict.isEmpty()) {
- writer.append(" ").append(foreignKeyRestrict);
+ public DdlBuffer appendWithSpace(String content) {
+ if (content != null && !content.isEmpty()) {
+ writer.append(" ").append(content);
}
return this;
}
@Override
- public DdlBuffer appendStatement(String content) throws IOException {
+ public DdlBuffer appendStatement(String content) {
if (content != null && !content.isEmpty()) {
writer.append(content);
endOfStatement();
@@ -48,19 +37,19 @@ public class BaseDdlBuffer implements DdlBuffer {
}
@Override
- public DdlBuffer append(String content) throws IOException {
+ public DdlBuffer append(String content) {
writer.append(content);
return this;
}
@Override
- public DdlBuffer append(String content, int space) throws IOException {
+ public DdlBuffer append(String content, int space) {
writer.append(content);
appendSpace(space, content);
return this;
}
- protected void appendSpace(int max, String content) throws IOException {
+ protected void appendSpace(int max, String content) {
int space = max - content.length();
if (space > 0) {
for (int i = 0; i < space; i++) {
@@ -71,7 +60,7 @@ public class BaseDdlBuffer implements DdlBuffer {
}
@Override
- public DdlBuffer endOfStatement() throws IOException {
+ public DdlBuffer endOfStatement() {
writer.append(";\n");
return this;
}
@@ -81,7 +70,7 @@ public class BaseDdlBuffer implements DdlBuffer {
* This should be just whitespace or a sql comment.
*/
@Override
- public DdlBuffer end() throws IOException {
+ public DdlBuffer end() {
if (!isEmpty()) {
writer.append("\n");
}
@@ -89,7 +78,7 @@ public class BaseDdlBuffer implements DdlBuffer {
}
@Override
- public DdlBuffer newLine() throws IOException {
+ public DdlBuffer newLine() {
writer.append("\n");
return this;
}
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 c4715fde3..da8c91d9f 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
@@ -11,7 +11,6 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.ddlgeneration.TableDdl;
-import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.IndexSet;
import io.ebeaninternal.dbmigration.migration.AddColumn;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
import io.ebeaninternal.dbmigration.migration.AddTableComment;
@@ -33,14 +32,9 @@ import io.ebeaninternal.dbmigration.model.MTable;
import io.ebeaninternal.dbmigration.model.MTableIdentity;
import io.ebeaninternal.server.deploy.IdentityMode;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
import static io.ebean.util.StringHelper.replace;
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
@@ -51,12 +45,6 @@ import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.s
*/
public class BaseTableDdl implements TableDdl {
- enum HistorySupport {
- NONE,
- SQL2011,
- TRIGGER_BASED
- }
-
protected final DbConstraintNaming naming;
protected final NamingConvention namingConvention;
@@ -65,12 +53,6 @@ public class BaseTableDdl implements TableDdl {
protected final String historyTableSuffix;
- /**
- * Used to check that indexes on foreign keys should be skipped as a unique index on the columns
- * already exists.
- */
- protected final IndexSet indexSet = new IndexSet();
-
/**
* Used when unique constraints specifically for OneToOne can't be created normally (MsSqlServer).
*/
@@ -78,26 +60,9 @@ public class BaseTableDdl implements TableDdl {
protected final List externalCompoundUnique = new ArrayList<>();
- // counters used when constraint names are truncated due to maximum length
- // and these counters are used to keep the constraint name unique
- protected int countCheck;
- protected int countUnique;
- protected int countForeignKey;
- protected int countIndex;
-
- /**
- * Base tables that have associated history tables that need their triggers/functions regenerated as
- * columns have been added, removed, included or excluded.
- */
- protected final Map regenerateHistoryTriggers = new LinkedHashMap<>();
-
- private final Set needsReorg = new HashSet<>();
-
- private int reorgCount;
-
private final boolean strictMode;
- private final HistorySupport historySupport;
+ private final boolean alterHistoryTables;
/**
* Helper class that is used to execute the migration ddl before and after the migration action.
@@ -148,32 +113,29 @@ public class BaseTableDdl implements TableDdl {
after = getScriptsForPlatform(alter.getAfter());
}
- void writeBefore(DdlBuffer buffer) throws IOException {
+ void write(DdlWrite writer) {
if (!before.isEmpty()) {
- buffer.end();
- flushReorgTables(buffer);
+ writer.apply().end();
if (withHistory) {
- buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
+ writer.apply().append("-- NOTE: table has @History - special migration may be necessary").newLine();
}
for (String ddlScript : before) {
- buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
+ writer.apply().appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
}
}
-
- }
-
- void writeAfter(DdlBuffer buffer) throws IOException {
+ // effective order in DDL.sql:
+ // 'before' goes to apply-buffer
+ // altered columns will be in the alterTable buffers.
+ // 'after' goes to the post-alter-buffer
if (!after.isEmpty()) {
- if (withHistory) {
- buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
- }
- flushReorgTables(buffer);
-
+ writer.applyPostAlter().append("-- NOTE: table has @History - special migration may be necessary").newLine();
+
// here we run post migration scripts
for (String ddlScript : after) {
- buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
+ writer.applyPostAlter().appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
}
- buffer.end();
+
+ writer.applyPostAlter().end();
}
}
@@ -221,9 +183,9 @@ public class BaseTableDdl implements TableDdl {
this.strictMode = config.isDdlStrictMode();
DbHistorySupport hist = platformDdl.getPlatform().getHistorySupport();
if (hist == null) {
- this.historySupport = HistorySupport.NONE;
+ this.alterHistoryTables = false;
} else {
- this.historySupport = hist.isStandardsBased() ? HistorySupport.SQL2011 : HistorySupport.TRIGGER_BASED;
+ this.alterHistoryTables = platformDdl.historyDdl.alterHistoryTables();
}
}
@@ -231,13 +193,8 @@ public class BaseTableDdl implements TableDdl {
* Reset counters and index set for each table processed.
*/
protected void reset() {
- indexSet.clear();
externalUnique.clear();
externalCompoundUnique.clear();
- countCheck = 0;
- countUnique = 0;
- countForeignKey = 0;
- countIndex = 0;
}
/**
@@ -245,7 +202,7 @@ public class BaseTableDdl implements TableDdl {
* and add them to the appropriate 'apply' and 'rollback' buffers.
*/
@Override
- public void generate(DdlWrite writer, CreateTable createTable) throws IOException {
+ public void generate(DdlWrite writer, CreateTable createTable) {
reset();
String tableName = lowerTableName(createTable.getName());
@@ -277,7 +234,7 @@ public class BaseTableDdl implements TableDdl {
}
}
if (platformDdl.isInlineForeignKeys()) {
- writeInlineForeignKeys(writer, createTable);
+ writeInlineForeignKeys(apply, createTable);
}
apply.newLine().append(")");
if (createTable.getTablespace() != null) {
@@ -322,7 +279,7 @@ public class BaseTableDdl implements TableDdl {
/**
* Add table and column comments (separate from the create table statement).
*/
- private void addComments(DdlBuffer apply, CreateTable createTable) throws IOException {
+ private void addComments(DdlBuffer apply, CreateTable createTable) {
if (!platformDdl.isInlineComments()) {
String tableComment = createTable.getComment();
if (hasValue(tableComment)) {
@@ -339,7 +296,7 @@ public class BaseTableDdl implements TableDdl {
/**
* Add the table storage engine clause.
*/
- private void addTableStorageEngine(DdlBuffer apply, CreateTable createTable) throws IOException {
+ private void addTableStorageEngine(DdlBuffer apply, CreateTable createTable) {
if (platformDdl.isIncludeStorageEngine()) {
platformDdl.tableStorageEngine(apply, createTable.getStorageEngine());
}
@@ -348,7 +305,7 @@ public class BaseTableDdl implements TableDdl {
/**
* Add the table comment inline with the create table statement.
*/
- private void addTableCommentInline(DdlBuffer apply, CreateTable createTable) throws IOException {
+ private void addTableCommentInline(DdlBuffer apply, CreateTable createTable) {
if (platformDdl.isInlineComments()) {
String tableComment = createTable.getComment();
if (!StringHelper.isNull(tableComment)) {
@@ -357,7 +314,7 @@ public class BaseTableDdl implements TableDdl {
}
}
- private void writeTableColumns(DdlBuffer apply, List columns, DdlIdentity identity) throws IOException {
+ private void writeTableColumns(DdlBuffer apply, List columns, DdlIdentity identity) {
platformDdl.writeTableColumns(apply, columns, identity);
}
@@ -365,7 +322,7 @@ public class BaseTableDdl implements TableDdl {
* Specific handling of OneToOne unique constraints for MsSqlServer.
* For all other DB platforms these unique constraints are done inline as per normal.
*/
- protected void writeUniqueOneToOneConstraints(DdlWrite write, CreateTable createTable) throws IOException {
+ protected void writeUniqueOneToOneConstraints(DdlWrite writer, CreateTable createTable) {
String tableName = createTable.getName();
for (Column col : externalUnique) {
String uqName = col.getUniqueOneToOne();
@@ -373,8 +330,9 @@ public class BaseTableDdl implements TableDdl {
uqName = col.getUnique();
}
String[] columnNames = {col.getName()};
- write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, Boolean.TRUE.equals(col.isNotnull()) ? null : columnNames));
- write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
+ String[] nullableColumns = Boolean.TRUE.equals(col.isNotnull()) ? null : columnNames;
+ writer.applyPostAlter().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns));
+ writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
}
for (UniqueConstraint constraint : externalCompoundUnique) {
@@ -382,12 +340,12 @@ public class BaseTableDdl implements TableDdl {
String[] columnNames = split(constraint.getColumnNames());
String[] nullableColumns = split(constraint.getNullableColumns());
- write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns));
- write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
+ writer.applyPostAlter().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns));
+ writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
}
}
- protected void writeSequence(DdlWrite writer, DdlIdentity identity) throws IOException {
+ protected void writeSequence(DdlWrite writer, DdlIdentity identity) {
String seqName = identity.getSequenceName();
String createSeq = platformDdl.createSequence(seqName, identity);
if (hasValue(createSeq)) {
@@ -396,75 +354,75 @@ public class BaseTableDdl implements TableDdl {
}
}
- protected void createWithHistory(DdlWrite writer, String name) throws IOException {
+ protected void createWithHistory(DdlWrite writer, String name) {
MTable table = writer.getTable(name);
platformDdl.createWithHistory(writer, table);
}
- protected void writeInlineForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
+ protected void writeInlineForeignKeys(DdlBuffer buffer, CreateTable createTable) {
for (Column column : createTable.getColumn()) {
String references = column.getReferences();
if (hasValue(references)) {
- writeInlineForeignKey(write, column);
+ writeInlineForeignKey(buffer, column);
}
}
- writeInlineCompoundForeignKeys(write, createTable);
+ writeInlineCompoundForeignKeys(buffer, createTable);
}
- protected void writeInlineForeignKey(DdlWrite write, Column column) throws IOException {
+ protected void writeInlineForeignKey(DdlBuffer buffer, Column column) {
String fkConstraint = platformDdl.tableInlineForeignKey(new WriteForeignKey(null, column));
- write.apply().append(",").newLine().append(" ").append(fkConstraint);
+ buffer.append(",").newLine().append(" ").append(fkConstraint);
}
- protected void writeInlineCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
+ protected void writeInlineCompoundForeignKeys(DdlBuffer buffer, CreateTable createTable) {
for (ForeignKey key : createTable.getForeignKey()) {
String fkConstraint = platformDdl.tableInlineForeignKey(new WriteForeignKey(null, key));
- write.apply().append(",").newLine().append(" ").append(fkConstraint);
+ buffer.append(",").newLine().append(" ").append(fkConstraint);
}
}
- protected void writeAddForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
+ protected void writeAddForeignKeys(DdlWrite writer, CreateTable createTable) {
for (Column column : createTable.getColumn()) {
String references = column.getReferences();
if (hasValue(references)) {
- writeForeignKey(write, createTable.getName(), column);
+ writeForeignKey(writer, createTable.getName(), column);
}
}
- writeAddCompoundForeignKeys(write, createTable);
+ writeAddCompoundForeignKeys(writer, createTable);
}
- protected void writeAddCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
+ protected void writeAddCompoundForeignKeys(DdlWrite writer, CreateTable createTable) {
for (ForeignKey key : createTable.getForeignKey()) {
- writeForeignKey(write, new WriteForeignKey(createTable.getName(), key));
+ writeForeignKey(writer, new WriteForeignKey(createTable.getName(), key));
}
}
- protected void writeForeignKey(DdlWrite write, String tableName, Column column) throws IOException {
- writeForeignKey(write, new WriteForeignKey(tableName, column));
+ protected void writeForeignKey(DdlWrite writer, String tableName, Column column) {
+ writeForeignKey(writer, new WriteForeignKey(tableName, column));
}
- protected void writeForeignKey(DdlWrite write, WriteForeignKey request) throws IOException {
- DdlBuffer fkeyBuffer = write.applyForeignKeys();
+ protected void writeForeignKey(DdlWrite writer, WriteForeignKey request) {
+ DdlBuffer fkeyBuffer = writer.applyForeignKeys();
String tableName = lowerTableName(request.table());
if (request.indexName() != null) {
// no matching unique constraint so add the index
fkeyBuffer.appendStatement(platformDdl.createIndex(new WriteCreateIndex(request.indexName(), tableName, request.cols(), false)));
}
- alterTableAddForeignKey(write.getOptions(), fkeyBuffer, request);
+ alterTableAddForeignKey(writer.getOptions(), fkeyBuffer, request);
fkeyBuffer.end();
- write.dropAllForeignKeys().appendStatement(platformDdl.alterTableDropForeignKey(tableName, request.fkName()));
+ writer.dropAllForeignKeys().appendStatement(platformDdl.alterTableDropForeignKey(tableName, request.fkName()));
if (hasValue(request.indexName())) {
- write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(request.indexName(), tableName));
+ writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(request.indexName(), tableName));
}
- write.dropAllForeignKeys().end();
+ writer.dropAllForeignKeys().end();
}
- protected void alterTableAddForeignKey(DdlOptions options, DdlBuffer buffer, WriteForeignKey request) throws IOException {
+ protected void alterTableAddForeignKey(DdlOptions options, DdlBuffer buffer, WriteForeignKey request) {
buffer.appendStatement(platformDdl.alterTableAddForeignKey(options, request));
}
- protected void appendColumns(String[] columns, DdlBuffer buffer) throws IOException {
+ protected void appendColumns(String[] columns, DdlBuffer buffer) {
buffer.append(" (");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
@@ -478,18 +436,18 @@ public class BaseTableDdl implements TableDdl {
/**
* Add 'drop table' statement to the buffer.
*/
- protected void dropTable(DdlBuffer buffer, String tableName) throws IOException {
+ protected void dropTable(DdlBuffer buffer, String tableName) {
buffer.appendStatement(platformDdl.dropTable(tableName));
}
/**
* Add 'drop sequence' statement to the buffer.
*/
- protected void dropSequence(DdlBuffer buffer, String sequenceName) throws IOException {
+ protected void dropSequence(DdlBuffer buffer, String sequenceName) {
buffer.appendStatement(platformDdl.dropSequence(sequenceName));
}
- protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
+ protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) {
boolean inlineUniqueWhenNull = platformDdl.isInlineUniqueWhenNullable();
for (UniqueConstraint uniqueConstraint : createTable.getUniqueConstraint()) {
if (platformInclude(uniqueConstraint.getPlatforms())) {
@@ -512,7 +470,7 @@ public class BaseTableDdl implements TableDdl {
/**
* Write the unique constraints inline with the create table statement.
*/
- protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
+ protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) {
boolean inlineUniqueWhenNullable = platformDdl.isInlineUniqueWhenNullable();
List columns = new WriteUniqueConstraint(createTable.getColumn()).uniqueKeys();
for (Column column : columns) {
@@ -529,7 +487,7 @@ public class BaseTableDdl implements TableDdl {
/**
* Write the unique constraint inline with the create table statement.
*/
- protected void inlineUniqueConstraintSingle(DdlBuffer buffer, Column column) throws IOException {
+ protected void inlineUniqueConstraintSingle(DdlBuffer buffer, Column column) {
String uqName = column.getUnique();
if (uqName == null) {
uqName = column.getUniqueOneToOne();
@@ -544,7 +502,7 @@ public class BaseTableDdl implements TableDdl {
/**
* Write the primary key constraint inline with the create table statement.
*/
- protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) throws IOException {
+ protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) {
buffer.append(",").newLine();
buffer.append(" constraint ").append(pkName).append(" primary key");
appendColumns(pkColumns, buffer);
@@ -589,43 +547,43 @@ public class BaseTableDdl implements TableDdl {
}
@Override
- public void generate(DdlWrite writer, CreateIndex index) throws IOException {
+ public void generate(DdlWrite writer, CreateIndex index) {
if (platformInclude(index.getPlatforms())) {
- flushReorgTables(writer.apply());
- writer.apply().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
+ writer.applyForeignKeys().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
writer.dropAll().appendStatement(platformDdl.dropIndex(index.getIndexName(), index.getTableName(), Boolean.TRUE.equals(index.isConcurrent())));
}
}
@Override
- public void generate(DdlWrite writer, DropIndex dropIndex) throws IOException {
+ public void generate(DdlWrite writer, DropIndex dropIndex) {
if (platformInclude(dropIndex.getPlatforms())) {
- flushReorgTables(writer.apply());
- writer.apply().appendStatement(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName(), Boolean.TRUE.equals(dropIndex.isConcurrent())));
+ writer.applyDropDependencies()
+ .appendStatement(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName(), Boolean.TRUE.equals(dropIndex.isConcurrent())));
}
}
@Override
- public void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException {
+ public void generate(DdlWrite writer, AddUniqueConstraint constraint) {
if (platformInclude(constraint.getPlatforms())) {
if (DdlHelp.isDropConstraint(constraint.getColumnNames())) {
- writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName()));
+ writer.applyDropDependencies()
+ .appendStatement(platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName()));
} else {
- flushReorgTables(writer.apply());
String[] cols = split(constraint.getColumnNames());
String[] nullableColumns = split(constraint.getNullableColumns());
- writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns));
+ writer.applyPostAlter()
+ .appendStatement(platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns));
}
}
}
@Override
- public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException {
+ public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) {
if (DdlHelp.isDropForeignKey(alterForeignKey.getColumnNames())) {
- writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName()));
+ writer.applyDropDependencies().appendStatement(platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName()));
} else {
- writer.apply().appendStatement(platformDdl.alterTableAddForeignKey(writer.getOptions(), new WriteForeignKey(alterForeignKey)));
+ writer.applyForeignKeys().appendStatement(platformDdl.alterTableAddForeignKey(writer.getOptions(), new WriteForeignKey(alterForeignKey)));
}
}
@@ -633,7 +591,7 @@ public class BaseTableDdl implements TableDdl {
* Add add history table DDL.
*/
@Override
- public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
+ public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) {
platformDdl.addHistoryTable(writer, addHistoryTable);
}
@@ -641,37 +599,27 @@ public class BaseTableDdl implements TableDdl {
* Add drop history table DDL.
*/
@Override
- public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
+ public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) {
platformDdl.dropHistoryTable(writer, dropHistoryTable);
}
@Override
- public void generateProlog(DdlWrite write) throws IOException {
- platformDdl.generateProlog(write);
+ public void generateProlog(DdlWrite writer) {
+ platformDdl.generateProlog(writer);
}
/**
* Called at the end to generate additional ddl such as regenerate history triggers.
*/
@Override
- public void generateEpilog(DdlWrite write) throws IOException {
- if (!regenerateHistoryTriggers.isEmpty()) {
- platformDdl.lockTables(write.applyHistoryTrigger(), regenerateHistoryTriggers.keySet());
-
- for (HistoryTableUpdate update : this.regenerateHistoryTriggers.values()) {
- platformDdl.regenerateHistoryTriggers(write, update);
- }
-
- platformDdl.unlockTables(write.applyHistoryTrigger(), regenerateHistoryTriggers.keySet());
- }
- platformDdl.generateEpilog(write);
- flushReorgTables(write.apply());
+ public void generateEpilog(DdlWrite writer) {
+ platformDdl.generateEpilog(writer);
}
@Override
- public void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException {
+ public void generate(DdlWrite writer, AddTableComment addTableComment) {
if (hasValue(addTableComment.getComment())) {
- platformDdl.addTableComment(writer.apply(), addTableComment.getName(), addTableComment.getComment());
+ platformDdl.addTableComment(writer.applyPostAlter(), addTableComment.getName(), addTableComment.getComment());
}
}
@@ -679,18 +627,20 @@ public class BaseTableDdl implements TableDdl {
* Add add column DDL.
*/
@Override
- public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
+ public void generate(DdlWrite writer, AddColumn addColumn) {
String tableName = addColumn.getTableName();
List columns = addColumn.getColumn();
for (Column column : columns) {
- alterTableAddColumn(writer.apply(), tableName, column, false, isTrue(addColumn.isWithHistory()));
+ alterTableAddColumn(writer, tableName, column, false, isTrue(addColumn.isWithHistory()));
}
- if (isTrue(addColumn.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
+ if (isTrue(addColumn.isWithHistory())) {
+ platformDdl.regenerateHistoryTriggers(writer, tableName);
// make same changes to the history table
- String historyTable = historyTable(tableName);
- for (Column column : columns) {
- regenerateHistoryTriggers(tableName, HistoryTableUpdate.Change.ADD, column.getName());
- alterTableAddColumn(writer.apply(), historyTable, column, true, true);
+ if (alterHistoryTables) {
+ String historyTable = historyTable(tableName);
+ for (Column column : columns) {
+ alterTableAddColumn(writer, historyTable, column, true, true);
+ }
}
}
for (Column column : columns) {
@@ -698,27 +648,26 @@ public class BaseTableDdl implements TableDdl {
writeForeignKey(writer, tableName, column);
}
}
- writer.apply().end();
}
/**
* Add drop table DDL.
*/
@Override
- public void generate(DdlWrite writer, DropTable dropTable) throws IOException {
- dropTable(writer.apply(), dropTable.getName());
+ public void generate(DdlWrite writer, DropTable dropTable) {
+ dropTable(writer.applyPostAlter(), dropTable.getName());
if (hasValue(dropTable.getSequenceCol())
&& platformDdl.getPlatform().getDbIdentity().isSupportsSequence()) {
String sequenceName = dropTable.getSequenceName();
if (!hasValue(sequenceName)) {
sequenceName = namingConvention.getSequenceName(dropTable.getName(), dropTable.getSequenceCol());
}
- dropSequence(writer.apply(), sequenceName);
+ dropSequence(writer.applyPostAlter(), sequenceName);
}
}
@Override
- public void generate(DdlWrite writer, AlterTable alterTable) throws IOException {
+ public void generate(DdlWrite writer, AlterTable alterTable) {
if (hasValue(alterTable.getTablespace()) || hasValue(alterTable.getIndexTablespace()) || hasValue(alterTable.getLobTablespace())) {
writer.apply().appendStatement(platformDdl.alterTableTablespace(alterTable.getName(),
DdlHelp.toTablespace(alterTable.getTablespace()),
@@ -727,8 +676,7 @@ public class BaseTableDdl implements TableDdl {
}
}
- protected void writeTablespaceChange(DdlBuffer buffer, String tablename, String tableSpace, String indexSpace,
- String lobSpace) throws IOException {
+ protected void writeTablespaceChange(DdlBuffer buffer, String tablename, String tableSpace, String indexSpace, String lobSpace) {
buffer.appendStatement("-- TableSpace changed: Table: " + tablename + ", tableSpace " + tableSpace + ", indexSpace "
+ indexSpace + ", lobSpace " + lobSpace);
if (strictMode) {
@@ -741,30 +689,32 @@ public class BaseTableDdl implements TableDdl {
* Add drop column DDL.
*/
@Override
- public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
+ public void generate(DdlWrite writer, DropColumn dropColumn) {
String tableName = dropColumn.getTableName();
- alterTableDropColumn(writer.apply(), tableName, dropColumn.getColumnName());
+ alterTableDropColumn(writer, tableName, dropColumn.getColumnName());
- if (isTrue(dropColumn.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
+ if (isTrue(dropColumn.isWithHistory())) {
+ platformDdl.regenerateHistoryTriggers(writer, tableName);
// also drop from the history table
- regenerateHistoryTriggers(tableName, HistoryTableUpdate.Change.DROP, dropColumn.getColumnName());
- alterTableDropColumn(writer.apply(), historyTable(tableName), dropColumn.getColumnName());
+ if (alterHistoryTables) {
+ alterTableDropColumn(writer, historyTable(tableName), dropColumn.getColumnName());
+ }
}
- writer.apply().end();
}
/**
* Add all the appropriate changes based on the column changes.
*/
@Override
- public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
+ public void generate(DdlWrite writer, AlterColumn alterColumn) {
DdlMigrationHelp ddlHelp = new DdlMigrationHelp(alterColumn);
- ddlHelp.writeBefore(writer.apply());
+ ddlHelp.write(writer);
- if (isTrue(alterColumn.isHistoryExclude())) {
- regenerateHistoryTriggers(alterColumn.getTableName(), HistoryTableUpdate.Change.EXCLUDE, alterColumn.getColumnName());
- } else if (isFalse(alterColumn.isHistoryExclude())) {
- regenerateHistoryTriggers(alterColumn.getTableName(), HistoryTableUpdate.Change.INCLUDE, alterColumn.getColumnName());
+ if (alterColumn.isHistoryExclude() != null) {
+ // CHECKME should we drop a small comment, if historyExclude changes, as not all DB systems will support this
+ // writer.apply().append("-- historyExclude of ").append(alterColumn.getTableName()).append(".").append(alterColumn.getColumnName())
+ // .append(" altered to ").append(String.valueOf(alterColumn.isHistoryExclude())).end();
+ platformDdl.regenerateHistoryTriggers(writer, alterColumn.getTableName());
}
if (hasValue(alterColumn.getDropForeignKey())) {
@@ -796,31 +746,21 @@ public class BaseTableDdl implements TableDdl {
// drop constraint before altering type etc
dropCheckConstraint(writer, alterColumn, alterColumn.getCheckConstraintName());
}
- boolean alterBaseAttributes = false;
- if (hasValue(alterColumn.getType())) {
- alterColumnType(writer, alterColumn);
- alterBaseAttributes = true;
- }
- if (hasValue(alterColumn.getDefaultValue())) {
- alterColumnDefaultValue(writer, alterColumn);
- alterBaseAttributes = true;
- }
- if (alterColumn.isNotnull() != null) {
- alterColumnNotnull(writer, alterColumn);
- alterBaseAttributes = true;
- }
- if (alterBaseAttributes) {
- alterColumnBaseAttributes(writer, alterColumn);
+
+ if (hasValue(alterColumn.getType())
+ || hasValue(alterColumn.getDefaultValue())
+ || alterColumn.isNotnull() != null) {
+ alterColumn(writer, alterColumn);
}
+
if (alterCheckConstraint) {
// add constraint last (after potential type change)
addCheckConstraint(writer, alterColumn);
}
- ddlHelp.writeAfter(writer.apply());
}
- private void alterColumnComment(DdlWrite writer, AlterColumn alterColumn) throws IOException {
- platformDdl.addColumnComment(writer.apply(), alterColumn.getTableName(), alterColumn.getColumnName(), alterColumn.getComment());
+ private void alterColumnComment(DdlWrite writer, AlterColumn alterColumn) {
+ platformDdl.addColumnComment(writer.applyPostAlter(), alterColumn.getTableName(), alterColumn.getColumnName(), alterColumn.getComment());
}
/**
@@ -831,124 +771,106 @@ public class BaseTableDdl implements TableDdl {
}
/**
- * Register the base table that we need to regenerate the history triggers on.
+ * alter all the base attributes (type/default/notnull) of the column together.
+ * Some platforms (like mysql/sqlserver/hana) must do that in one statement,
+ * other platforms may use several statements for altering one of the base
+ * attributes.
*/
- protected void regenerateHistoryTriggers(String baseTableName, HistoryTableUpdate.Change change, String column) {
- HistoryTableUpdate update = regenerateHistoryTriggers.computeIfAbsent(baseTableName, HistoryTableUpdate::new);
- update.add(change, column);
- }
+ protected void alterColumn(DdlWrite writer, AlterColumn alter) {
+ platformDdl.alterColumn(writer, alter);
- /**
- * This is mysql specific - alter all the base attributes of the column together.
- * Will be called, if there is a type, dbdefault or notnull change.
- */
- protected void alterColumnBaseAttributes(DdlWrite writer, AlterColumn alter) throws IOException {
- String ddl = platformDdl.alterColumnBaseAttributes(alter);
- if (hasValue(ddl)) {
- writer.apply().appendStatement(ddl);
-
- if (isTrue(alter.isWithHistory()) && alter.getType() != null && historySupport == HistorySupport.TRIGGER_BASED) {
- // mysql and sql server column type change allowing nulls in the history table column
- regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName());
- AlterColumn alterHistoryColumn = new AlterColumn();
- alterHistoryColumn.setTableName(historyTable(alter.getTableName()));
- alterHistoryColumn.setColumnName(alter.getColumnName());
- alterHistoryColumn.setType(alter.getType());
- String histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn);
-
- // write the apply to history table
- writer.apply().appendStatement(histColumnDdl);
+ if (isTrue(alter.isWithHistory())) {
+ // we will apply only type changes or notNull -> null transition
+ boolean isNull = Boolean.FALSE.equals(alter.isNotnull());
+ boolean applyToHistory = alter.getType() != null || isNull;
+ boolean syncExact = platformDdl.getPlatform().isPlatform(Platform.DB2);
+ // DB2 needs exact sync for notnull/null
+ if (syncExact && alter.isNotnull() != null) {
+ applyToHistory = true;
+ }
+ if (applyToHistory) {
+ platformDdl.regenerateHistoryTriggers(writer, alter.getTableName());
+ if (alterHistoryTables) {
+ AlterColumn alterHistoryColumn = new AlterColumn();
+ alterHistoryColumn.setTableName(historyTable(alter.getTableName()));
+ alterHistoryColumn.setColumnName(alter.getColumnName());
+ // ignore default value (not needed on history tables)
+ alterHistoryColumn.setCurrentType(alter.getCurrentType());
+ alterHistoryColumn.setType(alter.getType());
+ if (syncExact) {
+ alterHistoryColumn.setCurrentNotnull(alter.isCurrentNotnull());
+ alterHistoryColumn.setNotnull(alter.isNotnull());
+ } else if (isNull) {
+ // do transition from notNull to null
+ alterHistoryColumn.setCurrentNotnull(Boolean.TRUE);
+ alterHistoryColumn.setNotnull(Boolean.FALSE);
+ } else {
+ // assume that the column contains null values from the past (required for platforms like mysql/sqlserver/hana)
+ alterHistoryColumn.setCurrentNotnull(Boolean.FALSE);
+ }
+ platformDdl.alterColumn(writer, alterHistoryColumn);
+ }
}
}
}
- protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
- writer.apply().appendStatement(platformDdl.alterColumnDefaultValue(alter.getTableName(), alter.getColumnName(), alter.getDefaultValue()));
+ protected void dropCheckConstraint(DdlWrite writer, AlterColumn alter, String constraintName) {
+ writer.applyDropDependencies()
+ .appendStatement(platformDdl.alterTableDropConstraint(alter.getTableName(), constraintName));
}
- protected void dropCheckConstraint(DdlWrite writer, AlterColumn alter, String constraintName) throws IOException {
- writer.apply().appendStatement(platformDdl.alterTableDropConstraint(alter.getTableName(), constraintName));
+ protected void addCheckConstraint(DdlWrite writer, AlterColumn alter) {
+ writer.applyPostAlter()
+ .appendStatement(platformDdl.alterTableAddCheckConstraint(alter.getTableName(), alter.getCheckConstraintName(), alter.getCheckConstraint()));
}
- protected void addCheckConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
- writer.apply().appendStatement(platformDdl.alterTableAddCheckConstraint(alter.getTableName(), alter.getCheckConstraintName(), alter.getCheckConstraint()));
+ protected void alterColumnAddForeignKey(DdlWrite writer, AlterColumn alterColumn) {
+ alterTableAddForeignKey(writer.getOptions(), writer.applyForeignKeys(), new WriteForeignKey(alterColumn));
}
- protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) throws IOException {
- writer.apply().appendStatement(platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isNotnull()));
- needsReorg.add(alter.getTableName());
+ protected void alterColumnDropForeignKey(DdlWrite writer, AlterColumn alter) {
+ writer.applyDropDependencies()
+ .appendStatement(platformDdl.alterTableDropForeignKey(alter.getTableName(), alter.getDropForeignKey()));
}
- protected void alterColumnType(DdlWrite writer, AlterColumn alter) throws IOException {
- String ddl = platformDdl.alterColumnType(alter.getTableName(), alter.getColumnName(), alter.getType());
- if (hasValue(ddl)) {
- needsReorg.add(alter.getTableName());
- writer.apply().appendStatement(ddl);
- if (isTrue(alter.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
- regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName());
- // apply same type change to matching column in the history table
- ddl = platformDdl.alterColumnType(historyTable(alter.getTableName()), alter.getColumnName(), alter.getType());
- writer.apply().appendStatement(ddl);
- }
- }
+ protected void alterColumnDropUniqueConstraint(DdlWrite writer, AlterColumn alter) {
+ writer.applyDropDependencies()
+ .appendStatement(platformDdl.alterTableDropUniqueConstraint(alter.getTableName(), alter.getDropUnique()));
}
- protected void alterColumnAddForeignKey(DdlWrite writer, AlterColumn alterColumn) throws IOException {
- alterTableAddForeignKey(writer.getOptions(), writer.apply(), new WriteForeignKey(alterColumn));
- }
-
- protected void alterColumnDropForeignKey(DdlWrite writer, AlterColumn alter) throws IOException {
- writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alter.getTableName(), alter.getDropForeignKey()));
- }
-
- protected void alterColumnDropUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
- writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(alter.getTableName(), alter.getDropUnique()));
- }
-
- protected void alterColumnAddUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
+ protected void alterColumnAddUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alter) {
addUniqueConstraint(writer, alter, alter.getUniqueOneToOne());
}
- protected void alterColumnAddUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
+ protected void alterColumnAddUniqueConstraint(DdlWrite writer, AlterColumn alter) {
addUniqueConstraint(writer, alter, alter.getUnique());
}
- protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter, String uqName) throws IOException {
+ protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter, String uqName) {
String[] cols = {alter.getColumnName()};
boolean notNull = alter.isNotnull() != null ? alter.isNotnull() : Boolean.TRUE.equals(alter.isNotnull());
- writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull ? null : cols));
+ writer.applyPostAlter()
+ .appendStatement(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull ? null : cols));
writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, alter.getTableName()));
}
-
- protected void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
- platformDdl.alterTableDropColumn(buffer, tableName, columnName);
- needsReorg.add(tableName);
+ protected void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
+ platformDdl.alterTableDropColumn(writer, tableName, columnName);
}
- protected void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, boolean withHistory) throws IOException {
+ protected void alterTableAddColumn(DdlWrite writer, String tableName, Column column, boolean onHistoryTable, boolean withHistory) {
DdlMigrationHelp help = new DdlMigrationHelp(tableName, column, withHistory);
if (!onHistoryTable) {
- help.writeBefore(buffer);
+ help.write(writer);
}
- platformDdl.alterTableAddColumn(buffer, tableName, column, onHistoryTable, help.getDefaultValue());
+ platformDdl.alterTableAddColumn(writer, tableName, column, onHistoryTable, help.getDefaultValue());
final String comment = column.getComment();
if (comment != null && !comment.isEmpty()) {
- platformDdl.addColumnComment(buffer, tableName, column.getName(), comment);
+ platformDdl.addColumnComment(writer.applyPostAlter(), tableName, column.getName(), comment);
}
- if (!onHistoryTable) {
- help.writeAfter(buffer);
- }
- }
-
- protected void flushReorgTables(DdlBuffer buffer) throws IOException {
- for (String table : needsReorg) {
- buffer.appendStatement(platformDdl.reorgTable(table, ++reorgCount));
- }
- needsReorg.clear();
}
protected boolean isFalse(Boolean value) {
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java
index 0bb2f7895..469e58420 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java
@@ -15,6 +15,7 @@ class ClickHouseDbArray {
mapping.put("integer[]", "Array(UInt32)");
mapping.put("bigint[]", "Array(UInt64)");
mapping.put("float[]", "Array(Float32)");
+ mapping.put("decimal[]", "Array(Decimal)");
}
/**
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java
index 97f3bf8c7..940cdcf24 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java
@@ -6,8 +6,6 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
-import java.io.IOException;
-
public class ClickHouseDdl extends PlatformDdl {
private static final String LOG_TABLE = "ENGINE = Log()";
@@ -16,6 +14,7 @@ public class ClickHouseDdl extends PlatformDdl {
super(platform);
this.includeStorageEngine = true;
this.identitySuffix = "";
+ this.columnNotNull = null;
}
@Override
@@ -32,7 +31,7 @@ public class ClickHouseDdl extends PlatformDdl {
* Add an table storage engine to the create table statement.
*/
@Override
- public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException {
+ public void tableStorageEngine(DdlBuffer apply, String storageEngine) {
if (storageEngine == null) {
// default to Log() table but really should all be explicit (need arguments for MergeTree etc)
storageEngine = LOG_TABLE;
@@ -70,11 +69,6 @@ public class ClickHouseDdl extends PlatformDdl {
return null;
}
- @Override
- protected void writeColumnNotNull(DdlBuffer buffer) {
- // do nothing
- }
-
@Override
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
// do nothing
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/CockroachDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/CockroachDdl.java
index 7a14001fa..700000583 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/CockroachDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/CockroachDdl.java
@@ -36,6 +36,12 @@ public class CockroachDdl extends PlatformDdl {
// do nothing
}
+ @Override
+ public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
+ // workaround for: https://github.com/cockroachdb/cockroach/issues/42840
+ return "drop index " + maxConstraintName(uniqueConstraintName) + " cascade";
+ }
+
@Override
public boolean isInlineComments() {
return false;
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java
index aa1a95494..67c3eb133 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java
@@ -1,10 +1,14 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-import java.io.IOException;
-
-import io.ebean.annotation.ConstraintMode;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import io.ebean.util.StringHelper;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
+import io.ebeaninternal.dbmigration.migration.Column;
/**
* DB2 platform specific DDL.
@@ -44,6 +48,7 @@ public class DB2Ddl extends PlatformDdl {
this.columnSetNull = "drop not null";
this.columnSetType = "set data type ";
this.inlineUniqueWhenNullable = false;
+ this.historyDdl = new Db2HistoryDdl();
}
@Override
@@ -71,8 +76,9 @@ public class DB2Ddl extends PlatformDdl {
if (uqName == null) {
throw new NullPointerException();
}
- sb.append("create unique index ").append(maxConstraintName(uqName));
- sb.append(" on ").append(lowerTableName(tableName)).append('(');
+ sb = new StringBuilder("create unique index ");
+ sb.append(maxConstraintName(uqName)).append(" on ").append(tableName).append('(');
+
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
sb.append(",");
@@ -83,17 +89,82 @@ public class DB2Ddl extends PlatformDdl {
return sb.toString();
}
+
+ // @Override
+ // public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace)
+ // throws IOException {
+ // apply.append(" in ").append(tablespaceName).append(" index in ").append(indexTablespace).append(" long in ").append(lobTablespace);
+ // }
+
+ @Override
+ public void alterTableAddColumn(DdlWrite writer, String tableName, Column column, boolean onHistoryTable, String defaultValue) {
+
+ String convertedType = convert(column.getType());
+ DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, column.getName());
+ buffer.append(convertedType);
+
+ // Add default value also to history table if it is not excluded
+ if (defaultValue != null) {
+ buffer.append(" default ");
+ buffer.append(defaultValue);
+ }
+
+ if (isTrue(column.isNotnull())) {
+ buffer.appendWithSpace(columnNotNull);
+ }
+ // DB2 History table must match exact!
+ if (!onHistoryTable) {
+ // check constraints cannot be added in one statement for h2
+ if (!StringHelper.isNull(column.getCheckConstraint())) {
+ String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint());
+ writer.applyPostAlter().appendStatement(ddl);
+ }
+ }
+
+ }
+ @Override
+ public String alterTableDropForeignKey(String tableName, String fkName) {
+ return alterTableDropConstraint(tableName, fkName);
+ };
+
@Override
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
- return alterTableDropConstraint(tableName, uniqueConstraintName) + "\n"
- + dropIndex(uniqueConstraintName, tableName);
+ return alterTableDropConstraint(tableName, uniqueConstraintName)
+ + "\n" + dropIndex(uniqueConstraintName, tableName);
}
@Override
- protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
- // do nothing, no on update clause for db2
+ public String alterTableDropConstraint(String tableName, String constraintName) {
+ StringBuilder sb = new StringBuilder(300);
+ sb.append("delimiter $$\n")
+ .append("begin\n")
+ .append("if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = '")
+ .append(maxConstraintName(constraintName).toUpperCase())
+ .append("' and tabname = '").append(lowerTableName(tableName).toUpperCase()).append("') then\n")
+
+ .append(" prepare stmt from 'alter table ").append(lowerTableName(tableName))
+ .append(" drop constraint ").append(maxConstraintName(constraintName)).append("';\n")
+
+ .append(" execute stmt;\n")
+ .append("end if;\n")
+ .append("end$$");
+ return sb.toString();
+
}
+ @Override
+ public String dropIndex(String indexName, String tableName, boolean concurrent) {
+ StringBuilder sb = new StringBuilder(300);
+ sb.append("delimiter $$\n")
+ .append("begin\n")
+ .append("if exists (select indname from syscat.indexes where indschema = current_schema and indname = '")
+ .append(maxConstraintName(indexName).toUpperCase()).append("') then\n")
+ .append(" prepare stmt from 'drop index ").append(maxConstraintName(indexName)).append("';\n")
+ .append(" execute stmt;\n")
+ .append("end if;\n")
+ .append("end$$");
+ return sb.toString();
+ }
@Override
public String dropSequence(String sequenceName) {
@@ -101,61 +172,68 @@ public class DB2Ddl extends PlatformDdl {
sb.append("delimiter $$\n");
sb.append("begin\n");
sb.append("if exists (select seqschema from syscat.sequences where seqschema = current_schema and seqname = '")
- .append(maxConstraintName(sequenceName).toUpperCase()).append("') then\n");
+ .append(maxConstraintName(sequenceName).toUpperCase()).append("') then\n");
sb.append(" prepare stmt from 'drop sequence ").append(maxConstraintName(sequenceName)).append("';\n");
sb.append(" execute stmt;\n");
sb.append("end if;\n");
sb.append("end$$");
return sb.toString();
}
-
- @Override
- public String alterTableDropForeignKey(String tableName, String fkName) {
- return alterTableDropConstraint(tableName, fkName);
- }
- @Override
- public String alterTableDropConstraint(String tableName, String constraintName) {
- StringBuilder sb = new StringBuilder(300);
- sb.append("delimiter $$\n");
- sb.append("begin\n");
- sb.append("if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = '");
- sb.append(maxConstraintName(constraintName).toUpperCase());
- sb.append("' and tabname = '").append(lowerTableName(tableName).toUpperCase()).append("') then\n");
-
- sb.append(" prepare stmt from 'alter table ").append(lowerTableName(tableName));
- sb.append(" drop constraint ").append(maxConstraintName(constraintName)).append("';\n");
-
- sb.append(" execute stmt;\n");
- sb.append("end if;\n");
- sb.append("end$$");
- return sb.toString();
- }
-
- @Override
- public String dropIndex(String indexName, String tableName, boolean concurrent) {
- StringBuilder sb = new StringBuilder(300);
- sb.append("delimiter $$\n");
- sb.append("begin\n");
- sb.append("if exists (select indname from syscat.indexes where indschema = current_schema and indname = '");
- sb.append(maxConstraintName(indexName).toUpperCase()).append("') then\n");
+@Override
+protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
+ return writer.applyAlterTable(tableName, Db2AlterTableWrite::new);
+};
+ static class Db2AlterTableWrite extends BaseAlterTableWrite {
- sb.append(" prepare stmt from 'drop index ").append(maxConstraintName(indexName)).append("';\n");
- sb.append(" execute stmt;\n");
- sb.append("end if;\n");
- sb.append("end$$");
- return sb.toString();
- }
+ public Db2AlterTableWrite(String tableName) {
+ super(tableName);
+ }
- @Override
- public String reorgTable(String table, int counter) {
- return "call sysproc.admin_cmd('reorg table " + lowerTableName(table) + "') /* reorg #" + counter + " */";
+ @Override
+ protected List postProcessCommands(List cmds) {
+ List ret = new ArrayList<>(cmds.size() + 1);
+ boolean requiresReorg = false;
+ for (AlterCmd cmd : cmds) {
+ ret.add(cmd);
+ if (!requiresReorg && checkReorg(cmd)) {
+ requiresReorg = true;
+ }
+ }
+ if (requiresReorg) {
+ ret.add(newRawCommand("call sysproc.admin_cmd('reorg table " + tableName() + "')"));
+ }
+ return ret;
+ }
+
+ /**
+ * determine, if we need a reorg.
+ *
+ * See: https://www.ibm.com/docs/en/db2/11.5?topic=statements-alter-table The following is the full list of REORG-recommended
+ * ALTER statements that cause a version change and place the table into a REORG-pending state:
+ *
+ * - DROP COLUMN
+ *
- ALTER COLUMN SET NOT NULL
+ *
- ALTER COLUMN DROP NOT NULL
+ *
- ALTER COLUMN SET DATA TYPE, except in the following situations:
+ * Increasing the length of a VARCHAR or VARGRAPHIC column
+ * Decreasing the length of a VARCHAR or VARGRAPHIC column without truncating trailing blanks from existing data, when no indexes
+ * exist on the column
+ *
+ *
+ */
+ private boolean checkReorg(AlterCmd cmd) {
+ switch (cmd.getOperation()) {
+ case "drop column":
+ return true;
+ case "alter column":
+ String alter = cmd.getAlternation();
+ return alter.equals("set not null")
+ || alter.equals("drop not default")
+ || alter.startsWith("set data type"); // note: altering varchar length only is not detected here
+ default:
+ return false;
+ }
+ }
}
-
- @Override
- public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace)
- throws IOException {
- apply.append(" in ").append(tablespaceName).append(" index in ").append(indexTablespace).append(" long in ").append(lobTablespace);
- }
-
}
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
new file mode 100644
index 000000000..f1409974d
--- /dev/null
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/Db2HistoryDdl.java
@@ -0,0 +1,138 @@
+package io.ebeaninternal.dbmigration.ddlgeneration.platform;
+
+import java.util.Collection;
+
+import io.ebean.config.DatabaseConfig;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
+import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
+import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
+import io.ebeaninternal.dbmigration.model.MColumn;
+import io.ebeaninternal.dbmigration.model.MTable;
+
+/**
+ * DB2 History support.
+ *
+ * @author Roland Praml, FOCONIS AG
+ */
+public class Db2HistoryDdl implements PlatformHistoryDdl {
+
+ private String systemPeriodStart;
+ private String systemPeriodEnd;
+ private String transactionId;
+ private PlatformDdl platformDdl;
+ private String historySuffix;
+
+ @Override
+ public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
+ this.systemPeriodStart = config.getAsOfSysPeriod() + "_start";
+ this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end";
+ this.transactionId = config.getAsOfSysPeriod() + "_txn"; // required for DB2
+ this.platformDdl = platformDdl;
+ this.historySuffix = config.getHistoryTableSuffix();
+ }
+
+ @Override
+ public void createWithHistory(DdlWrite writer, MTable table) {
+ String tableName = table.getName();
+ String historyTableName = tableName + historySuffix;
+
+ DdlBuffer apply = writer.applyPostAlter();
+ apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName).append(" (").newLine();
+
+ // create history table
+ Collection cols = table.allColumns();
+ for (MColumn column : cols) {
+ if (!column.isDraftOnly()) {
+ writeColumnDefinition(apply, column.getName(), column.getType(), column.isNotnull() || column.isPrimaryKey());
+ apply.append(",").newLine();
+ }
+ }
+ writeColumnDefinition(apply, systemPeriodStart, "timestamp(12)", true);
+ apply.append(",").newLine();
+ writeColumnDefinition(apply, systemPeriodEnd, "timestamp(12)", true);
+ apply.append(",").newLine();
+ writeColumnDefinition(apply, transactionId, "timestamp(12)", false);
+ apply.newLine().append(")").endOfStatement();
+
+ // enable system versioning
+ addSysPeriodColumns(writer, tableName);
+ enableSystemVersioning(apply, tableName);
+ platformDdl.alterTable(writer, tableName).setHistoryHandled();
+
+ // drop all: We do not drop columns here, as the whole table will be dropped
+ disableSystemVersioning(writer.dropAll(), tableName);
+ writer.dropAll().append("drop table ").append(historyTableName).endOfStatement();
+ }
+
+ void addSysPeriodColumns(DdlWrite writer, String baseTable) {
+ platformDdl.alterTableAddColumn(writer, baseTable, systemPeriodStart, "timestamp(12) not null generated always as row begin", null);
+ platformDdl.alterTableAddColumn(writer, baseTable, systemPeriodEnd, "timestamp(12) not null generated always as row end", null);
+ platformDdl.alterTableAddColumn(writer, baseTable, transactionId, "timestamp(12) generated always as transaction start id", null);
+ platformDdl.alterTable(writer, baseTable).append("add period system_time", null)
+ .append("(").append(systemPeriodStart).append(",").append(systemPeriodEnd).append(")");
+ }
+
+ @Override
+ public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
+ dropHistoryTable(writer, dropHistoryTable.getBaseTable(), dropHistoryTable.getBaseTable() + historySuffix);
+ }
+
+ protected void dropHistoryTable(DdlWrite writer, String baseTable, String historyTable) {
+ disableSystemVersioning(writer.apply(), baseTable);
+ writer.apply().append("alter table ").append(baseTable).append(" drop period system_time").endOfStatement();
+
+ // drop the period & period columns
+ platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodStart);
+ platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodEnd);
+ platformDdl.alterTableDropColumn(writer, baseTable, transactionId);
+
+ // drop the history table
+ writer.applyPostAlter().append("drop table ").append(historyTable).endOfStatement();
+ }
+
+ @Override
+ public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
+ MTable table = writer.getTable(addHistoryTable.getBaseTable());
+ if (table == null) {
+ throw new IllegalStateException("MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)");
+ }
+ createWithHistory(writer, table);
+ }
+
+ @Override
+ public boolean alterHistoryTables() {
+ return true;
+ }
+
+ @Override
+ public void updateTriggers(DdlWrite writer, String tableName) {
+ DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
+ MTable table = writer.getTable(tableName);
+ if (table.isWithHistory() && !alter.isHistoryHandled()) {
+ disableSystemVersioning(writer.apply(), tableName);
+ enableSystemVersioning(writer.applyPostAlter(), tableName);
+ alter.setHistoryHandled();
+ }
+ }
+
+ protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type, boolean isNotNull) {
+
+ String platformType = platformDdl.convert(type);
+ buffer.append(" ").append(platformDdl.lowerColumnName(columnName));
+ buffer.append(" ").append(platformType);
+ if (isNotNull) {
+ buffer.append(" not null");
+ }
+ }
+
+ public void disableSystemVersioning(DdlBuffer apply, String tableName) {
+ apply.append("alter table ").append(tableName).append(" drop versioning").endOfStatement();
+ }
+
+ public void enableSystemVersioning(DdlBuffer apply, String tableName) {
+ apply.append("alter table ").append(tableName).append(" add versioning use history table ").append(tableName).append(historySuffix).endOfStatement();
+ }
+
+}
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 58bed4505..a7457b0ae 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
@@ -2,6 +2,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;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
@@ -9,8 +10,6 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.model.MColumn;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
-import java.util.Collection;
import java.util.List;
/**
@@ -49,51 +48,20 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
}
@Override
- public void updateTriggers(DdlWrite writer, HistoryTableUpdate update) throws IOException {
-
- MTable table = writer.getTable(update.getBaseTable());
- if (table == null) {
- throw new IllegalStateException("MTable " + update.getBaseTable() + " not found in writer? (required for history DDL)");
- }
- updateTriggers(writer, table, update);
- }
-
- /**
- * Replace the existing triggers/stored procedures/views for history table support given the included columns.
- */
- protected abstract void updateHistoryTriggers(DbTriggerUpdate triggerUpdate) throws IOException;
-
- /**
- * Process the HistoryTableUpdate which can result in changes to the apply, rollback
- * and drop scripts.
- */
- protected void updateTriggers(DdlWrite writer, MTable table, HistoryTableUpdate update) throws IOException {
-
- writer.applyHistoryTrigger().append("-- changes: ").append(update.description()).newLine();
-
- updateHistoryTriggers(createDbTriggerUpdate(writer, table));
- }
-
- protected DbTriggerUpdate createDbTriggerUpdate(DdlWrite writer, MTable table) {
-
- List columns = columnNamesForApply(table);
- String baseTableName = table.getName();
- String historyTableName = historyTableName(baseTableName);
- return new DbTriggerUpdate(baseTableName, historyTableName, writer, columns);
- }
-
- @Override
- public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
+ public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
String baseTable = dropHistoryTable.getBaseTable();
// drop in appropriate order
dropTriggers(writer.applyDropDependencies(), baseTable);
- dropHistoryTableEtc(writer.applyDropDependencies(), baseTable);
+ dropWithHistoryView(writer.applyDropDependencies(), baseTable);
+ dropHistoryTable(writer.applyDropDependencies(), baseTable);
+
+ dropSysPeriodColumns(writer, baseTable);
}
@Override
- public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
+ public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
String baseTable = addHistoryTable.getBaseTable();
MTable table = writer.getTable(baseTable);
@@ -105,27 +73,55 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
}
@Override
- public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
+ public void createWithHistory(DdlWrite writer, MTable table) {
String baseTable = table.getName();
- String whenCreatedColumn = table.getWhenCreatedColumn();
+ addSysPeriodColumns(writer, baseTable, table.getWhenCreatedColumn());
+ createHistoryTable(writer.applyPostAlter(), table);
+
+ createWithHistoryView(writer.applyPostAlter(), table.getName());
+ createTriggers(writer.applyPostAlter(), baseTable, columnNamesForApply(table));
+ writer.applyPostAlter().end();
+
+ // drop all scripts
dropTriggers(writer.dropAll(), baseTable);
- dropHistoryTableEtc(writer.dropAll(), baseTable);
+ dropWithHistoryView(writer.dropAll(), baseTable);
+ dropHistoryTable(writer.dropAll(), baseTable);
+ // no need to dropSysPeriodColumns as whole table will be deleted soon
- addHistoryTable(writer, table, whenCreatedColumn);
- createStoredFunction(writer, table);
- createTriggers(writer, table);
}
- protected abstract void createTriggers(DdlWrite writer, MTable table) throws IOException;
+ @Override
+ public void updateTriggers(DdlWrite writer, String tableName) {
+ MTable table = writer.getTable(tableName);
+ if (table != null && table.isWithHistory()) {
+ DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
+ if (!alter.isHistoryHandled()) {
+ // this code effectively disables history support before the table alter and enables it again
+ // immediately after the table alter. As all alters per table are altogether now, this can done here
+ dropTriggers(writer.apply(), tableName);
+ dropWithHistoryView(writer.apply(), tableName);
+ // here are the alter commands
+ createWithHistoryView(writer.applyPostAlter(), tableName);
+ createTriggers(writer.applyPostAlter(), tableName, columnNamesForApply(table));
- protected abstract void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException;
-
- protected void createStoredFunction(DdlWrite writer, MTable table) throws IOException {
- // do nothing
+ alter.setHistoryHandled();
+ }
+ }
}
+ /**
+ * Will add a history trigger to the buffer. The config
+ *
+ * @param buffer
+ * @param table
+ */
+ protected abstract void createTriggers(DdlBuffer buffer, String baseTable, List columnNames);
+
+ protected abstract void dropTriggers(DdlBuffer buffer, String baseTable);
+
+
protected String normalise(String tableName) {
return constraintNaming.normaliseTable(tableName);
}
@@ -150,35 +146,32 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
return normalise(baseTableName) + "_history_del";
}
- protected void addHistoryTable(DdlWrite writer, MTable table, String whenCreatedColumn) throws IOException {
+ protected void addHistoryTable(DdlWrite writer, MTable table, String whenCreatedColumn) {
String baseTableName = table.getName();
- DdlBuffer apply = writer.applyHistoryView();
- addSysPeriodColumns(apply, baseTableName, whenCreatedColumn);
- createHistoryTable(apply, table);
- createWithHistoryView(apply, baseTableName);
+ addSysPeriodColumns(writer, baseTableName, whenCreatedColumn);
+ createHistoryTable(writer.applyPostAlter(), table);
+ createWithHistoryView(writer.applyPostAlter(), baseTableName);
}
- protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
-
- apply.append("alter table ").append(baseTableName).append(" add column ")
- .append(sysPeriodStart).append(" ").append(sysPeriodType).append(" default ").append(now).endOfStatement();
- apply.append("alter table ").append(baseTableName).append(" add column ")
- .append(sysPeriodEnd).append(" ").append(sysPeriodType).endOfStatement();
+ protected void addSysPeriodColumns(DdlWrite writer, String baseTableName, String whenCreatedColumn) {
+ platformDdl.alterTableAddColumn(writer, baseTableName, sysPeriodStart, sysPeriodType, now);
+ platformDdl.alterTableAddColumn(writer, baseTableName, sysPeriodEnd, sysPeriodType, null);
if (whenCreatedColumn != null) {
- apply.append("update ").append(baseTableName).append(" set ").append(sysPeriodStart).append(" = ").append(whenCreatedColumn).endOfStatement();
+ writer.applyPostAlter()
+ .append("update ").append(baseTableName).append(" set ").append(sysPeriodStart).append(" = ").append(whenCreatedColumn).endOfStatement();
}
}
- protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
+ protected void createHistoryTable(DdlBuffer apply, MTable table) {
createHistoryTableAs(apply, table);
createHistoryTableWithPeriod(apply);
}
- protected void createHistoryTableAs(DdlBuffer apply, MTable table) throws IOException {
+ protected void createHistoryTableAs(DdlBuffer apply, MTable table) {
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(table.getName()).append(historySuffix).append("(").newLine();
for (MColumn column : table.allColumns()) {
if (!column.isDraftOnly()) {
@@ -188,7 +181,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
}
}
- protected void createHistoryTableWithPeriod(DdlBuffer apply) throws IOException {
+ protected void createHistoryTableWithPeriod(DdlBuffer apply) {
writeColumnDefinition(apply, sysPeriodStart, sysPeriodType);
apply.append(",").newLine();
writeColumnDefinition(apply, sysPeriodEnd, sysPeriodType);
@@ -198,7 +191,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
/**
* Write the column definition to the create table statement.
*/
- protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type) throws IOException {
+ protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type) {
String platformType = platformDdl.convert(type);
buffer.append(" ");
@@ -206,57 +199,43 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
buffer.append(platformType);
}
- protected void createWithHistoryView(DdlBuffer apply, String baseTableName) throws IOException {
+ protected void createWithHistoryView(DdlBuffer apply, String baseTableName) {
apply
.append("create view ").append(baseTableName).append(viewSuffix)
.append(" as select * from ").append(baseTableName)
.append(" union all select * from ").append(baseTableName).append(historySuffix)
- .endOfStatement().end();
+ .endOfStatement();
}
-
- /**
- * For postgres/h2/mysql we need to drop and recreate the view. Well, we could add columns to the end of the view
- * but otherwise we need to drop and create it.
- */
- protected void recreateHistoryView(DbTriggerUpdate update) throws IOException {
-
- DdlBuffer buffer = update.dropDependencyBuffer();
- // we need to drop the view early/first before any changes to the tables etc
- buffer.append("drop view if exists ").append(update.getBaseTable()).append(viewSuffix).endOfStatement();
-
- // recreate the view after all ddl modifications - the view requires ALL columns, also the historyExclude ones.
- createWithHistoryView(update.historyViewBuffer(), update.getBaseTable());
- }
-
- protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
+ protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) {
appendColumnName(apply, prefix, sysPeriodStart);
appendColumnName(apply, prefix, sysPeriodEnd);
}
- protected void dropHistoryTableEtc(DdlBuffer buffer, String baseTableName) throws IOException {
-
- buffer.append("drop view ").append(baseTableName).append(viewSuffix).endOfStatement();
- dropSysPeriodColumns(buffer, baseTableName);
- buffer.append("drop table ").append(baseTableName).append(historySuffix).endOfStatement().end();
+ protected void dropWithHistoryView(DdlBuffer apply, String baseTableName) {
+ apply.append("drop view ").append(baseTableName).append(viewSuffix).endOfStatement();
}
- protected void dropSysPeriodColumns(DdlBuffer buffer, String baseTableName) throws IOException {
- platformDdl.alterTableDropColumn(buffer, baseTableName, sysPeriodStart);
- platformDdl.alterTableDropColumn(buffer, baseTableName, sysPeriodEnd);
+ protected void dropHistoryTable(DdlBuffer apply, String baseTableName) {
+ apply.append("drop table ").append(baseTableName).append(historySuffix).endOfStatement().end();
}
- protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List columns) throws IOException {
+ protected void dropSysPeriodColumns(DdlWrite writer, String baseTableName) {
+ platformDdl.alterTableDropColumn(writer, baseTableName, sysPeriodStart);
+ platformDdl.alterTableDropColumn(writer, baseTableName, sysPeriodEnd);
+ }
- buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriodStart).append(",").append(sysPeriodEnd).append(",");
+ protected void appendInsertIntoHistory(DdlBuffer buffer, String baseTable, List columns) {
+
+ buffer.append(" insert into ").append(baseTable).append(historySuffix).append(" (").append(sysPeriodStart).append(",").append(sysPeriodEnd).append(",");
appendColumnNames(buffer, columns, "");
buffer.append(") values (OLD.").append(sysPeriodStart).append(", ").append(sysPeriodEndValue).append(",");
appendColumnNames(buffer, columns, "OLD.");
buffer.append(");").newLine();
}
- void appendColumnNames(DdlBuffer buffer, List columns, String columnPrefix) throws IOException {
+ void appendColumnNames(DdlBuffer buffer, List columns, String columnPrefix) {
for (int i = 0; i < columns.size(); i++) {
if (i > 0) {
buffer.append(", ");
@@ -269,7 +248,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
/**
* Append a single column to the buffer if it is not null.
*/
- void appendColumnName(DdlBuffer buffer, String prefix, String columnName) throws IOException {
+ void appendColumnName(DdlBuffer buffer, String prefix, String columnName) {
if (columnName != null) {
buffer.append(prefix).append(columnName);
}
@@ -287,4 +266,8 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
return table.allHistoryColumns(true);
}
+ @Override
+ public boolean alterHistoryTables() {
+ return true;
+ }
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerUpdate.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerUpdate.java
deleted file mode 100644
index fa90a233e..000000000
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerUpdate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
-
-import java.util.List;
-
-/**
- * DB trigger update when a change occurs on a table with history.
- */
-public class DbTriggerUpdate {
-
- private final String baseTableName;
-
- private final String historyTableName;
-
- private final DdlWrite writer;
-
- private final List columns;
-
- public DbTriggerUpdate(String baseTableName, String historyTableName, DdlWrite writer, List columns) {
- this.baseTableName = baseTableName;
- this.historyTableName = historyTableName;
- this.writer = writer;
- this.columns = columns;
- }
-
- /**
- * Return the appropriate buffer for the current mode.
- */
- public DdlBuffer historyViewBuffer() {
- return writer.applyHistoryView();
- }
-
- /**
- * Return the appropriate buffer for the current mode.
- */
- public DdlBuffer historyTriggerBuffer() {
- return writer.applyHistoryTrigger();
- }
-
-
- /**
- * Return the appropriate drop dependency buffer for the current mode.
- */
- public DdlBuffer dropDependencyBuffer() {
- return writer.applyDropDependencies();
- }
-
- /**
- * Return the base table name.
- */
- public String getBaseTable() {
- return baseTableName;
- }
-
- /**
- * Return the history table name.
- */
- public String getHistoryTable() {
- return historyTableName;
- }
-
- /**
- * Return the included columns.
- */
- public List getColumns() {
- return columns;
- }
-
-}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/H2HistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/H2HistoryDdl.java
index 5bd58adeb..7e5d2aa87 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/H2HistoryDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/H2HistoryDdl.java
@@ -1,10 +1,8 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
-import io.ebeaninternal.dbmigration.model.MTable;
+import java.util.List;
-import java.io.IOException;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
/**
* H2 history support using DB triggers to maintain a history table.
@@ -20,26 +18,16 @@ public class H2HistoryDdl extends DbTriggerBasedHistoryDdl {
}
@Override
- protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
+ protected void dropTriggers(DdlBuffer buffer, String baseTable) {
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
}
@Override
- protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
- String baseTableName = table.getName();
- DdlBuffer apply = writer.applyHistoryTrigger();
- addCreateTrigger(apply, updateTriggerName(baseTableName), baseTableName);
+ protected void createTriggers(DdlBuffer buffer, String baseTable, List columnNames) {
+ addCreateTrigger(buffer, updateTriggerName(baseTable), baseTable);
}
- @Override
- protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
- recreateHistoryView(update);
- DdlBuffer buffer = update.historyTriggerBuffer();
- dropTriggers(buffer, update.getBaseTable());
- addCreateTrigger(buffer, updateTriggerName(update.getBaseTable()), update.getBaseTable());
- }
-
- private void addCreateTrigger(DdlBuffer apply, String triggerName, String baseTable) throws IOException {
+ private void addCreateTrigger(DdlBuffer apply, String triggerName, String baseTable) {
// Note that this does not take into account the historyTable name (excepts _history suffix) and
// does not take into account excluded columns (all columns included in history)
apply
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaColumnStoreDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaColumnStoreDdl.java
index 872fc3930..b1fbd08a8 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaColumnStoreDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaColumnStoreDdl.java
@@ -3,8 +3,6 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import java.io.IOException;
-
public class HanaColumnStoreDdl extends AbstractHanaDdl {
public HanaColumnStoreDdl(DatabasePlatform platform) {
@@ -31,20 +29,16 @@ public class HanaColumnStoreDdl extends AbstractHanaDdl {
@Override
public String dropIndex(String indexName, String tableName, boolean concurrent) {
- DdlBuffer buffer = new BaseDdlBuffer(null);
- try {
- buffer.append("delimiter $$").newLine();
- buffer.append("do").newLine();
- buffer.append("begin").newLine();
- buffer.append("declare exit handler for sql_error_code 261 begin end").endOfStatement();
- buffer.append("exec '").append(dropIndexIfExists).append(maxConstraintName(indexName)).append("'")
- .endOfStatement();
- buffer.append("end").endOfStatement();
- buffer.append("$$");
- return buffer.getBuffer();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ DdlBuffer buffer = new BaseDdlBuffer();
+ buffer.append("delimiter $$").newLine();
+ buffer.append("do").newLine();
+ buffer.append("begin").newLine();
+ buffer.append("declare exit handler for sql_error_code 261 begin end").endOfStatement();
+ buffer.append("exec '").append(dropIndexIfExists).append(maxConstraintName(indexName)).append("'")
+ .endOfStatement();
+ buffer.append("end").endOfStatement();
+ buffer.append("$$");
+ return buffer.getBuffer();
}
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaDdlHandler.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaDdlHandler.java
deleted file mode 100644
index 47172dc30..000000000
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaDdlHandler.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-
-import io.ebean.config.DatabaseConfig;
-import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
-
-public class HanaDdlHandler extends BaseDdlHandler {
-
- public HanaDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
- super(config, platformDdl, new HanaTableDdl(config, platformDdl));
- }
-}
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 3624fa1da..f0f4cf8ac 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.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
@@ -8,11 +9,7 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.model.MColumn;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
public class HanaHistoryDdl implements PlatformHistoryDdl {
@@ -20,8 +17,6 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
private String systemPeriodEnd;
private PlatformDdl platformDdl;
private String historySuffix;
- private final AtomicInteger counter = new AtomicInteger(0);
- private Map createdHistoryTables = new ConcurrentHashMap<>();
@Override
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
@@ -32,13 +27,10 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
}
@Override
- public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
+ public void createWithHistory(DdlWrite writer, MTable table) {
String tableName = table.getName();
String historyTableName = tableName + historySuffix;
- DdlBuffer apply = writer.applyHistoryView();
- if (apply.isEmpty()) {
- createdHistoryTables.clear();
- }
+ DdlBuffer apply = writer.applyPostAlter();
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName).append(" (").newLine();
@@ -65,20 +57,19 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
apply.append("alter table ").append(tableName).append(" add period for system_time(").append(systemPeriodStart)
.append(",").append(systemPeriodEnd).append(")").endOfStatement();
- enableSystemVersioning(apply, tableName, historyTableName, true, false);
-
- createdHistoryTables.put(tableName, historyTableName);
+ enableSystemVersioning(apply, tableName, true);
+ platformDdl.alterTable(writer, tableName).setHistoryHandled();
dropHistoryTable(writer.dropAll(), tableName, historyTableName);
}
@Override
- public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
+ public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
dropHistoryTable(writer.applyDropDependencies(), dropHistoryTable.getBaseTable(),
dropHistoryTable.getBaseTable() + historySuffix);
}
- protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) throws IOException {
+ protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) {
// disable system versioning
disableSystemVersioning(apply, baseTable);
@@ -93,7 +84,7 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
}
@Override
- public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
+ public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
MTable table = writer.getTable(addHistoryTable.getBaseTable());
if (table == null) {
throw new IllegalStateException("MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)");
@@ -102,12 +93,23 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
}
@Override
- public void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) {
- // nothing to do
+ public boolean alterHistoryTables() {
+ return true;
+ }
+
+ @Override
+ public void updateTriggers(DdlWrite writer, String tableName) {
+ DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
+ MTable table = writer.getTable(tableName);
+ if (table.isWithHistory() && !alter.isHistoryHandled()) {
+ disableSystemVersioning(writer.apply(), tableName);
+ enableSystemVersioning(writer.applyPostAlter(), tableName, false);
+ alter.setHistoryHandled();
+ }
}
protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type, String defaultValue,
- boolean isNotNull, String generated) throws IOException {
+ boolean isNotNull, String generated) {
String platformType = platformDdl.convert(type);
buffer.append(" ").append(platformDdl.lowerColumnName(columnName));
@@ -123,35 +125,16 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
}
}
- public void disableSystemVersioning(DdlBuffer apply, String tableName) throws IOException {
- disableSystemVersioning(apply, tableName, false);
+ public void disableSystemVersioning(DdlBuffer apply, String tableName) {
+ apply.append("alter table ").append(tableName).append(" drop system versioning").endOfStatement();
}
- public void disableSystemVersioning(DdlBuffer apply, String tableName, boolean uniqueStatement) throws IOException {
- apply.append("alter table ").append(tableName).append(" drop system versioning");
- if (uniqueStatement) {
- // needed for the DB migration test to prevent the statement from being filtered
- // out as a duplicate
- apply.append(" /* ").append(String.valueOf(counter.getAndIncrement())).append(" */");
- }
- apply.endOfStatement();
- }
-
- public void enableSystemVersioning(DdlBuffer apply, String tableName, String historyTableName, boolean validated,
- boolean uniqueStatement) throws IOException {
- apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(historyTableName);
+ 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);
if (!validated) {
apply.append(" not validated");
}
- if (uniqueStatement) {
- // needed for the DB migration test to prevent the statement from being filtered
- // out as a duplicate
- apply.append(" /* ").append(String.valueOf(counter.getAndIncrement())).append(" */");
- }
apply.endOfStatement();
}
- public boolean isSystemVersioningEnabled(String tableName) {
- return !createdHistoryTables.containsKey(tableName);
- }
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaTableDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaTableDdl.java
deleted file mode 100644
index 341fe9517..000000000
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaTableDdl.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-
-import io.ebean.config.DatabaseConfig;
-import io.ebean.config.PropertiesWrapper;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
-import io.ebeaninternal.dbmigration.migration.AddColumn;
-import io.ebeaninternal.dbmigration.migration.AlterColumn;
-import io.ebeaninternal.dbmigration.migration.Column;
-import io.ebeaninternal.dbmigration.migration.DropColumn;
-import io.ebeaninternal.dbmigration.model.MTable;
-
-import java.io.IOException;
-import java.util.List;
-
-public class HanaTableDdl extends BaseTableDdl {
-
- private final HanaHistoryDdl historyDdl;
- private final boolean generateUniqueDdl;
-
- public HanaTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
- super(config, platformDdl);
- this.historyDdl = (HanaHistoryDdl) platformDdl.historyDdl;
- if (config.getProperties() != null) {
- PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "hana", config.getProperties(), config.getClassLoadConfig());
- this.generateUniqueDdl = wrapper.getBoolean("generateUniqueDdl", false);
- } else {
- this.generateUniqueDdl = false;
- }
- }
-
- @Override
- protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
- // done in alterColumnBaseAttributes
- }
-
- @Override
- public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
- String tableName = addColumn.getTableName();
- MTable table = writer.getTable(tableName);
- if (table == null) {
- super.generate(writer, addColumn);
- return;
- }
-
- boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
-
- if (manageSystemVersioning) {
- historyDdl.disableSystemVersioning(writer.apply(), table.getName(), this.generateUniqueDdl);
- }
-
- super.generate(writer, addColumn);
-
- if (manageSystemVersioning) {
- // make same changes to the history table
- String historyTable = historyTable(tableName);
- List columns = addColumn.getColumn();
- for (Column column : columns) {
- alterTableAddColumn(writer.apply(), historyTable, column, true, true);
- }
-
- historyDdl.enableSystemVersioning(writer.apply(), table.getName(), historyTable, false, this.generateUniqueDdl);
- }
- }
-
- @Override
- public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
- String tableName = alterColumn.getTableName();
- MTable table = writer.getTable(tableName);
- if (table == null) {
- super.generate(writer, alterColumn);
- return;
- }
-
- boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
-
- if (manageSystemVersioning) {
- historyDdl.disableSystemVersioning(writer.apply(), tableName, this.generateUniqueDdl);
- }
-
- super.generate(writer, alterColumn);
-
- if (manageSystemVersioning) {
- // make same changes to the history table
- String historyTable = historyTable(tableName);
- if (hasValue(alterColumn.getType()) || hasValue(alterColumn.getDefaultValue()) || alterColumn.isNotnull() != null) {
- AlterColumn alterHistoryColumn = new AlterColumn();
- alterHistoryColumn.setTableName(historyTable);
- alterHistoryColumn.setColumnName(alterColumn.getColumnName());
- alterHistoryColumn.setType(alterColumn.getType());
- alterHistoryColumn.setDefaultValue(alterColumn.getDefaultValue());
- alterHistoryColumn.setNotnull(alterColumn.isNotnull());
- alterHistoryColumn.setCurrentType(alterColumn.getCurrentType());
- alterHistoryColumn.setCurrentDefaultValue(alterColumn.getCurrentDefaultValue());
- alterHistoryColumn.setCurrentNotnull(alterColumn.isCurrentNotnull());
- String histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn);
-
- // write the apply to history table
- writer.apply().append(histColumnDdl).endOfStatement();
- }
-
- historyDdl.enableSystemVersioning(writer.apply(), tableName, historyTable, false, this.generateUniqueDdl);
- }
- }
-
- @Override
- public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
- String tableName = dropColumn.getTableName();
- MTable table = writer.getTable(tableName);
- if (table == null) {
- super.generate(writer, dropColumn);
- return;
- }
-
- boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
-
- if (manageSystemVersioning) {
- historyDdl.disableSystemVersioning(writer.apply(), tableName, this.generateUniqueDdl);
- }
-
- super.generate(writer, dropColumn);
-
- if (manageSystemVersioning) {
- // also drop from the history table
- String historyTable = historyTable(tableName);
- alterTableDropColumn(writer.apply(), historyTable, dropColumn.getColumnName());
-
- historyDdl.enableSystemVersioning(writer.apply(), tableName, historyTable, false, this.generateUniqueDdl);
- }
- }
-
-}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HistoryTableUpdate.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HistoryTableUpdate.java
deleted file mode 100644
index a72350a1f..000000000
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HistoryTableUpdate.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Bean holding comments relating to a history table that needs to have it's
- * associated triggers/function updated due to columns added/dropped/included
- * or excluded.
- */
-public class HistoryTableUpdate {
-
- /**
- * Column change type.
- */
- public enum Change {
- ADD,
- DROP,
- INCLUDE,
- EXCLUDE,
- ALTER
- }
-
- private static class Column {
-
- final Change change;
-
- final String column;
-
- public Column(Change change, String column) {
- this.change = change;
- this.column = column;
- }
-
- @Override
- public String toString() {
- return description();
- }
-
- public String description() {
- return change.name().toLowerCase() + " " + column;
- }
-
- }
-
- private final String baseTable;
-
- private final List columnChanges = new ArrayList<>();
-
- /**
- * Construct with a given base table name.
- */
- public HistoryTableUpdate(String baseTable) {
- this.baseTable = baseTable;
- }
-
- /**
- * Return a description of the changes that cause the history trigger/function
- * to be regenerated (added, included, excluded and dropped columns).
- */
- public String description() {
- return columnChanges.toString();
- }
-
- /**
- * Add a comment for column added, dropped, included or excluded.
- */
- public void add(Change change, String column) {
- columnChanges.add(new Column(change, column));
- }
-
- /**
- * Return the base table name.
- */
- public String getBaseTable() {
- return baseTable;
- }
-
-}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MariaDbHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MariaDbHistoryDdl.java
index 3fbdfad61..31d3cdd91 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MariaDbHistoryDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MariaDbHistoryDdl.java
@@ -1,53 +1,59 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.DatabaseConfig;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
-
/**
* History DDL for MariaDB.
*/
public class MariaDbHistoryDdl implements PlatformHistoryDdl {
+ private PlatformDdl platformDdl;
+
@Override
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
- // do nothing
+ this.platformDdl = platformDdl;
}
@Override
- public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
+ public void createWithHistory(DdlWrite writer, MTable table) {
String baseTable = table.getName();
enableSystemVersioning(writer, baseTable);
}
- private void enableSystemVersioning(DdlWrite writer, String baseTable) throws IOException {
- DdlBuffer apply = writer.applyHistoryView();
- apply.append("alter table ").append(baseTable).append(" add system versioning").endOfStatement();
+ private void enableSystemVersioning(DdlWrite writer, String baseTable) {
+ platformDdl.alterTable(writer, baseTable).append("add system versioning", null);
DdlBuffer drop = writer.dropAll();
drop.append("alter table ").append(baseTable).append(" drop system versioning").endOfStatement();
}
@Override
- public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
+ public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
String baseTable = dropHistoryTable.getBaseTable();
- DdlBuffer apply = writer.applyHistoryView();
- apply.append("alter table ").append(baseTable).append(" drop system versioning").endOfStatement();
+ platformDdl.alterTable(writer, baseTable).append("drop system versioning", null);
}
@Override
- public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
+ public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
String baseTable = addHistoryTable.getBaseTable();
enableSystemVersioning(writer, baseTable);
}
@Override
- public void updateTriggers(DdlWrite writer, HistoryTableUpdate baseTable) {
- // do nothing
+ public void updateTriggers(DdlWrite writer, String tableName) {
+ MTable table = writer.getTable(tableName);
+ // For MariaDB we need to enable system_versioning_alter_history only once
+ // per DDL script. This info is stored in the virtual "__$HISTORY_FLAG__" table
+ DdlAlterTable history = platformDdl.alterTable(writer, "__$HISTORY_FLAG__");
+ if (table != null && table.isWithHistory() && !history.isHistoryHandled()) {
+ writer.apply().appendStatement("SET @@system_versioning_alter_history = 1");
+ history.setHistoryHandled();
+ }
}
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java
index c772a30aa..d8ec08128 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java
@@ -3,12 +3,10 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.util.StringHelper;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.Column;
-import java.io.IOException;
-import java.util.Collection;
-
/**
* MySql specific DDL.
*/
@@ -22,7 +20,7 @@ public class MySqlDdl extends PlatformDdl {
public MySqlDdl(DatabasePlatform platform) {
super(platform);
- this.alterColumn = "modify";
+ this.alterColumn = "alter";
this.dropUniqueConstraint = "drop index";
this.historyDdl = new MySqlHistoryDdl();
this.inlineComments = true;
@@ -38,11 +36,11 @@ public class MySqlDdl extends PlatformDdl {
}
@Override
- public void alterTableDropColumn(final DdlBuffer buffer, final String tableName, final String columnName) throws IOException {
+ public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
if (this.useMigrationStoredProcedures) {
- buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')").endOfStatement();
+ alterTable(writer, tableName).raw("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')");
} else {
- super.alterTableDropColumn(buffer, tableName, columnName);
+ super.alterTableDropColumn(writer, tableName, columnName);
}
}
@@ -92,42 +90,35 @@ public class MySqlDdl extends PlatformDdl {
}
@Override
- public String alterColumnType(String tableName, String columnName, String type) {
- // can't alter itself - done in alterColumnBaseAttributes()
- return null;
- }
-
- @Override
- public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
- // can't alter itself - done in alterColumnBaseAttributes()
- return null;
- }
-
- @Override
- public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
- String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + convertDefaultValue(defaultValue);
- return "alter table " + tableName + " alter " + columnName + " " + suffix;
- }
-
- @Override
- public String alterColumnBaseAttributes(AlterColumn alter) {
- if (alter.getType() == null && alter.isNotnull() == null) {
- // No type change or notNull change
- // defaultValue change already handled in alterColumnDefaultValue
- return null;
- }
+ public void alterColumn(DdlWrite writer, AlterColumn alter) {
String tableName = alter.getTableName();
String columnName = alter.getColumnName();
- String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
- type = convert(type);
- boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
- String notnullClause = notnull ? " not null" : "";
- return "alter table " + tableName + " modify " + columnName + " " + type + notnullClause;
+ if (alter.getType() == null && alter.isNotnull() == null) {
+ // No type change or notNull change -> handle default value change
+ if (hasValue(alter.getDefaultValue())) {
+ alterColumnDefault(writer, alter);
+ }
+ } else {
+ // we must regenerate whole statement -> read altered and current value
+ String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
+ type = convert(type);
+ boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
+ String defaultValue = alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue();
+
+ DdlBuffer buffer = alterTable(writer, tableName).append("modify", columnName);
+ buffer.append(type);
+ if (notnull) {
+ buffer.append(" not null");
+ }
+ if (hasValue(defaultValue) && !DdlHelp.isDropDefault(defaultValue)) {
+ buffer.append(" default ").append(convertDefaultValue(defaultValue));
+ }
+ }
}
@Override
- protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) throws IOException {
+ protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) {
super.writeColumnDefinition(buffer, column, identity);
String comment = column.getComment();
if (!StringHelper.isNull(comment)) {
@@ -140,7 +131,7 @@ public class MySqlDdl extends PlatformDdl {
}
@Override
- public void inlineTableComment(DdlBuffer apply, String tableComment) throws IOException {
+ public void inlineTableComment(DdlBuffer apply, String tableComment) {
if (tableComment.length() > 1000) {
tableComment = tableComment.substring(0, 1000);
}
@@ -151,7 +142,7 @@ public class MySqlDdl extends PlatformDdl {
* Add table comment as a separate statement (from the create table statement).
*/
@Override
- public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
+ public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
if (DdlHelp.isDropComment(tableComment)) {
tableComment = "";
}
@@ -163,32 +154,4 @@ public class MySqlDdl extends PlatformDdl {
// alter comment currently not supported as it requires to repeat whole column definition
}
-
- /**
- * Locks all tables for triggers that have to be updated.
- */
- @Override
- public void lockTables(DdlBuffer buffer, Collection tables) throws IOException {
- if (!tables.isEmpty()) {
- buffer.append("lock tables ");
- int i = 0;
- for (String table : tables) {
- if (i > 0) {
- buffer.append(", ");
- }
- buffer.append(table).append(" write");
- i++;
- }
- buffer.endOfStatement();
- }
- }
-
- /**
- * Unlocks all tables for triggers that have to be updated.
- */
- @Override
- public void unlockTables(DdlBuffer buffer, Collection tables) throws IOException {
- buffer.append("unlock tables").endOfStatement();
- }
-
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlHistoryDdl.java
index 16d07136e..7a9e06730 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlHistoryDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlHistoryDdl.java
@@ -1,10 +1,8 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
-import io.ebeaninternal.dbmigration.model.MTable;
+import java.util.List;
-import java.io.IOException;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
/**
* MySql history support using DB triggers to maintain a history table.
@@ -15,54 +13,41 @@ public class MySqlHistoryDdl extends DbTriggerBasedHistoryDdl {
}
@Override
- protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
+ protected void dropTriggers(DdlBuffer buffer, String baseTable) {
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
}
- @Override
- protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
-
- DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
-
- addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
- addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
- }
@Override
- protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
+ protected void createTriggers(DdlBuffer buffer, String baseTable, List columnNames) {
- recreateHistoryView(update);
+ buffer.append("lock tables ").append(baseTable).append(" write").endOfStatement();
+ addBeforeUpdate(buffer, updateTriggerName(baseTable), baseTable, columnNames);
+ addBeforeDelete(buffer, deleteTriggerName(baseTable), baseTable, columnNames);
+ buffer.appendStatement("unlock tables");
- DdlBuffer buffer = update.historyTriggerBuffer();
- String baseTable = update.getBaseTable();
-
- dropTriggers(buffer, baseTable);
- addBeforeUpdate(updateTriggerName(baseTable), update);
- addBeforeDelete(deleteTriggerName(baseTable), update);
}
- private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
+ private void addBeforeUpdate(DdlBuffer apply, String triggerName, String tableName, List columnNames) {
- DdlBuffer apply = update.historyTriggerBuffer();
apply
.append("delimiter $$").newLine()
- .append("create trigger ").append(triggerName).append(" before update on ").append(update.getBaseTable())
+ .append("create trigger ").append(triggerName).append(" before update on ").append(tableName)
.append(" for each row begin").newLine();
- appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
+ appendInsertIntoHistory(apply, tableName, columnNames);
apply
.append(" set NEW.").append(sysPeriod).append("_start = now(6)").endOfStatement()
.append("end$$").newLine();
}
- private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
+ private void addBeforeDelete(DdlBuffer apply, String triggerName, String tableName, List columnNames) {
- DdlBuffer apply = update.historyTriggerBuffer();
apply
.append("delimiter $$").newLine()
- .append("create trigger ").append(triggerName).append(" before delete on ").append(update.getBaseTable())
+ .append("create trigger ").append(triggerName).append(" before delete on ").append(tableName)
.append(" for each row begin").newLine();
- appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
+ appendInsertIntoHistory(apply, tableName, columnNames);
apply.append("end$$").newLine();
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NoHistorySupportDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NoHistorySupportDdl.java
index fbaab9be8..b580f20cb 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NoHistorySupportDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NoHistorySupportDdl.java
@@ -6,8 +6,6 @@ import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
-
/**
* Default history implementation that does nothing. Needs to be replaced
* with an appropriate implementation for the given database platform.
@@ -20,7 +18,7 @@ public class NoHistorySupportDdl implements PlatformHistoryDdl {
}
@Override
- public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
+ public void createWithHistory(DdlWrite writer, MTable table) {
// does nothing
}
@@ -30,12 +28,8 @@ public class NoHistorySupportDdl implements PlatformHistoryDdl {
}
@Override
- public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
+ public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
// does nothing
}
- @Override
- public void updateTriggers(DdlWrite write, HistoryTableUpdate update) {
- // does nothing
- }
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NuoDbHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NuoDbHistoryDdl.java
index 89d81eb9b..b92b07640 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NuoDbHistoryDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/NuoDbHistoryDdl.java
@@ -1,10 +1,9 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
-import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
+import java.util.List;
+
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
/**
* NuoDB history support using DB triggers to maintain a history table.
@@ -17,59 +16,43 @@ public class NuoDbHistoryDdl extends DbTriggerBasedHistoryDdl {
}
@Override
- protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
+ protected void dropTriggers(DdlBuffer buffer, String baseTable) {
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
}
@Override
- protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
+ protected void createTriggers(DdlBuffer buffer, String baseTable, List columnNames) {
- DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
-
- addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
- addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
+ addBeforeUpdate(buffer, updateTriggerName(baseTable), baseTable, columnNames);
+ addBeforeDelete(buffer, deleteTriggerName(baseTable), baseTable, columnNames);
}
- @Override
- protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
+ private void addBeforeUpdate(DdlBuffer apply, String triggerName, String tableName, List columnNames) {
- recreateHistoryView(update);
+ addTriggerStart(triggerName, tableName, apply, " before update for each row as ");
- DdlBuffer buffer = update.historyTriggerBuffer();
- String baseTable = update.getBaseTable();
-
- dropTriggers(buffer, baseTable);
- addBeforeUpdate(updateTriggerName(baseTable), update);
- addBeforeDelete(deleteTriggerName(baseTable), update);
- }
-
- private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
-
- DdlBuffer apply = update.historyTriggerBuffer();
- addTriggerStart(triggerName, update, apply, " before update for each row as ");
apply.append(" NEW.sys_period_start = greatest(current_timestamp, date_add(OLD.sys_period_start, interval 1 microsecond))").endOfStatement();
- appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
+ appendInsertIntoHistory(apply, tableName, columnNames);
addEndTrigger(apply);
}
- private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
+ private void addBeforeDelete(DdlBuffer apply, String triggerName, String tableName, List columnNames) {
- DdlBuffer apply = update.historyTriggerBuffer();
- addTriggerStart(triggerName, update, apply, " before delete for each row as");
- appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
+ addTriggerStart(triggerName, tableName, apply, " before delete for each row as");
+ appendInsertIntoHistory(apply, tableName, columnNames);
addEndTrigger(apply);
}
- private void addTriggerStart(String triggerName, DbTriggerUpdate update, DdlBuffer apply, String s) throws IOException {
+ private void addTriggerStart(String triggerName, String baseTable, DdlBuffer apply, String s) {
apply
.append("delimiter $$").newLine()
- .append("create or replace trigger ").append(triggerName).append(" for ").append(update.getBaseTable())
+ .append("create or replace trigger ").append(triggerName).append(" for ").append(baseTable)
.append(s).newLine();
}
- private void addEndTrigger(DdlBuffer apply) throws IOException {
+ private void addEndTrigger(DdlBuffer apply) {
apply.append("end_trigger")
.endOfStatement()
.append("$$").newLine()
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/OracleDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/OracleDdl.java
index 740870b09..f94b559d2 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/OracleDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/OracleDdl.java
@@ -20,6 +20,8 @@ public class OracleDdl extends PlatformDdl {
this.columnSetNotnull = "not null";
this.columnSetNull = "null";
this.columnSetDefault = "default";
+ this.columnDropDefault = "default null"; // dropping default is not supported. See:
+ // https://stackoverflow.com/questions/8481532/how-do-i-remove-the-default-value-from-a-column-in-oracle
this.identitySuffix = " generated by default as identity";
}
@@ -33,6 +35,21 @@ public class OracleDdl extends PlatformDdl {
}
}
+ @Override
+ public String dropSequence(String sequenceName) {
+ return ignoreError(-2289, super.dropSequence(sequenceName));
+ }
+
+ @Override
+ public String alterTableDropConstraint(String tableName, String constraintName) {
+ return ignoreError(-2443, super.alterTableDropConstraint(tableName, constraintName));
+ }
+
+ @Override
+ public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
+ return ignoreError(-2443, super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName));
+ }
+
@Override
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
// do nothing, no on update clause for oracle
@@ -57,4 +74,21 @@ public class OracleDdl extends PlatformDdl {
return asIdentityStandardOptions(columnDefn, identity);
}
+ /**
+ * generates anonymous pl/sql block that catches expected error so that we can
+ * effectively do a 'drop if exists'
+ */
+ private String ignoreError(int errorNr, String statement) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("delimiter $$\n")
+ .append("declare\n")
+ .append(" expected_error exception;\n")
+ .append(" pragma exception_init(expected_error, ").append(errorNr).append(");\n")
+ .append("begin\n")
+ .append(" execute immediate '").append(statement).append("';\n")
+ .append("exception\n")
+ .append(" when expected_error then null;\n")
+ .append("end;\n$$");
+ return sb.toString();
+ }
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java
index 34d7f7ebc..8156e67ae 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java
@@ -9,11 +9,7 @@ import io.ebean.config.dbplatform.DbDefaultValue;
import io.ebean.config.dbplatform.DbIdentity;
import io.ebean.config.dbplatform.IdType;
import io.ebean.util.StringHelper;
-import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
+import io.ebeaninternal.dbmigration.ddlgeneration.*;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.PlatformTypeConverter;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.VowelRemover;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
@@ -22,8 +18,6 @@ import io.ebeaninternal.dbmigration.migration.Column;
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
-import java.util.Collection;
import java.util.List;
import java.util.Locale;
@@ -82,16 +76,12 @@ public class PlatformDdl {
protected String alterColumn = "alter column";
- protected String alterColumnSuffix = "";
-
protected String dropUniqueConstraint = "drop constraint";
protected String addConstraint = "add constraint";
protected String addColumn = "add column";
- protected String addColumnSuffix = "";
-
protected String columnSetType = "";
protected String columnSetDefault = "set default";
@@ -102,14 +92,14 @@ public class PlatformDdl {
protected String columnSetNull = "set null";
+ protected String columnNotNull = "not null";
+
protected String updateNullWithDefault = "update ${table} set ${column} = ${default} where ${column} is null";
protected String createTable = "create table";
protected String dropColumn = "drop column";
- protected String dropColumnSuffix = "";
-
protected String addForeignKeySkipCheck = "";
protected String uniqueIndex = "unique";
@@ -236,7 +226,7 @@ public class PlatformDdl {
/**
* Write all the table columns converting to platform types as necessary.
*/
- public void writeTableColumns(DdlBuffer apply, List columns, DdlIdentity identity) throws IOException {
+ public void writeTableColumns(DdlBuffer apply, List columns, DdlIdentity identity) {
for (int i = 0; i < columns.size(); i++) {
if (i > 0) {
apply.append(",");
@@ -260,7 +250,7 @@ public class PlatformDdl {
/**
* Write the column definition to the create table statement.
*/
- protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) throws IOException {
+ protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) {
String columnDefn = convert(column.getType());
if (identity.useIdentity() && isTrue(column.isPrimaryKey())) {
@@ -277,20 +267,13 @@ public class PlatformDdl {
}
}
if (isTrue(column.isNotnull()) || isTrue(column.isPrimaryKey())) {
- writeColumnNotNull(buffer);
+ buffer.appendWithSpace(columnNotNull);
}
// add check constraints later as we really want to give them a nice name
// so that the database can potentially provide a nice SQL error
}
- /**
- * Allow for platform overriding (e.g. ClickHouse).
- */
- protected void writeColumnNotNull(DdlBuffer buffer) throws IOException {
- buffer.append(" not null");
- }
-
/**
* Returns the check constraint.
*/
@@ -319,9 +302,7 @@ public class PlatformDdl {
if (type == null) {
return null;
}
-
type = extract(type);
-
if (type.contains("[]")) {
return convertArrayType(type);
}
@@ -333,16 +314,18 @@ public class PlatformDdl {
// e.g. @Column(columnDefinition = "db2;blob(64M);sqlserver,h2;varchar(227);varchar(127)")
private String extract(String type) {
String[] tmp = type.split(";");
- assert tmp.length % 2 == 1;
- for (int i = 0; i < tmp.length - 2; i+=2) {
+ if (tmp.length % 2 == 0) {
+ throw new IllegalArgumentException("You need an odd number of arguments. See Issue #2559 for details");
+ }
+ for (int i = 0; i < tmp.length - 2; i += 2) {
String[] platforms = tmp[i].split(",");
for (String plat : platforms) {
if (platform.isPlatform(Platform.valueOf(plat.toUpperCase(Locale.ENGLISH)))) {
- return tmp[i+1];
+ return tmp[i + 1];
}
}
}
- return tmp[tmp.length-1]; // else
+ return tmp[tmp.length - 1]; // else
}
/**
@@ -359,29 +342,29 @@ public class PlatformDdl {
/**
* Add history support to this table using the platform specific mechanism.
*/
- public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
+ public void createWithHistory(DdlWrite writer, MTable table) {
historyDdl.createWithHistory(writer, table);
}
/**
* Drop history support for a given table.
*/
- public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
+ public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
historyDdl.dropHistoryTable(writer, dropHistoryTable);
}
/**
* Add history support to an existing table.
*/
- public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
+ public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
historyDdl.addHistoryTable(writer, addHistoryTable);
}
/**
* Regenerate the history triggers (or function) due to a column being added/dropped/excluded or included.
*/
- public void regenerateHistoryTriggers(DdlWrite write, HistoryTableUpdate update) throws IOException {
- historyDdl.updateTriggers(write, update);
+ public void regenerateHistoryTriggers(DdlWrite writer, String tableName) {
+ historyDdl.updateTriggers(writer, tableName);
}
/**
@@ -550,13 +533,11 @@ public class PlatformDdl {
return buffer.toString();
}
- public void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, String defaultValue) throws IOException {
+ public void alterTableAddColumn(DdlWrite writer, String tableName, Column column, boolean onHistoryTable, String defaultValue) {
String convertedType = convert(column.getType());
-
- buffer.append("alter table ").append(tableName)
- .append(" ").append(addColumn).append(" ").append(column.getName())
- .append(" ").append(convertedType);
+ DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, column.getName());
+ buffer.append(convertedType);
// Add default value also to history table if it is not excluded
if (defaultValue != null) {
@@ -568,28 +549,35 @@ public class PlatformDdl {
if (!onHistoryTable) {
if (isTrue(column.isNotnull())) {
- writeColumnNotNull(buffer);
+ buffer.appendWithSpace(columnNotNull);
}
- buffer.append(addColumnSuffix);
- buffer.endOfStatement();
// check constraints cannot be added in one statement for h2
if (!StringHelper.isNull(column.getCheckConstraint())) {
String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint());
- if (hasValue(ddl)) {
- buffer.append(ddl).endOfStatement();
- }
+ writer.applyPostAlter().appendStatement(ddl);
}
- } else {
- buffer.append(addColumnSuffix);
- buffer.endOfStatement();
}
}
- public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
- buffer.append("alter table ").append(tableName).append(" ").append(dropColumn).append(" ").append(columnName)
- .append(dropColumnSuffix).endOfStatement();
+ /**
+ * This method is used from DbTriggerBasedHistoryDdl to add the sysPeriodColumns.
+ */
+ public void alterTableAddColumn(DdlWrite writer, String tableName, String columnName, String columnType, String defaultValue) {
+
+ String convertedType = convert(columnType);
+ DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, columnName);
+ buffer.append(convertedType);
+
+ if (defaultValue != null) {
+ buffer.append(" default ");
+ buffer.append(defaultValue);
+ }
+ }
+
+ public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
+ alterTable(writer, tableName).append(dropColumn, columnName);
}
/**
@@ -604,22 +592,27 @@ public class PlatformDdl {
/**
* Alter a column type.
*
- * Note that that MySql and SQL Server instead use alterColumnBaseAttributes()
+ * Note that that MySql, SQL Server, and HANA instead use alterColumn()
*
*/
- public String alterColumnType(String tableName, String columnName, String type) {
- return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + columnSetType + convert(type) + alterColumnSuffix;
+ protected void alterColumnType(DdlWrite writer, AlterColumn alter) {
+ alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName())
+ .append(columnSetType).append(convert(alter.getType()));
}
/**
* Alter a column adding or removing the not null constraint.
*
- * Note that that MySql, SQL Server, and HANA instead use alterColumnBaseAttributes()
+ * Note that that MySql, SQL Server, and HANA instead use alterColumn()
*
*/
- public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
- String suffix = notnull ? columnSetNotnull : columnSetNull;
- return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix + alterColumnSuffix;
+ protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) {
+ DdlBuffer buffer = alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName());
+ if (Boolean.TRUE.equals(alter.isNotnull())) {
+ buffer.append(columnSetNotnull);
+ } else {
+ buffer.append(columnSetNull);
+ }
}
/**
@@ -631,22 +624,46 @@ public class PlatformDdl {
/**
* Alter column setting the default value.
+ *
+ * Note that that MySql, SQL Server, and HANA instead use alterColumn()
+ *
*/
- public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
- String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + convertDefaultValue(defaultValue);
- return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix + alterColumnSuffix;
+ protected void alterColumnDefault(DdlWrite writer, AlterColumn alter) {
+ DdlBuffer buffer = alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName());
+ if (DdlHelp.isDropDefault(alter.getDefaultValue())) {
+ buffer.append(columnDropDefault);
+ } else {
+ buffer.append(columnSetDefault).appendWithSpace(convertDefaultValue(alter.getDefaultValue()));
+ }
}
/**
- * Alter column setting both the type and not null constraint.
+ * Alter column setting (type, default value and not null constraint).
*
- * Used by MySql, SQL Server, and HANA as these require both column attributes to be set together.
+ * Used by MySql, SQL Server, and HANA as these require all column attributes to
+ * be set together.
*
*/
- public String alterColumnBaseAttributes(AlterColumn alter) {
- // by default do nothing, only used by mysql, sql server, and HANA as they can only
- // modify the column with the full column definition
- return null;
+ public void alterColumn(DdlWrite writer, AlterColumn alter) {
+
+ if (hasValue(alter.getType())) {
+ alterColumnType(writer, alter);
+ }
+
+ if (hasValue(alter.getDefaultValue())) {
+ alterColumnDefault(writer, alter);
+ }
+
+ if (alter.isNotnull() != null) {
+ alterColumnNotnull(writer, alter);
+ }
+ }
+
+ /**
+ * Creates or replace a new DdlAlterTable for given tableName.
+ */
+ protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
+ return writer.applyAlterTable(tableName, BaseAlterTableWrite::new);
}
protected void appendColumns(String[] columns, StringBuilder buffer) {
@@ -705,21 +722,21 @@ public class PlatformDdl {
/**
* Add an inline table comment to the create table statement.
*/
- public void inlineTableComment(DdlBuffer apply, String tableComment) throws IOException {
+ public void inlineTableComment(DdlBuffer apply, String tableComment) {
// do nothing by default (MySql only)
}
/**
* Add an table storage engine to the create table statement.
*/
- public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException {
+ public void tableStorageEngine(DdlBuffer apply, String storageEngine) {
// do nothing by default
}
/**
* Add table comment as a separate statement (from the create table statement).
*/
- public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
+ public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
if (DdlHelp.isDropComment(tableComment)) {
tableComment = "";
}
@@ -729,7 +746,7 @@ public class PlatformDdl {
/**
* Add column comment as a separate statement.
*/
- public void addColumnComment(DdlBuffer apply, String table, String column, String comment) throws IOException {
+ public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
if (DdlHelp.isDropComment(comment)) {
comment = "";
}
@@ -739,14 +756,14 @@ public class PlatformDdl {
/**
* Use this to generate a prolog for each script (stored procedures)
*/
- public void generateProlog(DdlWrite write) throws IOException {
+ public void generateProlog(DdlWrite writer) {
}
/**
* Use this to generate an epilog. Will be added at the end of script
*/
- public void generateEpilog(DdlWrite write) throws IOException {
+ public void generateEpilog(DdlWrite writer) {
}
@@ -769,20 +786,6 @@ public class PlatformDdl {
return name;
}
- /**
- * Mysql-specific: Locks all tables for triggers that have to be updated.
- */
- public void lockTables(DdlBuffer buffer, Collection tables) throws IOException {
-
- }
-
- /**
- * Mysql-specific: Unlocks all tables for triggers that have to be updated.
- */
- public void unlockTables(DdlBuffer buffer, Collection tables) throws IOException {
-
- }
-
/**
* Returns the database-specific "create table" command prefix. For HANA this is
* either "create column table" or "create row table", for all other databases
@@ -798,7 +801,7 @@ public class PlatformDdl {
return false;
}
- public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
+ public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) {
// only supported by postgres initially
}
@@ -806,7 +809,7 @@ public class PlatformDdl {
* Adds tablespace declaration. Now only supported for db2.
* @throws IOException
*/
- public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace) throws IOException{
+ public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace) {
// now only supported for db2
}
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 c5e93aa23..4dd1dec6d 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
@@ -6,8 +6,6 @@ import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
-
/**
* Defines the implementation for adding history support to a table.
*/
@@ -21,20 +19,32 @@ public interface PlatformHistoryDdl {
/**
* Creates a new table and add history support to the table using platform specific mechanism.
*/
- void createWithHistory(DdlWrite writer, MTable table) throws IOException;
+ void createWithHistory(DdlWrite writer, MTable table);
/**
* Drop history support for the given table.
*/
- void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
+ void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable);
/**
* Add history support to the given table.
*/
- void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
+ 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.
+ *
+ * Note: This function may be called multiple times for the same table.
*/
- void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) throws IOException;
+ default void updateTriggers(DdlWrite writer, String tableName) {
+ // nop
+ }
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java
index 734621a66..1618cfd9e 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java
@@ -2,8 +2,8 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
-
-import java.io.IOException;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
+import io.ebeaninternal.dbmigration.migration.AlterColumn;
/**
* Postgres specific DDL.
@@ -40,7 +40,7 @@ public class PostgresDdl extends PlatformDdl {
}
@Override
- public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
+ public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) {
apply.append(" partition by range (").append(partitionColumn).append(")");
}
@@ -58,7 +58,10 @@ public class PostgresDdl extends PlatformDdl {
}
@Override
- public String alterColumnType(String tableName, String columnName, String type) {
- return super.alterColumnType(tableName, columnName, type) + " using " + columnName + "::" + convert(type);
+ protected void alterColumnType(DdlWrite writer, AlterColumn alter) {
+ String type = convert(alter.getType());
+ alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName())
+ .append(columnSetType).append(type)
+ .append(" using ").append(alter.getColumnName()).append("::").append(type);
}
}
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 b0257f96a..135324899 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
@@ -4,7 +4,6 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
import java.util.List;
/**
@@ -21,7 +20,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
* Use Postgres create table like to create the history table.
*/
@Override
- protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
+ protected void createHistoryTable(DdlBuffer apply, MTable table) {
apply.append("create table ").append(table.getName()).append(historySuffix)
.append("(like ").append(table.getName()).append(")").endOfStatement();
}
@@ -30,50 +29,45 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
* Use Postgres range type rather than start and end timestamps.
*/
@Override
- protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
- apply
- .append("alter table ").append(baseTableName)
- .append(" add column ").append(sysPeriod).append(" tstzrange not null default tstzrange(").append(now).append(", null)")
- .endOfStatement();
-
+ protected void addSysPeriodColumns(DdlWrite writer, String baseTableName, String whenCreatedColumn) {
+ platformDdl.alterTableAddColumn(writer, baseTableName, sysPeriod, "tstzrange not null", "tstzrange(" + now + ", null)");
if (whenCreatedColumn != null) {
- apply.append("update ").append(baseTableName).append(" set ")
+ writer.applyPostAlter()
+ .append("update ").append(baseTableName).append(" set ")
.append(sysPeriod).append(" = tstzrange(").append(whenCreatedColumn).append(", null)").endOfStatement();
}
}
@Override
- protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
+ protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) {
appendColumnName(apply, prefix, sysPeriod);
}
@Override
- protected void dropSysPeriodColumns(DdlBuffer buffer, String baseTableName) throws IOException {
- buffer.append("alter table ").append(baseTableName).append(" drop column ").append(sysPeriod).endOfStatement();
+ protected void dropSysPeriodColumns(DdlWrite writer, String baseTableName) {
+ platformDdl.alterTableDropColumn(writer, baseTableName, sysPeriod);
}
@Override
- protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
- String baseTableName = table.getName();
+ protected void createTriggers(DdlBuffer buffer, String baseTableName, List columnNames) {
String procedureName = procedureName(baseTableName);
String triggerName = triggerName(baseTableName);
-
- DdlBuffer apply = writer.applyHistoryTrigger();
- apply
+ createOrReplaceFunction(buffer, procedureName, historyTableName(baseTableName), columnNames);
+ buffer
.append("create trigger ").append(triggerName).newLine()
.append(" before update or delete on ").append(baseTableName).newLine()
.append(" for each row execute procedure ").append(procedureName).append("();").newLine().newLine();
}
@Override
- protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
+ protected void dropTriggers(DdlBuffer buffer, String baseTable) {
// rollback trigger then function
buffer.append("drop trigger if exists ").append(triggerName(baseTable)).append(" on ").append(baseTable).append(" cascade").endOfStatement();
buffer.append("drop function if exists ").append(procedureName(baseTable)).append("()").endOfStatement();
buffer.end();
}
- protected void createOrReplaceFunction(DdlBuffer apply, String procedureName, String historyTable, List includedColumns) throws IOException {
+ protected void createOrReplaceFunction(DdlBuffer apply, String procedureName, String historyTable, List includedColumns) {
apply
.append("create or replace function ").append(procedureName).append("() returns trigger as $$").newLine();
@@ -105,23 +99,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
}
@Override
- protected void createStoredFunction(DdlWrite writer, MTable table) throws IOException {
- String procedureName = procedureName(table.getName());
- String historyTable = historyTableName(table.getName());
-
- List columnNames = columnNamesForApply(table);
- createOrReplaceFunction(writer.applyHistoryTrigger(), procedureName, historyTable, columnNames);
- }
-
- @Override
- protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
- String procedureName = procedureName(update.getBaseTable());
- recreateHistoryView(update);
- createOrReplaceFunction(update.historyTriggerBuffer(), procedureName, update.getHistoryTable(), update.getColumns());
- }
-
- @Override
- protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List columns) throws IOException {
+ protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List columns) {
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriod).append(",");
appendColumnNames(buffer, columns, "");
buffer.append(") values (tstzrange(lowerTs,upperTs), ");
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SQLiteDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SQLiteDdl.java
index 392051dac..50ce99d25 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SQLiteDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SQLiteDdl.java
@@ -1,11 +1,19 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
+import java.util.ArrayList;
+import java.util.List;
+
import io.ebean.config.dbplatform.DatabasePlatform;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
/**
- * DB2 platform specific DDL.
+ * SQLite platform specific DDL.
+ *
+ * Note: SQLite has very limited alter capabilities. Altering a column is not
+ * supported and may need a recreation of the whole table
*/
public class SQLiteDdl extends PlatformDdl {
@@ -27,7 +35,57 @@ public class SQLiteDdl extends PlatformDdl {
@Override
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
- // not supported
- return null;
+ return "-- not supported: " + super.alterTableAddForeignKey(options, request);
+ }
+
+ @Override
+ public String alterTableDropForeignKey(String tableName, String fkName) {
+ return "-- not supported: " + super.alterTableDropForeignKey(tableName, fkName);
+ }
+
+ @Override
+ public String alterTableAddCheckConstraint(String tableName, String checkConstraintName, String checkConstraint) {
+ return "-- not supported: " + super.alterTableAddCheckConstraint(tableName, checkConstraintName, checkConstraint);
+ }
+
+ @Override
+ public String alterTableDropConstraint(String tableName, String constraintName) {
+ return "-- not supported: " + super.alterTableDropConstraint(tableName, constraintName);
+ }
+
+ @Override
+ public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
+ return "-- not supported: " + super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
+ }
+
+ @Override
+ public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
+ return "-- not supported: " + super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName);
+ }
+
+ @Override
+ protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
+ return writer.applyAlterTable(tableName, SQLiteAlterTableWrite::new);
+ }
+
+ static class SQLiteAlterTableWrite extends BaseAlterTableWrite {
+ public SQLiteAlterTableWrite(String tableName) {
+ super(tableName);
+ }
+
+ @Override
+ protected List postProcessCommands(List cmds) {
+ List ret = new ArrayList();
+ for (AlterCmd cmd : cmds) {
+ switch (cmd.getOperation()) {
+ case "alter column":
+ ret.add(newRawCommand("-- not supported: " + cmd));
+ break;
+ default:
+ ret.add(cmd);
+ }
+ }
+ return ret;
+ }
}
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerDdl.java
index 00edd1b75..d2dd88afa 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/SqlServerDdl.java
@@ -6,13 +6,17 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
-import java.io.IOException;
-
/**
* MS SQL Server platform specific DDL.
*/
public class SqlServerDdl extends PlatformDdl {
+ private static final String CONSTRAINT = "C";
+ private static final String UNIQUE_CONSTRAINT = "UQ";
+ private static final String USER_TABLE = "U";
+ private static final String FOREIGN_KEY = "F";
+ private static final String SEQUENCE_OBJECT = "SO";
+
public SqlServerDdl(DatabasePlatform platform) {
super(platform);
this.identitySuffix = " identity(1,1)";
@@ -33,12 +37,7 @@ public class SqlServerDdl extends PlatformDdl {
@Override
public String dropTable(String tableName) {
- StringBuilder buffer = new StringBuilder();
- buffer.append("IF OBJECT_ID('");
- buffer.append(tableName);
- buffer.append("', 'U') IS NOT NULL drop table ");
- buffer.append(tableName);
- return buffer.toString();
+ return ifObjectExists(tableName, USER_TABLE) + "drop table " + tableName;
}
@Override
@@ -48,12 +47,12 @@ public class SqlServerDdl extends PlatformDdl {
if (pos != -1) {
objectId = tableName.substring(0, pos + 1) + fkName;
}
- return "IF OBJECT_ID('" + objectId + "', 'F') IS NOT NULL " + super.alterTableDropForeignKey(tableName, fkName);
+ return ifObjectExists(objectId, FOREIGN_KEY) + super.alterTableDropForeignKey(tableName, fkName);
}
@Override
public String dropSequence(String sequenceName) {
- return "IF OBJECT_ID('" + sequenceName + "', 'SO') IS NOT NULL drop sequence " + sequenceName;
+ return ifObjectExists(sequenceName, SEQUENCE_OBJECT) + "drop sequence " + sequenceName;
}
@Override
@@ -73,12 +72,12 @@ public class SqlServerDdl extends PlatformDdl {
throw new NullPointerException();
}
// issues#233
- StringBuilder sb = new StringBuilder("create unique nonclustered index ");
- sb.append(uqName).append(" on ").append(tableName).append('(');
+ StringBuilder sb = new StringBuilder(256);
+ sb.append("create unique nonclustered index ").append(uqName).append(" on ").append(tableName).append('(');
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
- sb.append(",");
+ sb.append(',');
}
sb.append(columns[i]);
}
@@ -93,11 +92,9 @@ public class SqlServerDdl extends PlatformDdl {
@Override
public String alterTableDropConstraint(String tableName, String constraintName) {
- StringBuilder sb = new StringBuilder();
- sb.append("IF (OBJECT_ID('").append(constraintName).append("', 'C') IS NOT NULL) ");
- sb.append(super.alterTableDropConstraint(tableName, constraintName));
- return sb.toString();
+ return ifObjectExists(maxConstraintName(constraintName), CONSTRAINT) + super.alterTableDropConstraint(tableName, constraintName);
}
+
/**
* Drop a unique constraint from the table (Sometimes this is an index).
*/
@@ -105,10 +102,12 @@ public class SqlServerDdl extends PlatformDdl {
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
StringBuilder sb = new StringBuilder();
sb.append(dropIndex(uniqueConstraintName, tableName)).append(";\n");
- sb.append("IF (OBJECT_ID('").append(maxConstraintName(uniqueConstraintName)).append("', 'UQ') IS NOT NULL) ");
- sb.append(super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName));
+
+ sb.append(ifObjectExists(maxConstraintName(uniqueConstraintName), UNIQUE_CONSTRAINT))
+ .append(super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName));
return sb.toString();
}
+
/**
* Generate and return the create sequence DDL.
*/
@@ -135,57 +134,60 @@ public class SqlServerDdl extends PlatformDdl {
}
@Override
- public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
+ protected void alterColumnDefault(DdlWrite writer, AlterColumn alter) {
// Unfortunately, the SqlServer creates default values with a random name.
// You can specify a name in DDL, but this does not work in conjunction with
// temporal tables in certain cases. So we have to delete the constraint with
// a rather complex statement.
- StringBuilder sb = new StringBuilder();
- if (DdlHelp.isDropDefault(defaultValue)) {
- sb.append("EXEC usp_ebean_drop_default_constraint ").append(tableName).append(", ").append(columnName);
- } else {
- sb.append("alter table ").append(tableName);
- sb.append(" add default ").append(convertDefaultValue(defaultValue)).append(" for ").append(columnName);
- }
- return sb.toString();
- }
-
- @Override
- public String alterColumnBaseAttributes(AlterColumn alter) {
- if (alter.getType() == null && alter.isNotnull() == null) {
- // No type change or notNull change
- // defaultValue change already handled in alterColumnDefaultValue
- return null;
- }
String tableName = alter.getTableName();
String columnName = alter.getColumnName();
- String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
- type = convert(type);
- boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
- String notnullClause = notnull ? " not null" : "";
-
- return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + type + notnullClause;
+ String defaultValue = alter.getDefaultValue();
+ if (DdlHelp.isDropDefault(defaultValue)) {
+ execUspDropDefaultConstraint(writer, tableName, columnName);
+ } else {
+ execUspDropDefaultConstraint(writer, tableName, columnName);
+ setDefaultValue(writer, tableName, columnName, defaultValue);
+ }
}
@Override
- public String alterColumnType(String tableName, String columnName, String type) {
+ public void alterColumn(DdlWrite writer, AlterColumn alter) {
+ String tableName = alter.getTableName();
+ String columnName = alter.getColumnName();
+ if (alter.getType() == null && alter.isNotnull() == null) {
+ // No type change or notNull change
+ if (hasValue(alter.getDefaultValue())) {
+ alterColumnDefault(writer, alter);
+ }
+ } else {
+ // we must regenerate whole statement -> read altered and current value
+ String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
+ type = convert(type);
+ boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
+ String defaultValue = alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue();
+ if (hasValue(defaultValue)) {
+ // default value present -> drop default constraint before altering
+ execUspDropDefaultConstraint(writer, tableName, columnName);
+ }
- // can't alter itself - done in alterColumnBaseAttributes()
- return null;
- }
+ DdlBuffer buffer = alterTable(writer, tableName).append(alterColumn, columnName);
+ buffer.append(type);
+ if (notnull) {
+ buffer.append(" not null");
+ }
- @Override
- public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
-
- // can't alter itself - done in alterColumnBaseAttributes()
- return null;
+ // re add - default constraint
+ if (hasValue(defaultValue) && !DdlHelp.isDropDefault(defaultValue)) {
+ setDefaultValue(writer, tableName, columnName, defaultValue);
+ }
+ }
}
/**
* Add table comment as a separate statement (from the create table statement).
*/
@Override
- public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
+ public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
// do nothing for MS SQL Server (cause it requires stored procedures etc)
}
@@ -194,7 +196,7 @@ public class SqlServerDdl extends PlatformDdl {
* Add column comment as a separate statement.
*/
@Override
- public void addColumnComment(DdlBuffer apply, String table, String column, String comment) throws IOException {
+ public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
// do nothing for MS SQL Server (cause it requires stored procedures etc)
}
@@ -204,47 +206,58 @@ public class SqlServerDdl extends PlatformDdl {
* (constraints, default values, indices and foreign keys). That's why we call a user stored procedure here
*/
@Override
- public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
-
- buffer.append("EXEC usp_ebean_drop_column ").append(tableName).append(", ").append(columnName).endOfStatement();
+ public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
+ alterTable(writer, tableName).raw("EXEC usp_ebean_drop_column ").append(tableName).append(", ").append(columnName);
}
/**
* This writes the multi value datatypes needed for MultiValueBind.
*/
@Override
- public void generateProlog(DdlWrite write) throws IOException {
- super.generateProlog(write);
+ public void generateProlog(DdlWrite writer) {
+ super.generateProlog(writer);
- generateTVPDefinitions(write, "bigint");
- generateTVPDefinitions(write, "float");
- generateTVPDefinitions(write, "bit");
- generateTVPDefinitions(write, "date");
- generateTVPDefinitions(write, "time");
+ generateTVPDefinitions(writer, "bigint");
+ generateTVPDefinitions(writer, "float");
+ generateTVPDefinitions(writer, "bit");
+ generateTVPDefinitions(writer, "date");
+ generateTVPDefinitions(writer, "time");
//generateTVPDefinitions(write, "datetime2");
- generateTVPDefinitions(write, "uniqueidentifier");
- generateTVPDefinitions(write, "nvarchar(max)");
+ generateTVPDefinitions(writer, "uniqueidentifier");
+ generateTVPDefinitions(writer, "nvarchar(max)");
}
- private void generateTVPDefinitions(DdlWrite write, String definition) throws IOException {
+ private void generateTVPDefinitions(DdlWrite writer, String definition) {
int pos = definition.indexOf('(');
String name = pos == -1 ? definition : definition.substring(0, pos);
- dropTVP(write.dropAll(), name);
+ dropTVP(writer.dropAll(), name);
//TVPs are included in "I__create_procs.sql"
//createTVP(write.apply(), name, definition);
}
- private void dropTVP(DdlBuffer ddl, String name) throws IOException {
+ private void dropTVP(DdlBuffer ddl, String name) {
ddl.append("if exists (select name from sys.types where name = 'ebean_").append(name)
.append("_tvp') drop type ebean_").append(name).append("_tvp").endOfStatement();
}
- private void createTVP(DdlBuffer ddl, String name, String definition) throws IOException {
+ @SuppressWarnings("unused")
+ private void createTVP(DdlBuffer ddl, String name, String definition) {
ddl.append("if not exists (select name from sys.types where name = 'ebean_").append(name)
.append("_tvp') create type ebean_").append(name).append("_tvp as table (c1 ").append(definition).append(")")
.endOfStatement();
}
+ public static String ifObjectExists(String object, String objectType) {
+ return "IF OBJECT_ID('" + object + "', '" + objectType + "') IS NOT NULL ";
+ }
+
+ private void execUspDropDefaultConstraint(DdlWrite writer, String tableName, String columnName) {
+ alterTable(writer, tableName).raw("EXEC usp_ebean_drop_default_constraint " + tableName + ", " + columnName);
+ }
+
+ private void setDefaultValue(DdlWrite writer, String tableName, String columnName, String defaultValue) {
+ alterTable(writer, tableName).append("add default " + convertDefaultValue(defaultValue) + " for", columnName);
+ }
}
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 4b87ff04e..c0b1eaebc 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,14 +1,14 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.DatabaseConfig;
+import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
+import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
-
/**
* @author Vilmos Nagy
*/
@@ -26,7 +26,7 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
}
@Override
- public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
+ public void createWithHistory(DdlWrite writer, MTable table) {
String baseTable = table.getName();
enableSystemVersioning(writer, baseTable);
}
@@ -43,8 +43,8 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
return historyTable;
}
- private void enableSystemVersioning(DdlWrite writer, String baseTable) throws IOException {
- DdlBuffer apply = writer.applyHistoryView();
+ private void enableSystemVersioning(DdlWrite writer, String baseTable) {
+ DdlBuffer apply = writer.applyPostAlter();
apply.append("alter table ").append(baseTable).newLine()
.append(" add ").append(systemPeriodStart).append(" datetime2 GENERATED ALWAYS AS ROW START NOT NULL DEFAULT SYSUTCDATETIME(),").newLine()
.append(" ").append(systemPeriodEnd).append(" datetime2 GENERATED ALWAYS AS ROW END NOT NULL DEFAULT '9999-12-31T23:59:59.9999999',").newLine()
@@ -59,40 +59,49 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
}
@Override
- public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
+ public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
String baseTable = dropHistoryTable.getBaseTable();
- DdlBuffer apply = writer.applyHistoryView();
- apply.append("-- dropping history support for ").append(baseTable).endOfStatement();
// drop default constraints
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName(baseTable);
+ alter.setDefaultValue(DdlHelp.DROP_DEFAULT);
+ alter.setColumnName(systemPeriodStart);
+ platformDdl.alterColumn(writer, alter);
+ alter.setColumnName(systemPeriodEnd);
+ platformDdl.alterColumn(writer, alter);
- apply.append(platformDdl.alterColumnDefaultValue(baseTable, systemPeriodStart, DdlHelp.DROP_DEFAULT)).endOfStatement();
- apply.append(platformDdl.alterColumnDefaultValue(baseTable, systemPeriodEnd, DdlHelp.DROP_DEFAULT)).endOfStatement();
- // switch of versioning & period
+ // switch of versioning & period - must be done before altering
+ DdlBuffer apply = writer.apply();
+ apply.append("-- dropping history support for ").append(baseTable).endOfStatement();
apply.append("alter table ").append(baseTable).append(" set (system_versioning = off)").endOfStatement();
apply.append("alter table ").append(baseTable).append(" drop period for system_time").endOfStatement();
- // now drop tables & columns
- apply.append("alter table ").append(baseTable).append(" drop column ").append(systemPeriodStart).endOfStatement();
- apply.append("alter table ").append(baseTable).append(" drop column ").append(systemPeriodEnd).endOfStatement();
- apply.append("IF OBJECT_ID('").append(baseTable).append("_history', 'U') IS NOT NULL drop table ").append(baseTable).append("_history").endOfStatement();
apply.end();
+ // 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"));
}
@Override
- public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
+ public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
String baseTable = addHistoryTable.getBaseTable();
enableSystemVersioning(writer, baseTable);
}
@Override
- public void updateTriggers(DdlWrite writer, HistoryTableUpdate baseTable) throws IOException {
- // SQL Server 2016 does not need triggers
- DdlBuffer apply = writer.applyHistoryView();
- String baseTableName = baseTable.getBaseTable();
- apply.append("-- alter table ").append(baseTableName).append(" set (system_versioning = off (history_table=")
- .append(getHistoryTable(baseTableName)).append("))").endOfStatement();
- apply.append("-- history migration goes here").newLine();
- apply.append("-- alter table ").append(baseTableName).append(" set (system_versioning = on (history_table=")
- .append(getHistoryTable(baseTableName)).append("))").endOfStatement();
-
+ public void updateTriggers(DdlWrite writer, String tableName) {
+ DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
+ writer.getTable(tableName);
+ if (!alter.isHistoryHandled()) {
+ // 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();
+ 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();
+ }
+ alter.setHistoryHandled();
}
+
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java
index 3ba023881..204dcd762 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java
@@ -3,12 +3,10 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.model.MTable;
-import java.io.IOException;
-
public class YugabyteHistoryDdl extends PostgresHistoryDdl {
@Override
- protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
+ protected void createHistoryTable(DdlBuffer apply, MTable table) {
createHistoryTableAs(apply, table);
writeColumnDefinition(apply, sysPeriod, "tstzrange");
apply.newLine().append(")").endOfStatement();
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java
index e5c8743d2..faac168ea 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java
@@ -36,7 +36,7 @@ public class CurrentModel {
private ModelContainer model;
private ChangeSet changeSet;
- private DdlWrite write;
+ private DdlWrite writer;
/**
* Construct with a given EbeanServer instance for DDL create all generation, not migration.
@@ -117,7 +117,7 @@ public class CurrentModel {
/**
* Return the 'Create' DDL.
*/
- public String getCreateDdl() throws IOException {
+ public String getCreateDdl() {
createDdl();
@@ -128,10 +128,13 @@ public class CurrentModel {
if (jaxbPresent) {
addExtraDdl(ddl, ExtraDdlXmlReader.readBuiltin(), "-- init script ");
}
- ddl.append(write.apply().getBuffer());
- ddl.append(write.applyForeignKeys().getBuffer());
- ddl.append(write.applyHistoryView().getBuffer());
- ddl.append(write.applyHistoryTrigger().getBuffer());
+
+ try {
+ writer.writeApply(ddl);
+ } catch (IOException e) { // should not happen on StringBuilder
+ throw new RuntimeException(e);
+ }
+
return ddl.toString();
}
@@ -150,7 +153,7 @@ public class CurrentModel {
/**
* Return the 'Drop' DDL.
*/
- public String getDropAllDdl() throws IOException {
+ public String getDropAllDdl() {
createDdl();
@@ -158,22 +161,25 @@ public class CurrentModel {
if (ddlHeader != null && !ddlHeader.isEmpty()) {
ddl.append(ddlHeader).append('\n');
}
- ddl.append(write.dropAllForeignKeys().getBuffer());
- ddl.append(write.dropAll().getBuffer());
+ try {
+ writer.writeDropAll(ddl);
+ } catch (IOException e) { // should not happen on StringBuilder
+ throw new RuntimeException(e);
+ }
return ddl.toString();
}
/**
* Create all the DDL based on the changeSet.
*/
- private void createDdl() throws IOException {
- if (write == null) {
+ private void createDdl() {
+ if (writer == null) {
ChangeSet createChangeSet = getChangeSet();
- write = new DdlWrite(new MConfiguration(), model, ddlOptions);
+ writer = new DdlWrite(new MConfiguration(), model, ddlOptions);
DdlHandler handler = handler();
- handler.generateProlog(write);
- handler.generate(write, createChangeSet);
- handler.generateEpilog(write);
+ handler.generateProlog(writer);
+ handler.generate(writer, createChangeSet);
+ handler.generateEpilog(writer);
}
}
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java
index f226ebaec..aea2425d8 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java
@@ -89,8 +89,9 @@ public class MTableIdentity {
return IdentityType.EXTERNAL;
case GENERATOR:
return IdentityType.GENERATOR;
+ default:
+ return null;
}
- return null;
}
private static int toInt(BigInteger firstVal, BigInteger secVal) {
diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java
index ec55dd9a9..83de7e459 100644
--- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java
+++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java
@@ -3,7 +3,6 @@ package io.ebeaninternal.dbmigration.model;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.util.IOUtils;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
@@ -39,23 +38,24 @@ public class PlatformDdlWriter {
/**
* Write the migration as platform specific ddl.
*/
- public void processMigration(Migration dbMigration, DdlWrite write, File writePath, String fullVersion) throws IOException {
+ public void processMigration(Migration dbMigration, DdlWrite writer, File writePath, String fullVersion)
+ throws IOException {
DdlHandler handler = handler();
- handler.generateProlog(write);
+ handler.generateProlog(writer);
if (lockTimeoutSeconds > 0) {
String lockSql = platformDdl.setLockTimeout(lockTimeoutSeconds);
if (lockSql != null) {
- write.apply().append(lockSql).endOfStatement().newLine();
+ writer.apply().append(lockSql).endOfStatement().newLine();
}
}
List changeSets = dbMigration.getChangeSet();
for (ChangeSet changeSet : changeSets) {
if (isApply(changeSet)) {
- handler.generate(write, changeSet);
+ handler.generate(writer, changeSet);
}
}
- handler.generateEpilog(write);
- writePlatformDdl(write, writePath, fullVersion);
+ handler.generateEpilog(writer);
+ writePlatformDdl(writer, writePath, fullVersion);
}
/**
@@ -68,10 +68,10 @@ public class PlatformDdlWriter {
/**
* Write the ddl files.
*/
- protected void writePlatformDdl(DdlWrite write, File resourcePath, String fullVersion) throws IOException {
- if (!write.isApplyEmpty()) {
+ protected void writePlatformDdl(DdlWrite writer, File resourcePath, String fullVersion) throws IOException {
+ if (!writer.isApplyEmpty()) {
try (Writer applyWriter = createWriter(resourcePath, fullVersion, ".sql")) {
- writeApplyDdl(applyWriter, write);
+ writeApplyDdl(applyWriter, writer);
applyWriter.flush();
}
}
@@ -85,26 +85,12 @@ public class PlatformDdlWriter {
/**
* Write the 'Apply' DDL buffers to the writer.
*/
- protected void writeApplyDdl(Writer writer, DdlWrite write) throws IOException {
+ protected void writeApplyDdl(Writer writer, DdlWrite ddl) throws IOException {
String header = databaseConfig.getDdlHeader();
if (header != null && !header.isEmpty()) {
writer.append(header).append('\n');
}
- // merge the apply buffers in the appropriate order
- prependDropDependencies(writer, write.applyDropDependencies());
- writer.append("-- apply changes\n");
- writer.append(write.apply().getBuffer());
- writer.append(write.applyForeignKeys().getBuffer());
- writer.append(write.applyHistoryView().getBuffer());
- writer.append(write.applyHistoryTrigger().getBuffer());
- }
-
- private void prependDropDependencies(Writer writer, DdlBuffer buffer) throws IOException {
- if (!buffer.isEmpty()) {
- writer.append("-- drop dependencies\n");
- writer.append(buffer.getBuffer());
- writer.append("\n");
- }
+ ddl.writeApply(writer);
}
/**
diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/BaseDdlHandlerTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/BaseDdlHandlerTest.java
index 550d508ad..092bc75fa 100644
--- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/BaseDdlHandlerTest.java
+++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/BaseDdlHandlerTest.java
@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class BaseDdlHandlerTest extends BaseTestCase {
private static boolean useV1Syntax = Boolean.getBoolean("ebean.h2.useV1Syntax");
-
+
private final DatabaseConfig serverConfig = new DatabaseConfig();
private DdlHandler handler(DatabasePlatform platform) {
@@ -45,192 +45,196 @@ public class BaseDdlHandlerTest extends BaseTestCase {
@Test
public void addColumn_nullable_noConstraint() throws Exception {
- DdlWrite write = new DdlWrite();
- h2Handler().generate(write, Helper.getAddColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column added_to_foo varchar(20);\n\n");
+ DdlWrite writer = new DdlWrite();
+ h2Handler().generate(writer, Helper.getAddColumn());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column added_to_foo varchar(20);\n");
- write = new DdlWrite();
- sqlserverHandler().generate(write, Helper.getAddColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add added_to_foo nvarchar(20);\n\n");
+ writer = new DdlWrite();
+ sqlserverHandler().generate(writer, Helper.getAddColumn());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add added_to_foo nvarchar(20);\n");
- write = new DdlWrite();
- hanaHandler().generate(write, Helper.getAddColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( added_to_foo nvarchar(20));\n\n");
+ writer = new DdlWrite();
+ hanaHandler().generate(writer, Helper.getAddColumn());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (added_to_foo nvarchar(20));\n");
}
@Test
public void addColumn_withCheckConstraint() throws Exception {
- DdlWrite write = new DdlWrite();
- h2Handler().generate(write, Helper.getAlterTableAddColumnWithCheckConstraint());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column status integer;\n"
- + "alter table foo add constraint ck_ordering_status check ( status in (0,1));\n\n");
+ DdlWrite writer = new DdlWrite();
+ h2Handler().generate(writer, Helper.getAlterTableAddColumnWithCheckConstraint());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column status integer;\n"
+ + "-- apply post alter\nalter table foo add constraint ck_ordering_status check ( status in (0,1));\n");
- write = new DdlWrite();
- hanaHandler().generate(write, Helper.getAlterTableAddColumnWithCheckConstraint());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( status integer);\n"
- + "alter table foo add constraint ck_ordering_status check ( status in (0,1));\n\n");
+ writer = new DdlWrite();
+ hanaHandler().generate(writer, Helper.getAlterTableAddColumnWithCheckConstraint());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (status integer);\n"
+ + "-- apply post alter\nalter table foo add constraint ck_ordering_status check ( status in (0,1));\n");
}
/**
- * Test the functionality of the Ebean {@literal @}DbArray extension during DDL
- * generation.
+ * Test the functionality of the Ebean {@literal @}DbArray extension during DDL generation.
*/
@Test
public void addColumn_dbarray() throws Exception {
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
DdlHandler postgresHandler = postgresHandler();
- postgresHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());
+ postgresHandler.generate(writer, Helper.getAlterTableAddDbArrayColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_added_to_foo varchar[];\n\n");
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_added_to_foo varchar[];\n");
- write = new DdlWrite();
+ writer = new DdlWrite();
DdlHandler sqlserverHandler = sqlserverHandler();
- sqlserverHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_added_to_foo varchar(1000);\n\n");
+ sqlserverHandler.generate(writer, Helper.getAlterTableAddDbArrayColumn());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_added_to_foo varchar(1000);\n");
- write = new DdlWrite();
+ writer = new DdlWrite();
DdlHandler hanaHandler = hanaHandler();
- hanaHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_added_to_foo nvarchar(255) array);\n\n");
+ hanaHandler.generate(writer, Helper.getAlterTableAddDbArrayColumn());
+ assertThat(writer.toString())
+ .isEqualTo("-- apply alter tables\nalter table foo add (dbarray_added_to_foo nvarchar(255) array);\n");
}
@Test
public void addColumn_dbarray_withLength() throws Exception {
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
- postgresHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety varchar[];\n\n");
+ postgresHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_ninety varchar[];\n");
- write = new DdlWrite();
- h2Handler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
+ writer = new DdlWrite();
+ h2Handler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
if (useV1Syntax) {
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety array;\n\n");
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_ninety array;\n");
} else {
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety varchar array;\n\n");
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_ninety varchar array;\n");
}
- write = new DdlWrite();
- sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_ninety varchar(90);\n\n");
+ writer = new DdlWrite();
+ sqlserverHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_ninety varchar(90);\n");
- write = new DdlWrite();
- hanaHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_ninety nvarchar(255) array(90));\n\n");
+ writer = new DdlWrite();
+ hanaHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
+ assertThat(writer.toString())
+ .isEqualTo("-- apply alter tables\nalter table foo add (dbarray_ninety nvarchar(255) array(90));\n");
}
@Test
public void addColumn_dbarray_integer_withLength() throws Exception {
- DdlWrite write = new DdlWrite();
- postgresHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer integer[];\n\n");
+ DdlWrite writer = new DdlWrite();
+ postgresHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_integer integer[];\n");
- write = new DdlWrite();
- h2Handler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
+ writer = new DdlWrite();
+ h2Handler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
if (useV1Syntax) {
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer array;\n\n");
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_integer array;\n");
} else {
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer integer array;\n\n");
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_integer integer array;\n");
}
- write = new DdlWrite();
- sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_integer varchar(90);\n\n");
+ writer = new DdlWrite();
+ sqlserverHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_integer varchar(90);\n");
- write = new DdlWrite();
- sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnInteger());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_integer varchar(1000);\n\n");
+ writer = new DdlWrite();
+ sqlserverHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnInteger());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_integer varchar(1000);\n");
- write = new DdlWrite();
- hanaHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_integer integer array(90));\n\n");
+ writer = new DdlWrite();
+ hanaHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (dbarray_integer integer array(90));\n");
- write = new DdlWrite();
- hanaHandler().generate(write, Helper.getAlterTableAddDbArrayColumnInteger());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_integer integer array);\n\n");
+ writer = new DdlWrite();
+ hanaHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnInteger());
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (dbarray_integer integer array);\n");
}
@Test
public void addColumn_withForeignKey() throws Exception {
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
DdlHandler handler = h2Handler();
- handler.generate(write, Helper.getAlterTableAddColumn());
+ handler.generate(writer, Helper.getAlterTableAddColumn());
- String buffer = write.apply().getBuffer();
- assertThat(buffer).contains("alter table foo add column some_id integer;");
+ String buffer = writer.toString();
+ assertThat(buffer).contains("-- apply alter tables\nalter table foo add column some_id integer;");
- String fkBuffer = write.applyForeignKeys().getBuffer();
+ String fkBuffer = writer.applyForeignKeys().getBuffer();
assertThat(fkBuffer).contains(
- "alter table foo add constraint fk_foo_some_id foreign key (some_id) references bar (id) on delete restrict on update restrict;");
+ "alter table foo add constraint fk_foo_some_id foreign key (some_id) references bar (id) on delete restrict on update restrict;");
assertThat(fkBuffer).contains("create index idx_foo_some_id on foo (some_id);");
- assertThat(write.dropAll().getBuffer()).isEqualTo("");
+ assertThat(writer.dropAll().getBuffer()).isEqualTo("");
}
@Test
public void dropColumn() throws Exception {
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
DdlHandler handler = h2Handler();
- handler.generate(write, Helper.getDropColumn());
+ handler.generate(writer, Helper.getDropColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("alter table foo drop column col2;\n\n");
- assertThat(write.dropAll().getBuffer()).isEqualTo("");
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo drop column col2;\n");
+ assertThat(writer.dropAll().getBuffer()).isEqualTo("");
- write = new DdlWrite();
+ writer = new DdlWrite();
DdlHandler hanaHandler = hanaHandler();
- hanaHandler.generate(write, Helper.getDropColumn());
+ hanaHandler.generate(writer, Helper.getDropColumn());
- assertThat(write.apply().getBuffer()).isEqualTo("CALL usp_ebean_drop_column('foo', 'col2');\n\n");
- assertThat(write.dropAll().getBuffer()).isEqualTo("");
+ assertThat(writer.toString()).isEqualTo("-- apply alter tables\nCALL usp_ebean_drop_column('foo', 'col2');\n");
+ assertThat(writer.dropAll().getBuffer()).isEqualTo("");
}
@Test
public void createTable() throws Exception {
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
DdlHandler handler = h2Handler();
- handler.generate(write, Helper.getCreateTable());
+ handler.generate(writer, Helper.getCreateTable());
- String createTableDDL = Helper.asText(this, "/assert/create-table.txt");
+ String createTableDDL = Helper.asText(this, "/assert/drop-create-table.txt");
- assertThat(write.apply().getBuffer()).isEqualTo(createTableDDL);
- assertThat(write.dropAll().getBuffer().trim()).isEqualTo("drop table if exists foo;");
+ assertThat(writer.toString()).isEqualTo(createTableDDL);
+ assertThat(writer.dropAll().getBuffer().trim()).isEqualTo("drop table if exists foo;");
- write = new DdlWrite();
+ writer = new DdlWrite();
DdlHandler hanaHandler = hanaHandler();
- hanaHandler.generate(write, Helper.getCreateTable());
+ hanaHandler.generate(writer, Helper.getCreateTable());
- String createColumnTableDDL = Helper.asText(this, "/assert/create-column-table.txt");
+ String createColumnTableDDL = Helper.asText(this, "/assert/drop-create-column-table.txt");
- assertThat(write.apply().getBuffer()).isEqualTo(createColumnTableDDL);
- assertThat(write.dropAll().getBuffer().trim()).isEqualTo("drop table foo cascade;");
+ assertThat(writer.toString()).isEqualTo(createColumnTableDDL);
+ assertThat(writer.dropAll().getBuffer().trim()).isEqualTo("drop table foo cascade;");
}
@Test
public void generateChangeSet() throws Exception {
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
DdlHandler handler = h2Handler();
- handler.generate(write, Helper.getChangeSet());
+ handler.generate(writer, Helper.getChangeSet());
String apply = Helper.asText(this, "/assert/BaseDdlHandlerTest/baseApply.sql");
String rollbackLast = Helper.asText(this, "/assert/BaseDdlHandlerTest/baseDropAll.sql");
-
- assertThat(write.apply().getBuffer()).isEqualTo(apply);
- assertThat(write.dropAll().getBuffer()).isEqualTo(rollbackLast);
+ StringBuilder sb = new StringBuilder();
+ writer.writeApply(sb);
+ assertThat(sb.toString()).isEqualTo(apply);
+ sb = new StringBuilder();
+ writer.writeDropAll(sb);
+ assertThat(sb.toString()).isEqualTo(rollbackLast);
}
@Disabled
@@ -241,16 +245,16 @@ public class BaseDdlHandlerTest extends BaseTestCase {
ChangeSet createChangeSet = new CurrentModel(defaultServer).getChangeSet();
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
DdlHandler handler = h2Handler();
- handler.generate(write, createChangeSet);
+ handler.generate(writer, createChangeSet);
String apply = Helper.asText(this, "/assert/changeset-apply.txt");
String rollbackLast = Helper.asText(this, "/assert/changeset-dropAll.txt");
- assertThat(write.apply().getBuffer()).isEqualTo(apply);
- assertThat(write.dropAll().getBuffer()).isEqualTo(rollbackLast);
+ assertThat(writer.toString()).isEqualTo(apply);
+ assertThat(writer.dropAll().getBuffer()).isEqualTo(rollbackLast);
}
@Disabled
@@ -260,20 +264,20 @@ public class BaseDdlHandlerTest extends BaseTestCase {
ChangeSet createChangeSet = new CurrentModel(defaultServer).getChangeSet();
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
DdlHandler handler = postgresHandler();
- handler.generate(write, createChangeSet);
+ handler.generate(writer, createChangeSet);
String apply = Helper.asText(this, "/assert/changeset-pg-apply.sql");
String applyLast = Helper.asText(this, "/assert/changeset-pg-applyLast.sql");
String rollbackFirst = Helper.asText(this, "/assert/changeset-pg-rollbackFirst.sql");
String rollbackLast = Helper.asText(this, "/assert/changeset-pg-rollbackLast.sql");
- assertThat(write.apply().getBuffer()).isEqualTo(apply);
- assertThat(write.applyForeignKeys().getBuffer()).isEqualTo(applyLast);
- assertThat(write.dropAllForeignKeys().getBuffer()).isEqualTo(rollbackFirst);
- assertThat(write.dropAll().getBuffer()).isEqualTo(rollbackLast);
+ assertThat(writer.toString()).isEqualTo(apply);
+ assertThat(writer.applyForeignKeys().getBuffer()).isEqualTo(applyLast);
+ assertThat(writer.dropAllForeignKeys().getBuffer()).isEqualTo(rollbackFirst);
+ assertThat(writer.dropAll().getBuffer()).isEqualTo(rollbackLast);
}
}
diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java
index d6af52969..3f09718f6 100644
--- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java
+++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java
@@ -15,7 +15,6 @@ import io.ebeaninternal.dbmigration.migration.Column;
import io.ebeaninternal.dbmigration.migration.CreateTable;
import org.junit.jupiter.api.Test;
-import java.io.IOException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@@ -28,121 +27,121 @@ public class BaseTableDdlTest {
private final PlatformDdl h2ddl = PlatformDdlBuilder.create(new H2Platform());
@Test
- public void testAlterColumn() throws IOException {
+ public void testAlterColumn() {
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
AlterColumn alterColumn = new AlterColumn();
alterColumn.setTableName("mytab");
alterColumn.setCheckConstraint("check (acol in ('A','B'))");
alterColumn.setCheckConstraintName("ck_mytab_acol");
- ddlGen.generate(write, alterColumn);
+ ddlGen.generate(writer, alterColumn);
- String ddl = write.apply().getBuffer();
+ String ddl = writer.toString();
assertThat(ddl).contains("alter table mytab drop constraint if exists ck_mytab_acol");
assertThat(ddl).contains("alter table mytab add constraint ck_mytab_acol check (acol in ('A','B'))");
}
@Test
- public void testAddColumn_withTypeConversion() throws IOException {
+ public void testAddColumn_withTypeConversion() {
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, PlatformDdlBuilder.create(new OraclePlatform()));
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
Column column = new Column();
column.setName("col_name");
column.setType("varchar(20)");
- ddlGen.alterTableAddColumn(write.apply(), "mytable", column, false, false);
+ ddlGen.alterTableAddColumn(writer, "mytable", column, false, false);
- String ddl = write.apply().getBuffer();
+ String ddl = writer.toString();
assertThat(ddl).contains("alter table mytable add col_name varchar2(20)");
}
@Test
- public void testAddColumn_withTypeConversion_clickHouseVarchar() throws IOException {
+ public void testAddColumn_withTypeConversion_clickHouseVarchar() {
ClickHouseTableDdl ddlGen = new ClickHouseTableDdl(serverConfig, PlatformDdlBuilder.create(new ClickHousePlatform()));
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
Column column = new Column();
column.setName("col_name");
column.setType("varchar(20)");
- ddlGen.alterTableAddColumn(write.apply(), "mytable", column, false, false);
+ ddlGen.alterTableAddColumn(writer, "mytable", column, false, false);
- String ddl = write.apply().getBuffer();
+ String ddl = writer.toString();
assertThat(ddl).contains("alter table mytable add column col_name String");
}
@Test
- public void testAlterColumnComment() throws IOException {
+ public void testAlterColumnComment() {
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
AlterColumn alterColumn = new AlterColumn();
alterColumn.setTableName("mytab");
alterColumn.setColumnName("acol");
alterColumn.setComment("my comment");
- ddlGen.generate(write, alterColumn);
+ ddlGen.generate(writer, alterColumn);
- String ddl = write.apply().getBuffer();
+ String ddl = writer.applyPostAlter().getBuffer();
assertThat(ddl).contains("comment on column mytab.acol is 'my comment'");
}
@Test
- public void alterTableAddColumnWithComment() throws IOException {
+ public void alterTableAddColumnWithComment() {
BaseTableDdl ddl = new BaseTableDdl(serverConfig, h2ddl);
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
Column column = new Column();
column.setName("my_column");
column.setComment("some comment");
column.setType("int");
- ddl.alterTableAddColumn(write.apply(), "my_table", column, false, false);
- assertEquals(
- "alter table my_table add column my_column int;\n" +
- "comment on column my_table.my_column is 'some comment';\n", write.apply().getBuffer());
+ ddl.alterTableAddColumn(writer, "my_table", column, false, false);
+ assertEquals("-- apply alter tables\nalter table my_table add column my_column int;\n"
+ + "-- apply post alter\ncomment on column my_table.my_column is 'some comment';\n",
+ writer.toString());
}
@Test
- public void testAddTableComment() throws IOException {
+ public void testAddTableComment() {
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
AddTableComment addTableComment = new AddTableComment();
addTableComment.setName("mytab");
addTableComment.setComment("my comment");
- ddlGen.generate(write, addTableComment);
+ ddlGen.generate(writer, addTableComment);
- String ddl = write.apply().getBuffer();
+ String ddl = writer.applyPostAlter().getBuffer();
assertThat(ddl).contains("comment on table mytab is 'my comment'");
}
@Test
- public void testAddTableComment_mysql() throws IOException {
+ public void testAddTableComment_mysql() {
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, PlatformDdlBuilder.create(new MySqlPlatform()));
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
AddTableComment addTableComment = new AddTableComment();
addTableComment.setName("mytab");
addTableComment.setComment("my comment");
- ddlGen.generate(write, addTableComment);
+ ddlGen.generate(writer, addTableComment);
- String ddl = write.apply().getBuffer();
+ String ddl = writer.applyPostAlter().getBuffer();
assertThat(ddl).contains("alter table mytab comment = 'my comment'");
}
@@ -151,14 +150,14 @@ public class BaseTableDdlTest {
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
- ddlGen.generate(write, createTable());
- String apply = write.apply().getBuffer();
- String applyLast = write.applyForeignKeys().getBuffer();
+ ddlGen.generate(writer, createTable());
+ String apply = writer.apply().getBuffer();
+ String applyLast = writer.applyForeignKeys().getBuffer();
- String rollbackFirst = write.dropAllForeignKeys().getBuffer();
- String rollbackLast = write.dropAll().getBuffer();
+ String rollbackFirst = writer.dropAllForeignKeys().getBuffer();
+ String rollbackLast = writer.dropAll().getBuffer();
assertThat(apply).isEqualTo(Helper.asText(this, "/assert/BaseTableDdlTest/createTable-apply.txt"));
assertThat(applyLast).isEqualTo(Helper.asText(this, "/assert/BaseTableDdlTest/createTable-applyLast.txt"));
diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/H2HistoryDdlTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/H2HistoryDdlTest.java
deleted file mode 100644
index a23a7ad79..000000000
--- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/H2HistoryDdlTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-
-import io.ebean.DB;
-import io.ebean.config.dbplatform.h2.H2Platform;
-import io.ebeaninternal.api.SpiEbeanServer;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
-import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
-import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
-import io.ebeaninternal.dbmigration.model.CurrentModel;
-import io.ebeaninternal.dbmigration.model.MConfiguration;
-import io.ebeaninternal.dbmigration.model.ModelContainer;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-
-public class H2HistoryDdlTest {
-
- @Test
- public void testRegenerateHistoryTriggers() throws Exception {
-
- SpiEbeanServer ebeanServer = (SpiEbeanServer) DB.getDefault();
-
- HistoryTableUpdate update = new HistoryTableUpdate("c_user");
- update.add(HistoryTableUpdate.Change.ADD, "one");
- update.add(HistoryTableUpdate.Change.DROP, "two");
-
-
- CurrentModel currentModel = new CurrentModel(ebeanServer);
- ModelContainer modelContainer = currentModel.read();
- DdlWrite write = new DdlWrite(new MConfiguration(), modelContainer, new DdlOptions());
-
- H2Platform h2Platform = new H2Platform();
- PlatformDdl h2Ddl = PlatformDdlBuilder.create(h2Platform);
- h2Ddl.configure(ebeanServer.config());
- h2Ddl.regenerateHistoryTriggers(write, update);
-
- assertThat(write.applyHistoryView().isEmpty()).isFalse();
- assertThat(write.applyHistoryTrigger().isEmpty()).isFalse();
- assertThat(write.applyHistoryView().getBuffer())
- .contains("create view")
- .doesNotContain("create trigger");
- assertThat(write.applyHistoryTrigger().getBuffer())
- .contains("add one")
- .contains("create trigger")
- .doesNotContain("create view");
- assertThat(write.dropAll().isEmpty()).isTrue();
-
- }
-}
diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaDdlTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaDdlTest.java
index 3e467babe..17a904aca 100644
--- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaDdlTest.java
+++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaDdlTest.java
@@ -5,24 +5,22 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.Column;
import org.junit.jupiter.api.Test;
-import java.io.IOException;
-
import static org.junit.jupiter.api.Assertions.assertEquals;
public class HanaDdlTest {
@Test
- public void alterTableDropColumn() throws IOException {
+ public void alterTableDropColumn() {
HanaColumnStoreDdl ddl = new HanaColumnStoreDdl(new HanaPlatform());
- DdlWrite write = new DdlWrite();
- ddl.alterTableDropColumn(write.apply(), "my_table", "my_column");
- assertEquals("CALL usp_ebean_drop_column('my_table', 'my_column');\n", write.apply().getBuffer());
+ DdlWrite writer = new DdlWrite();
+ ddl.alterTableDropColumn(writer, "my_table", "my_column");
+ assertEquals("-- apply alter tables\nCALL usp_ebean_drop_column('my_table', 'my_column');\n", writer.toString());
}
@Test
- public void alterTableAddColumn() throws IOException {
+ public void alterTableAddColumn() {
HanaColumnStoreDdl ddl = new HanaColumnStoreDdl(new HanaPlatform());
- DdlWrite write = new DdlWrite();
+ DdlWrite writer = new DdlWrite();
Column column = new Column();
column.setName("my_column");
column.setComment("comment");
@@ -35,7 +33,9 @@ public class HanaDdlTest {
column.setCheckConstraintName("check_constraint");
column.setHistoryExclude(Boolean.TRUE);
column.setIdentity(Boolean.TRUE);
- ddl.alterTableAddColumn(write.apply(), "my_table", column, false, "1");
- assertEquals("alter table my_table add ( my_column int default 1 not null);\nalter table my_table add constraint check_constraint CHECK(my_column > 0);\n", write.apply().getBuffer());
+ ddl.alterTableAddColumn(writer, "my_table", column, false, "1");
+ assertEquals(
+ "-- apply alter tables\nalter table my_table add (my_column int default 1 not null);\n-- apply post alter\nalter table my_table add constraint check_constraint CHECK(my_column > 0);\n",
+ writer.toString());
}
}
diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HistoryTableUpdateTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HistoryTableUpdateTest.java
deleted file mode 100644
index a2f2c6080..000000000
--- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HistoryTableUpdateTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package io.ebeaninternal.dbmigration.ddlgeneration.platform;
-
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-
-public class HistoryTableUpdateTest {
-
- @Test
- public void testDescription() throws Exception {
-
- HistoryTableUpdate upd = new HistoryTableUpdate("mytab");
- upd.add(HistoryTableUpdate.Change.ADD, "two");
- upd.add(HistoryTableUpdate.Change.DROP, "four");
-
- assertThat(upd.description()).isEqualTo("[add two, drop four]");
- }
-
- @Test
- public void testDescription_withIncludeExclude() throws Exception {
-
- HistoryTableUpdate upd = new HistoryTableUpdate("mytab");
- upd.add(HistoryTableUpdate.Change.ADD, "two");
- upd.add(HistoryTableUpdate.Change.INCLUDE, "five");
- upd.add(HistoryTableUpdate.Change.EXCLUDE, "six");
- upd.add(HistoryTableUpdate.Change.DROP, "four");
-
- assertThat(upd.description()).isEqualTo("[add two, include five, exclude six, drop four]");
- }
-
-}
diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_AlterColumnTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_AlterColumnTest.java
index 2ae1118f1..c688a669a 100644
--- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_AlterColumnTest.java
+++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_AlterColumnTest.java
@@ -3,6 +3,7 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.DB;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.IdType;
+import io.ebean.config.dbplatform.db2.DB2LuwPlatform;
import io.ebean.config.dbplatform.h2.H2Platform;
import io.ebean.config.dbplatform.hana.HanaPlatform;
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
@@ -14,14 +15,11 @@ import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
import io.ebeaninternal.dbmigration.migration.Column;
+
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
-import java.io.IOException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.assertj.core.api.SoftAssertions;
public class PlatformDdl_AlterColumnTest {
@@ -33,229 +31,424 @@ public class PlatformDdl_AlterColumnTest {
private final PlatformDdl oraDdl = PlatformDdlBuilder.create(new OraclePlatform());
private final PlatformDdl sqlServerDdl = PlatformDdlBuilder.create(new SqlServer17Platform());
private final PlatformDdl hanaDdl = PlatformDdlBuilder.create(new HanaPlatform());
+ private final PlatformDdl db2Ddl = PlatformDdlBuilder.create(new DB2LuwPlatform());
+
+ private final SoftAssertions softly = new SoftAssertions();
{
DatabaseConfig serverConfig = DB.getDefault().pluginApi().config();
sqlServerDdl.configure(serverConfig);
}
- AlterColumn alterNotNull() {
- AlterColumn alterColumn = new AlterColumn();
- alterColumn.setTableName("mytab");
- alterColumn.setColumnName("acol");
- alterColumn.setCurrentType("varchar(5)");
- alterColumn.setNotnull(Boolean.TRUE);
-
- return alterColumn;
+ @AfterEach
+ void assertAll() {
+ softly.assertAll();
}
@Test
public void convertArrayType_default() {
- assertThat(mysqlDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar(90)");
- assertThat(mysqlDdl.convertArrayType("integer[](60)")).isEqualTo("varchar(60)");
- assertThat(mysqlDdl.convertArrayType("varchar[]")).isEqualTo("varchar(1000)");
- assertThat(mysqlDdl.convertArrayType("integer[]")).isEqualTo("varchar(1000)");
+ softly.assertThat(mysqlDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar(90)");
+ softly.assertThat(mysqlDdl.convertArrayType("integer[](60)")).isEqualTo("varchar(60)");
+ softly.assertThat(mysqlDdl.convertArrayType("varchar[]")).isEqualTo("varchar(1000)");
+ softly.assertThat(mysqlDdl.convertArrayType("integer[]")).isEqualTo("varchar(1000)");
}
@Test
public void convertArrayType_h2() {
if (useV1Syntax) {
- assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("array");
- assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("array");
- assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("array");
- assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("array");
+ softly.assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("array");
+ softly.assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("array");
+ softly.assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("array");
+ softly.assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("array");
} else {
- assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("varchar array");
- assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("integer array");
- assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("varchar array");
- assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("integer array");
+ softly.assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("varchar array");
+ softly.assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("integer array");
+ softly.assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("varchar array");
+ softly.assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("integer array");
}
}
@Test
public void convertArrayType_postgres() {
- assertThat(pgDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar[]");
- assertThat(pgDdl.convertArrayType("integer[](60)")).isEqualTo("integer[]");
- assertThat(pgDdl.convertArrayType("varchar[]")).isEqualTo("varchar[]");
- assertThat(pgDdl.convertArrayType("integer[]")).isEqualTo("integer[]");
+ softly.assertThat(pgDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar[]");
+ softly.assertThat(pgDdl.convertArrayType("integer[](60)")).isEqualTo("integer[]");
+ softly.assertThat(pgDdl.convertArrayType("varchar[]")).isEqualTo("varchar[]");
+ softly.assertThat(pgDdl.convertArrayType("integer[]")).isEqualTo("integer[]");
}
@Test
public void convertArrayType_hana() {
- assertThat(hanaDdl.convertArrayType("varchar[](90)")).isEqualTo("nvarchar(255) array(90)");
- assertThat(hanaDdl.convertArrayType("integer[](60)")).isEqualTo("integer array(60)");
- assertThat(hanaDdl.convertArrayType("varchar[]")).isEqualTo("nvarchar(255) array");
- assertThat(hanaDdl.convertArrayType("integer[]")).isEqualTo("integer array");
+ softly.assertThat(hanaDdl.convertArrayType("varchar[](90)")).isEqualTo("nvarchar(255) array(90)");
+ softly.assertThat(hanaDdl.convertArrayType("integer[](60)")).isEqualTo("integer array(60)");
+ softly.assertThat(hanaDdl.convertArrayType("varchar[]")).isEqualTo("nvarchar(255) array");
+ softly.assertThat(hanaDdl.convertArrayType("integer[]")).isEqualTo("integer array");
}
@Test
public void testAlterColumnBaseAttributes() {
- AlterColumn alterColumn = alterNotNull();
- assertNull(h2Ddl.alterColumnBaseAttributes(alterColumn));
- assertNull(pgDdl.alterColumnBaseAttributes(alterColumn));
- assertNull(oraDdl.alterColumnBaseAttributes(alterColumn));
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName("mytab");
+ alter.setColumnName("acol");
+ alter.setCurrentType("varchar(5)");
+ alter.setCurrentDefaultValue("'ho'");
+ alter.setCurrentNotnull(Boolean.FALSE);
- String sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab modify acol varchar(5) not null", sql);
+ // alter all attributes
+ alter.setNotnull(Boolean.TRUE); // -> alter to not null
+ alter.setDefaultValue("'hi'"); // and set default
+ alter.setType("varchar(50)"); // and alter type
- sql = sqlServerDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab alter column acol nvarchar(5) not null", sql);
+ String sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol varchar(50);\n"
+ + "alter table mytab alter column acol set default 'hi';\n"
+ + "alter table mytab alter column acol set not null;\n");
- sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab alter ( acol nvarchar(5) not null)", sql);
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol type varchar(50) using acol::varchar(50);\n"
+ + "alter table mytab alter column acol set default 'hi';\n"
+ + "alter table mytab alter column acol set not null;\n");
- alterColumn.setNotnull(Boolean.FALSE);
- sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab modify acol varchar(5)", sql);
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol varchar2(50);\n"
+ + "alter table mytab modify acol default 'hi';\n"
+ + "alter table mytab modify acol not null;\n");
- sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab alter ( acol nvarchar(5))", sql);
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol varchar(50) not null default 'hi';\n");
- alterColumn.setNotnull(null);
- alterColumn.setType("varchar(100)");
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
+ + "alter table mytab alter column acol nvarchar(50) not null;\n"
+ + "alter table mytab add default 'hi' for acol;\n");
- sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab modify acol varchar(100)", sql);
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(50) default 'hi' not null);\n");
- sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab alter ( acol nvarchar(100))", sql);
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set data type varchar(50);\n"
+ + "alter table mytab alter column acol set default 'hi';\n"
+ + "alter table mytab alter column acol set not null;\n"
+ + "call sysproc.admin_cmd('reorg table mytab');\n");
- alterColumn.setCurrentNotnull(Boolean.TRUE);
- sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab modify acol varchar(100) not null", sql);
+ //
+ alter.setCurrentNotnull(Boolean.TRUE);
+ alter.setNotnull(Boolean.FALSE);
+ alter.setDefaultValue("DROP DEFAULT");
+ alter.setType(null); // do not alter type
+
+ sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop default;\n"
+ + "alter table mytab alter column acol set null;\n");
+
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop default;\n"
+ + "alter table mytab alter column acol drop not null;\n");
+
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol default null;\n"
+ + "alter table mytab modify acol null;\n");
+
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol varchar(5);\n");
+
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
+ + "alter table mytab alter column acol nvarchar(5);\n");
+
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(5) default null);\n");
+
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop default;\n"
+ + "alter table mytab alter column acol drop not null;\n");
- sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
- assertEquals("alter table mytab alter ( acol nvarchar(100) not null)", sql);
}
@Test
public void testAlterColumnType() {
- String sql = h2Ddl.alterColumnType("mytab", "acol", "varchar(20)");
- assertEquals("alter table mytab alter column acol varchar(20)", sql);
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName("mytab");
+ alter.setColumnName("acol");
+ alter.setCurrentType("integer");
+ alter.setType("varchar(20)");
- sql = pgDdl.alterColumnType("mytab", "acol", "varchar(20)");
- assertEquals("alter table mytab alter column acol type varchar(20) using acol::varchar(20)", sql);
- sql = pgDdl.alterColumnType("mytab", "acol", "bigint");
- assertEquals("alter table mytab alter column acol type bigint using acol::bigint", sql);
+ String sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol varchar(20);\n");
- sql = oraDdl.alterColumnType("mytab", "acol", "varchar(20)");
- assertEquals("alter table mytab modify acol varchar2(20)", sql);
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol type varchar(20) using acol::varchar(20);\n");
- sql = mysqlDdl.alterColumnType("mytab", "acol", "varchar(20)");
- assertNull(sql);
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol varchar2(20);\n");
- sql = sqlServerDdl.alterColumnType("mytab", "acol", "varchar(20)");
- assertNull(sql);
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol varchar(20);\n");
+
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol nvarchar(20);\n");
+
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(20));\n");
+
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set data type varchar(20);\n"
+ // Note, this reorg may be not necessary when only length attribute is alterd
+ // but this is currently not implemented.
+ + "call sysproc.admin_cmd('reorg table mytab');\n");
+
+ alter.setType("bigint");
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol type bigint using acol::bigint;\n");
+
+ alter.setCurrentType("bigint");
+ alter.setType("integer");
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol decimal);\n"
+ + "alter table mytab alter (acol integer);\n");
+
+ alter.setCurrentType("varchar(20)");
+ alter.setType("varchar(10)");
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nclob);\n"
+ + "alter table mytab alter (acol nvarchar(10));\n");
- sql = hanaDdl.alterColumnType("mytab", "acol", "varchar(20)");
- assertNull(sql);
}
@Test
public void testAlterColumnNotnull() {
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName("mytab");
+ alter.setColumnName("acol");
+ alter.setCurrentType("varchar(20)");
+ alter.setCurrentNotnull(Boolean.FALSE);
+ alter.setNotnull(Boolean.TRUE);
- String sql = h2Ddl.alterColumnNotnull("mytab", "acol", true);
- assertEquals("alter table mytab alter column acol set not null", sql);
+ String sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set not null;\n");
- sql = pgDdl.alterColumnNotnull("mytab", "acol", true);
- assertEquals("alter table mytab alter column acol set not null", sql);
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set not null;\n");
- sql = oraDdl.alterColumnNotnull("mytab", "acol", true);
- assertEquals("alter table mytab modify acol not null", sql);
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol not null;\n");
- sql = mysqlDdl.alterColumnNotnull("mytab", "acol", true);
- assertNull(sql);
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol varchar(20) not null;\n");
- sql = sqlServerDdl.alterColumnNotnull("mytab", "acol", true);
- assertNull(sql);
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol nvarchar(20) not null;\n");
+
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(20) not null);\n");
+
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set not null;\n"
+ + "call sysproc.admin_cmd('reorg table mytab');\n");
- sql = hanaDdl.alterColumnNotnull("mytab", "acol", true);
- assertNull(sql);
}
@Test
public void testAlterColumnNull() {
- String sql = h2Ddl.alterColumnNotnull("mytab", "acol", false);
- assertEquals("alter table mytab alter column acol set null", sql);
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName("mytab");
+ alter.setColumnName("acol");
+ alter.setCurrentType("varchar(20)");
+ alter.setCurrentDefaultValue("'hi'");
+ alter.setCurrentNotnull(Boolean.TRUE);
- sql = pgDdl.alterColumnNotnull("mytab", "acol", false);
- assertEquals("alter table mytab alter column acol drop not null", sql);
+ alter.setNotnull(Boolean.FALSE);
+ String sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set null;\n");
- sql = oraDdl.alterColumnNotnull("mytab", "acol", false);
- assertEquals("alter table mytab modify acol null", sql);
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop not null;\n");
- sql = mysqlDdl.alterColumnNotnull("mytab", "acol", false);
- assertNull(sql);
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol null;\n");
- sql = sqlServerDdl.alterColumnNotnull("mytab", "acol", false);
- assertNull(sql);
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol varchar(20) default 'hi';\n");
- sql = hanaDdl.alterColumnNotnull("mytab", "acol", false);
- assertNull(sql);
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
+ + "alter table mytab alter column acol nvarchar(20);\n"
+ + "alter table mytab add default 'hi' for acol;\n");
+
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(20) default 'hi');\n");
+
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop not null;\n");
}
@Test
- public void testAlterColumnDefaultValue() {
+ public void testAlterColumnAddDefaultValue() {
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName("mytab");
+ alter.setColumnName("acol");
+ alter.setCurrentType("varchar(20)");
+ alter.setCurrentNotnull(Boolean.TRUE);
+ alter.setDefaultValue("'hi'");
- String sql = h2Ddl.alterColumnDefaultValue("mytab", "acol", "'hi'");
- assertEquals("alter table mytab alter column acol set default 'hi'", sql);
+ String sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set default 'hi';\n");
- sql = pgDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
- assertEquals("alter table mytab alter column acol set default 'hi'", sql);
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set default 'hi';\n");
- sql = oraDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
- assertEquals("alter table mytab modify acol default 'hi'", sql);
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol default 'hi';\n");
- sql = mysqlDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
- assertEquals("alter table mytab alter acol set default 'hi'", sql);
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter acol set default 'hi';\n");
- sql = sqlServerDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
- assertEquals("alter table mytab add default 'hi' for acol", sql);
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
+ + "alter table mytab add default 'hi' for acol;\n");
- boolean exceptionCaught = false;
- try {
- hanaDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
- } catch (UnsupportedOperationException e) {
- exceptionCaught = true;
- }
- assertTrue(exceptionCaught);
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(20) default 'hi' not null);\n");
+
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set default 'hi';\n");
+ }
+
+ @Test
+ public void testAlterColumnChangeDefaultValue() {
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName("mytab");
+ alter.setColumnName("acol");
+ alter.setCurrentType("varchar(20)");
+ alter.setCurrentNotnull(Boolean.TRUE);
+ alter.setDefaultValue("'ho'");
+ alter.setDefaultValue("'hi'");
+
+ String sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set default 'hi';\n");
+
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set default 'hi';\n");
+
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol default 'hi';\n");
+
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter acol set default 'hi';\n");
+
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
+ + "alter table mytab add default 'hi' for acol;\n");
+
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(20) default 'hi' not null);\n");
+
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol set default 'hi';\n");
}
@Test
public void testAlterColumnDropDefault() {
- String sql = h2Ddl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
- assertEquals("alter table mytab alter column acol drop default", sql);
+ AlterColumn alter = new AlterColumn();
+ alter.setTableName("mytab");
+ alter.setColumnName("acol");
+ alter.setCurrentType("varchar(20)");
+ alter.setCurrentNotnull(Boolean.TRUE);
+ alter.setCurrentDefaultValue("'hi'");
+ alter.setDefaultValue("DROP DEFAULT");
- sql = pgDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
- assertEquals("alter table mytab alter column acol drop default", sql);
+ String sql = alterColumn(h2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop default;\n");
- sql = oraDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
- assertEquals("alter table mytab modify acol drop default", sql);
+ sql = alterColumn(pgDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop default;\n");
- sql = mysqlDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
- assertEquals("alter table mytab alter acol drop default", sql);
+ sql = alterColumn(oraDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab modify acol default null;\n");
- sql = sqlServerDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
- assertEquals("EXEC usp_ebean_drop_default_constraint mytab, acol", sql);
+ sql = alterColumn(mysqlDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter acol drop default;\n");
+
+ sql = alterColumn(sqlServerDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "EXEC usp_ebean_drop_default_constraint mytab, acol;\n");
+
+ sql = alterColumn(hanaDdl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter (acol nvarchar(20) default null not null);\n");
+
+ sql = alterColumn(db2Ddl, alter);
+ softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ + "alter table mytab alter column acol drop default;\n");
- boolean exceptionCaught = false;
- try {
- hanaDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
- } catch (UnsupportedOperationException e) {
- exceptionCaught = true;
- }
- assertTrue(exceptionCaught);
}
@Test
- public void oracle_alterTableAddColumn() throws IOException {
- DdlWrite write = new DdlWrite();
- oraDdl.alterTableAddColumn(write.apply(), "my_table", simpleColumn(), false, "1");
- assertThat(write.apply().getBuffer()).isEqualTo("alter table my_table add my_column int default 1 not null;\n");
+ public void oracle_alterTableAddColumn() {
+ DdlWrite writer = new DdlWrite();
+ oraDdl.alterTableAddColumn(writer, "my_table", simpleColumn(), false, "1");
+ softly.assertThat(writer.toString())
+ .isEqualTo("-- apply alter tables\n"
+ + "alter table my_table add my_column int default 1 not null;\n");
}
private Column simpleColumn() {
@@ -269,79 +462,148 @@ public class PlatformDdl_AlterColumnTest {
@Test
public void useIdentityType_h2() {
- assertEquals(h2Ddl.useIdentityType(null), IdType.IDENTITY);
- assertEquals(h2Ddl.useIdentityType(IdType.SEQUENCE), IdType.SEQUENCE);
- assertEquals(h2Ddl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
- assertEquals(h2Ddl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
- assertEquals(h2Ddl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
+ softly.assertThat(h2Ddl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(h2Ddl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.SEQUENCE);
+ softly.assertThat(h2Ddl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(h2Ddl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
+ softly.assertThat(h2Ddl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
}
@Test
public void useIdentityType_postgres() {
- assertEquals(pgDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
- assertEquals(pgDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
+ softly.assertThat(pgDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
+ softly.assertThat(pgDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
- assertEquals(pgDdl.useIdentityType(null), IdType.IDENTITY);
- assertEquals(pgDdl.useIdentityType(IdType.SEQUENCE), IdType.SEQUENCE);
- assertEquals(pgDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
+ softly.assertThat(pgDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(pgDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.SEQUENCE);
+ softly.assertThat(pgDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
}
@Test
public void useIdentityType_mysql() {
- assertEquals(mysqlDdl.useIdentityType(null), IdType.IDENTITY);
- assertEquals(mysqlDdl.useIdentityType(IdType.SEQUENCE), IdType.IDENTITY);
- assertEquals(mysqlDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
- assertEquals(mysqlDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
- assertEquals(mysqlDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
+ softly.assertThat(mysqlDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(mysqlDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(mysqlDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(mysqlDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
+ softly.assertThat(mysqlDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
}
@Test
public void useIdentityType_oracle() {
- assertEquals(oraDdl.useIdentityType(null), IdType.IDENTITY);
- assertEquals(oraDdl.useIdentityType(IdType.SEQUENCE), IdType.SEQUENCE);
- assertEquals(oraDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
- assertEquals(oraDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
- assertEquals(oraDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
+ softly.assertThat(oraDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(oraDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.SEQUENCE);
+ softly.assertThat(oraDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(oraDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
+ softly.assertThat(oraDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
}
@Test
public void useIdentityType_hana() {
- assertEquals(hanaDdl.useIdentityType(null), IdType.IDENTITY);
- assertEquals(hanaDdl.useIdentityType(IdType.SEQUENCE), IdType.IDENTITY);
- assertEquals(hanaDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
- assertEquals(hanaDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
- assertEquals(hanaDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
+ softly.assertThat(hanaDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(hanaDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(hanaDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
+ softly.assertThat(hanaDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
+ softly.assertThat(hanaDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
}
@Test
public void appendForeignKeySuffix_when_defaults() {
- assertThat(alterFkey(null, null)).isEqualTo(" on delete restrict on update restrict");
+ softly.assertThat(alterFkey(h2Ddl, null, null)).isEqualTo(" on delete restrict on update restrict");
+ softly.assertThat(alterFkey(pgDdl, null, null)).isEqualTo(" on delete restrict on update restrict");
+ softly.assertThat(alterFkey(mysqlDdl, null, null)).isEqualTo(" on delete restrict on update restrict");
+ softly.assertThat(alterFkey(oraDdl, null, null)).isEqualTo("");
+ softly.assertThat(alterFkey(sqlServerDdl, null, null)).isEqualTo("");
+ softly.assertThat(alterFkey(hanaDdl, null, null)).isEqualTo(" on delete restrict on update restrict");
+ softly.assertThat(alterFkey(db2Ddl, null, null)).isEqualTo(" on delete restrict on update restrict");
}
@Test
public void appendForeignKeySuffix_when_RestrictSetNull() {
- assertThat(alterFkey("RESTRICT", "SET_NULL")).isEqualTo(" on delete restrict on update set null");
+ softly.assertThat(alterFkey(h2Ddl, "RESTRICT", "SET_NULL"))
+ .isEqualTo(" on delete restrict on update set null");
+
+ softly.assertThat(alterFkey(pgDdl, "RESTRICT", "SET_NULL"))
+ .isEqualTo(" on delete restrict on update set null");
+
+ softly.assertThat(alterFkey(mysqlDdl, "RESTRICT", "SET_NULL"))
+ .isEqualTo(" on delete restrict on update set null");
+
+ softly.assertThat(alterFkey(oraDdl, "RESTRICT", "SET_NULL"))
+ .isEqualTo("");
+
+ softly.assertThat(alterFkey(sqlServerDdl, "RESTRICT", "SET_NULL"))
+ .isEqualTo(" on update set null");
+
+ softly.assertThat(alterFkey(hanaDdl, "RESTRICT", "SET_NULL"))
+ .isEqualTo(" on delete restrict on update set null");
+
+ softly.assertThat(alterFkey(db2Ddl, "RESTRICT", "SET_NULL"))
+ .isEqualTo(" on delete restrict on update set null");
}
@Test
public void appendForeignKeySuffix_when_SetNullRestrict() {
- assertThat(alterFkey("SET_NULL", "RESTRICT")).isEqualTo(" on delete set null on update restrict");
+ softly.assertThat(alterFkey(h2Ddl, "SET_NULL", "RESTRICT"))
+ .isEqualTo(" on delete set null on update restrict");
+
+ softly.assertThat(alterFkey(pgDdl, "SET_NULL", "RESTRICT"))
+ .isEqualTo(" on delete set null on update restrict");
+
+ softly.assertThat(alterFkey(mysqlDdl, "SET_NULL", "RESTRICT"))
+ .isEqualTo(" on delete set null on update restrict");
+
+ softly.assertThat(alterFkey(oraDdl, "SET_NULL", "RESTRICT"))
+ .isEqualTo(" on delete set null");
+
+ softly.assertThat(alterFkey(sqlServerDdl, "SET_NULL", "RESTRICT"))
+ .isEqualTo(" on delete set null");
+
+ softly.assertThat(alterFkey(hanaDdl, "SET_NULL", "RESTRICT"))
+ .isEqualTo(" on delete set null on update restrict");
+
+ softly.assertThat(alterFkey(db2Ddl, "SET_NULL", "RESTRICT"))
+ .isEqualTo(" on delete set null on update restrict");
}
@Test
public void appendForeignKeySuffix_when_SetDefaultCascade() {
- assertThat(alterFkey("SET_DEFAULT", "CASCADE")).isEqualTo(" on delete set default on update cascade");
+ softly.assertThat(alterFkey(h2Ddl, "SET_DEFAULT", "CASCADE"))
+ .isEqualTo(" on delete set default on update cascade");
+
+ softly.assertThat(alterFkey(pgDdl, "SET_DEFAULT", "CASCADE"))
+ .isEqualTo(" on delete set default on update cascade");
+
+ softly.assertThat(alterFkey(mysqlDdl, "SET_DEFAULT", "CASCADE"))
+ .isEqualTo(" on delete set default on update cascade");
+
+ softly.assertThat(alterFkey(oraDdl, "SET_DEFAULT", "CASCADE"))
+ .isEqualTo("");
+
+ softly.assertThat(alterFkey(sqlServerDdl, "SET_DEFAULT", "CASCADE"))
+ .isEqualTo(" on delete set default on update cascade");
+
+ softly.assertThat(alterFkey(hanaDdl, "SET_DEFAULT", "CASCADE"))
+ .isEqualTo(" on delete set default on update cascade");
+
+ softly.assertThat(alterFkey(db2Ddl, "SET_DEFAULT", "CASCADE"))
+ .isEqualTo(" on delete set default on update cascade");
}
- private String alterFkey(String onDelete, String onUpdate) {
+ private String alterColumn(PlatformDdl ddl, AlterColumn alterColumn) {
+ DdlWrite write = new DdlWrite();
+ ddl.alterColumn(write, alterColumn);
+ return write.toString();
+ }
+
+ private String alterFkey(PlatformDdl ddl, String onDelete, String onUpdate) {
AlterForeignKey afk = new AlterForeignKey();
afk.setOnDelete(onDelete);
afk.setOnUpdate(onUpdate);
StringBuilder buffer = new StringBuilder();
- h2Ddl.appendForeignKeySuffix(new WriteForeignKey(afk), buffer);
+ ddl.appendForeignKeySuffix(new WriteForeignKey(afk), buffer);
return buffer.toString();
}
diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_dropUniqueConstraintTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_dropUniqueConstraintTest.java
index 00a6e271d..cebab093f 100644
--- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_dropUniqueConstraintTest.java
+++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_dropUniqueConstraintTest.java
@@ -29,11 +29,20 @@ public class PlatformDdl_dropUniqueConstraintTest {
sql = pgDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
assertEquals("alter table mytab drop constraint uq_name", sql);
sql = oraDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
- assertEquals("alter table mytab drop constraint uq_name", sql);
+ assertEquals("delimiter $$\n"
+ + "declare\n"
+ + " expected_error exception;\n"
+ + " pragma exception_init(expected_error, -2443);\n"
+ + "begin\n"
+ + " execute immediate 'alter table mytab drop constraint uq_name';\n"
+ + "exception\n"
+ + " when expected_error then null;\n"
+ + "end;\n"
+ + "$$", sql);
sql = sqlServerDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
assertEquals(
"IF EXISTS (SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('mytab','U') AND name = 'uq_name') drop index uq_name ON mytab;\n"
- + "IF (OBJECT_ID('uq_name', 'UQ') IS NOT NULL) alter table mytab drop constraint uq_name",
+ + "IF OBJECT_ID('uq_name', 'UQ') IS NOT NULL alter table mytab drop constraint uq_name",
sql);
sql = mysqlDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
diff --git a/ebean-ddl-generator/src/test/java/io/localtest/BaseTestCase.java b/ebean-ddl-generator/src/test/java/io/localtest/BaseTestCase.java
index b50932ac4..22b03d983 100644
--- a/ebean-ddl-generator/src/test/java/io/localtest/BaseTestCase.java
+++ b/ebean-ddl-generator/src/test/java/io/localtest/BaseTestCase.java
@@ -5,14 +5,11 @@ import io.ebean.Database;
import io.ebean.annotation.PersistBatch;
import io.ebean.annotation.Platform;
import io.ebeaninternal.api.SpiEbeanServer;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Types;
-import static org.assertj.core.api.Assertions.assertThat;
-
public abstract class BaseTestCase {
protected static Logger logger = LoggerFactory.getLogger(BaseTestCase.class);
diff --git a/ebean-ddl-generator/src/test/java/io/localtest/DbMigrationSqlServerTest.java b/ebean-ddl-generator/src/test/java/io/localtest/DbMigrationSqlServerTest.java
index 3e63179ec..fbe23d7b3 100644
--- a/ebean-ddl-generator/src/test/java/io/localtest/DbMigrationSqlServerTest.java
+++ b/ebean-ddl-generator/src/test/java/io/localtest/DbMigrationSqlServerTest.java
@@ -3,7 +3,6 @@ package io.localtest;
import io.ebean.annotation.Platform;
import io.ebean.dbmigration.DbMigration;
import io.ebeaninternal.api.DbOffline;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
diff --git a/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseApply.sql b/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseApply.sql
index 74f140511..46f430bce 100644
--- a/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseApply.sql
+++ b/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseApply.sql
@@ -1,3 +1,4 @@
+-- apply changes
create table foo (
col1 varchar(4) generated by default as identity not null,
col2 varchar(30) not null,
@@ -6,7 +7,6 @@ create table foo (
);
comment on table foo is 'comment';
+-- apply alter tables
alter table foo add column added_to_foo varchar(20);
-
alter table foo drop column col2;
-
diff --git a/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseDropAll.sql b/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseDropAll.sql
index cf3ebf022..170706608 100644
--- a/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseDropAll.sql
+++ b/ebean-ddl-generator/src/test/resources/assert/BaseDdlHandlerTest/baseDropAll.sql
@@ -1,2 +1,3 @@
+-- drop all
drop table if exists foo;
diff --git a/ebean-ddl-generator/src/test/resources/assert/ModelBuild_compoundKeyTest/apply.sql b/ebean-ddl-generator/src/test/resources/assert/ModelBuild_compoundKeyTest/apply.sql
index 44283c3bf..96ded6d9b 100644
--- a/ebean-ddl-generator/src/test/resources/assert/ModelBuild_compoundKeyTest/apply.sql
+++ b/ebean-ddl-generator/src/test/resources/assert/ModelBuild_compoundKeyTest/apply.sql
@@ -21,6 +21,7 @@ create table ckey_parent (
constraint pk_ckey_parent primary key (one_key,two_key)
);
+-- foreign keys and indices
create index ix_ckey_detail_parent on ckey_detail (one_key,two_key);
alter table ckey_detail add constraint fk_ckey_detail_parent foreign key (one_key,two_key) references ckey_parent (one_key,two_key) on delete restrict on update restrict;
diff --git a/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/apply.sql b/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/apply.sql
index c84e3c252..bc0f0635f 100644
--- a/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/apply.sql
+++ b/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/apply.sql
@@ -13,6 +13,7 @@ create table phones (
constraint pk_phones primary key (id)
);
+-- foreign keys and indices
create index ix_phones_person_id on phones (person_id);
alter table phones add constraint fk_phones_person_id foreign key (person_id) references persons (id) on delete restrict on update restrict;
diff --git a/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/pg-apply.sql b/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/pg-apply.sql
index e866a1f4b..e0063a84e 100644
--- a/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/pg-apply.sql
+++ b/ebean-ddl-generator/src/test/resources/assert/ModelBuild_explicitSequencesTest/pg-apply.sql
@@ -13,6 +13,7 @@ create table phones (
constraint pk_phones primary key (id)
);
+-- foreign keys and indices
create index ix_phones_person_id on phones (person_id);
alter table phones add constraint fk_phones_person_id foreign key (person_id) references persons (id) on delete restrict on update restrict not valid;
diff --git a/ebean-ddl-generator/src/test/resources/assert/create-column-table.txt b/ebean-ddl-generator/src/test/resources/assert/drop-create-column-table.txt
similarity index 84%
rename from ebean-ddl-generator/src/test/resources/assert/create-column-table.txt
rename to ebean-ddl-generator/src/test/resources/assert/drop-create-column-table.txt
index 879972680..b5b138663 100644
--- a/ebean-ddl-generator/src/test/resources/assert/create-column-table.txt
+++ b/ebean-ddl-generator/src/test/resources/assert/drop-create-column-table.txt
@@ -1,3 +1,7 @@
+-- drop all
+drop table foo cascade;
+
+-- apply changes
create column table foo (
col1 nvarchar(4) generated by default as identity not null,
col2 nvarchar(30) not null,
diff --git a/ebean-ddl-generator/src/test/resources/assert/create-table.txt b/ebean-ddl-generator/src/test/resources/assert/drop-create-table.txt
similarity index 83%
rename from ebean-ddl-generator/src/test/resources/assert/create-table.txt
rename to ebean-ddl-generator/src/test/resources/assert/drop-create-table.txt
index 3330f90e5..1b9b2ab87 100644
--- a/ebean-ddl-generator/src/test/resources/assert/create-table.txt
+++ b/ebean-ddl-generator/src/test/resources/assert/drop-create-table.txt
@@ -1,3 +1,7 @@
+-- drop all
+drop table if exists foo;
+
+-- apply changes
create table foo (
col1 varchar(4) generated by default as identity not null,
col2 varchar(30) not null,
diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml
index 66a48c9a0..916b13166 100644
--- a/ebean-externalmapping-xml/pom.xml
+++ b/ebean-externalmapping-xml/pom.xml
@@ -73,7 +73,7 @@
io.avaje
junit
- 1.0
+ 1.1
test
diff --git a/ebean-kotlin/pom.xml b/ebean-kotlin/pom.xml
index 1b50fe698..df37c439c 100644
--- a/ebean-kotlin/pom.xml
+++ b/ebean-kotlin/pom.xml
@@ -42,7 +42,7 @@
io.avaje
junit
- 1.0
+ 1.1
test
diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml
index 0a49ac36b..b41011ab4 100644
--- a/ebean-postgis/pom.xml
+++ b/ebean-postgis/pom.xml
@@ -14,7 +14,7 @@
ebean-postgis
- 2.2.1
+ 2.5.1
@@ -37,14 +37,14 @@
net.postgis
postgis-jdbc
- [${postgis.jdbc.version}]
+ ${postgis.jdbc.version}
org.postgresql
postgresql
- 42.3.2
+ 42.3.3
provided
@@ -64,13 +64,6 @@
provided