#559 - DDL - DB Migration refactor - remove rollback.ddl generation (ultimately not used by FlywayDb etc)

This commit is contained in:
Robin Bygrave
2016-02-11 22:17:35 +13:00
parent 019ce4e614
commit 062f7a281f
16 changed files with 64 additions and 368 deletions
@@ -23,11 +23,6 @@ public class DbMigrationConfig {
*/
protected boolean generate;
/**
* Set to true to suppress the output of the rollback script.
*/
protected boolean suppressRollback;
/**
* The migration version name (typically FlywayDb compatible).
* <p>
@@ -61,21 +56,8 @@ public class DbMigrationConfig {
*/
protected String modelPath = "model";
/**
* Subdirectory the rollback ddl scripts go into.
*/
protected String rollbackPath = "rollback";
/**
* Apply script suffix.
*/
protected String applySuffix = ".sql";
/**
* Default rollback script suffix to ddl so that it isn't picked up by FlywayDb.
*/
protected String rollbackSuffix = ".rollback.ddl";
protected String modelSuffix = ".model.xml";
protected boolean includeGeneratedFileComment;
@@ -135,20 +117,6 @@ public class DbMigrationConfig {
this.modelPath = modelPath;
}
/**
* Return the relative path for the rollback ddl scripts (defaults to rollback).
*/
public String getRollbackPath() {
return rollbackPath;
}
/**
* Set the relative path for the rollback ddl scripts (defaults to rollback).
*/
public void setRollbackPath(String rollbackPath) {
this.rollbackPath = rollbackPath;
}
/**
* Return the model suffix (defaults to model.xml)
*/
@@ -163,20 +131,6 @@ public class DbMigrationConfig {
this.modelSuffix = modelSuffix;
}
/**
* Return true if the rollback script should not be output.
*/
public boolean isSuppressRollback() {
return suppressRollback;
}
/**
* Set to true to suppress the output of the rollback script.
*/
public void setSuppressRollback(boolean suppressRollback) {
this.suppressRollback = suppressRollback;
}
/**
* Return the apply script suffix (defaults to sql).
*/
@@ -191,20 +145,6 @@ public class DbMigrationConfig {
this.applySuffix = applySuffix;
}
/**
* Return the rollback script suffix (defaults to ddl so that it isn't picked up by FlywayDb).
*/
public String getRollbackSuffix() {
return rollbackSuffix;
}
/**
* Set the rollback script suffix (defaults to ddl so that it isn't picked up by FlywayDb).
*/
public void setRollbackSuffix(String rollbackSuffix) {
this.rollbackSuffix = rollbackSuffix;
}
/**
* Return true if the generated file comment should be included.
*/
@@ -256,7 +196,6 @@ public class DbMigrationConfig {
* into a single directory.
*/
public void singleDirectory() {
this.rollbackPath = "";
this.modelPath = "";
}
@@ -270,16 +209,13 @@ public class DbMigrationConfig {
singleDirectory();
} else {
modelPath = properties.get("migration.modelPath", modelPath);
rollbackPath = properties.get("migration.rollbackPath", rollbackPath);
}
applySuffix = properties.get("migration.applySuffix", applySuffix);
rollbackSuffix = properties.get("migration.rollbackSuffix", rollbackSuffix);
modelSuffix = properties.get("migration.modelSuffix", modelSuffix);
includeGeneratedFileComment = properties.getBoolean("migration.includeGeneratedFileComment", includeGeneratedFileComment);
generatePendingDrop = properties.get("migration.generatePendingDrop", generatePendingDrop);
platform = properties.getEnum(DbPlatformName.class, "migration.platform", platform);
suppressRollback = properties.getBoolean("migration.suppressRollback", suppressRollback);
generate = properties.getBoolean("migration.generate", generate);
version = properties.get("migration.version", version);
@@ -2,7 +2,6 @@ package com.avaje.ebean.dbmigration;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.dbmigration.model.CurrentModel;
import com.avaje.ebeaninternal.api.SpiEbeanPlugin;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import javax.persistence.PersistenceException;
@@ -30,8 +29,8 @@ public class DdlGenerator {
private final boolean createOnly;
private CurrentModel currentModel;
private String dropContent;
private String createContent;
private String dropAllContent;
private String createAllContent;
public DdlGenerator(SpiEbeanServer server, ServerConfig serverConfig) {
this.server = server;
@@ -84,18 +83,18 @@ public class DdlGenerator {
protected void runDropSql() throws IOException {
if (!createOnly) {
if (dropContent == null) {
dropContent = readFile(getDropFileName());
if (dropAllContent == null) {
dropAllContent = readFile(getDropFileName());
}
runScript(true, dropContent, getDropFileName());
runScript(true, dropAllContent, getDropFileName());
}
}
protected void runCreateSql() throws IOException {
if (createContent == null) {
createContent = readFile(getCreateFileName());
if (createAllContent == null) {
createAllContent = readFile(getCreateFileName());
}
runScript(false, createContent, getCreateFileName());
runScript(false, createAllContent, getCreateFileName());
}
protected void runInitSql() throws IOException {
@@ -132,8 +131,7 @@ public class DdlGenerator {
protected void writeDrop(String dropFile) {
try {
String c = generateDropDdl();
writeFile(dropFile, c);
writeFile(dropFile, generateDropAllDdl());
} catch (IOException e) {
throw new PersistenceException("Error generating Drop DDL", e);
}
@@ -142,28 +140,27 @@ public class DdlGenerator {
protected void writeCreate(String createFile) {
try {
String c = generateCreateDdl();
writeFile(createFile, c);
writeFile(createFile, generateCreateAllDdl());
} catch (IOException e) {
throw new PersistenceException("Error generating Create DDL", e);
}
}
protected String generateDropDdl() {
protected String generateDropAllDdl() {
try {
dropContent = currentModel().getDropDdl();
return dropContent;
dropAllContent = currentModel().getDropAllDdl();
return dropAllContent;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
protected String generateCreateDdl() {
protected String generateCreateAllDdl() {
try {
createContent = currentModel().getCreateDdl();
return createContent;
createAllContent = currentModel().getCreateDdl();
return createAllContent;
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -10,11 +10,6 @@ import com.avaje.ebean.dbmigration.model.ModelContainer;
*/
public class DdlWrite {
public enum Mode {
APPLY,
ROLLBACK
}
private final ModelContainer currentModel;
private final DdlBuffer applyDropDependencies;
@@ -25,11 +20,9 @@ public class DdlWrite {
private final DdlBuffer applyHistory;
private final DdlBuffer rollbackDropDependencies;
private final DdlBuffer dropAllForeignKeys;
private final DdlBuffer rollbackForeignKeys;
private final DdlBuffer rollback;
private final DdlBuffer dropAll;
/**
* Create without any configuration or current model (no history support).
@@ -47,9 +40,8 @@ public class DdlWrite {
this.apply = new BaseDdlBuffer(configuration);
this.applyForeignKeys = new BaseDdlBuffer(configuration);
this.applyHistory = new BaseDdlBuffer(configuration);
this.rollbackDropDependencies = new BaseDdlBuffer(configuration);
this.rollbackForeignKeys = new BaseDdlBuffer(configuration);
this.rollback = new BaseDdlBuffer(configuration);
this.dropAllForeignKeys = new BaseDdlBuffer(configuration);
this.dropAll = new BaseDdlBuffer(configuration);
}
/**
@@ -73,52 +65,6 @@ public class DdlWrite {
&& applyDropDependencies.getBuffer().isEmpty();
}
/**
* Return true if the apply rollback buffers are all empty.
*/
public boolean isApplyRollbackEmpty() {
return rollback.getBuffer().isEmpty()
&& rollbackForeignKeys.getBuffer().isEmpty()
&& rollbackDropDependencies.getBuffer().isEmpty();
}
/**
* Return the apply or rollback buffer.
*/
public DdlBuffer buffer(Mode mode) {
switch (mode) {
case APPLY: return apply();
case ROLLBACK: return rollback();
default:
throw new IllegalStateException("Invalid mode" + mode);
}
}
/**
* Return the apply or rollback buffer.
*/
public DdlBuffer historyBuffer(Mode mode) {
switch (mode) {
case APPLY: return applyHistory();
case ROLLBACK: return rollback();
default:
throw new IllegalStateException("Invalid mode" + mode);
}
}
/**
* Return the apply or rollback drop dependencies buffer.
*/
public DdlBuffer dropDependencies(Mode mode) {
switch (mode) {
case APPLY: return applyDropDependencies();
case ROLLBACK: return rollbackDropDependencies();
default:
throw new IllegalStateException("Invalid mode" + mode);
}
}
/**
* Return the buffer that APPLY DDL is written to.
*/
@@ -151,32 +97,17 @@ public class DdlWrite {
}
/**
* Return the buffer that rollback executes early to drop dependencies like views.
* Return the buffer used for the 'drop all DDL' for dropping foreign keys and associated indexes.
*/
public DdlBuffer rollbackDropDependencies() {
return rollbackDropDependencies;
public DdlBuffer dropAllForeignKeys() {
return dropAllForeignKeys;
}
/**
* Return the buffer that ROLLBACK DDL is written to for foreign keys and associated indexes.
* Return the buffer used for the 'drop all DDL' to drop tables, views and history triggers etc.
*/
public DdlBuffer rollbackForeignKeys() {
return rollbackForeignKeys;
}
/**
* Return the buffer that ROLLBACK DDL is written to which is considered safe to run when
* apply changes fail to execute. This will reverse the apply changes typically dropping
* newly created tables, foreign keys etc.
* <p>
* When apply changes are made against DB's that support transactional DDL you could argue
* that these rollback statements are not necessary.
* <p>
* Note that statements added to this rollback buffer are executed after foreign key rollback
* has been executed.
*/
public DdlBuffer rollback() {
return rollback;
public DdlBuffer dropAll() {
return dropAll;
}
}
@@ -140,7 +140,7 @@ public class BaseTableDdl implements TableDdl {
// add drop table to the rollback buffer - do this before
// we drop the related sequence (if sequences are used)
dropTable(writer.rollback(), tableName);
dropTable(writer.dropAll(), tableName);
if (useSequence) {
String pkCol = pk.get(0).getName();
@@ -149,7 +149,7 @@ public class BaseTableDdl implements TableDdl {
// add blank line for a bit of whitespace between tables
apply.end();
writer.rollback().end();
writer.dropAll().end();
writeAddForeignKeys(writer, createTable);
@@ -204,7 +204,7 @@ public class BaseTableDdl implements TableDdl {
.append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames))
.endOfStatement();
write.rollbackForeignKeys()
write.dropAllForeignKeys()
.append(platformDdl.dropIndex(uqName, tableName))
.endOfStatement();
}
@@ -225,7 +225,7 @@ public class BaseTableDdl implements TableDdl {
String createSeq = platformDdl.createSequence(seqName, initial, allocate);
if (createSeq != null) {
writer.apply().append(createSeq).newLine();
writer.rollback().append(platformDdl.dropSequence(seqName)).endOfStatement();
writer.dropAll().append(platformDdl.dropSequence(seqName)).endOfStatement();
}
}
@@ -295,15 +295,15 @@ public class BaseTableDdl implements TableDdl {
fkeyBuffer.end();
write.rollbackForeignKeys()
write.dropAllForeignKeys()
.append(platformDdl.alterTableDropForeignKey(tableName, fkName)).endOfStatement();
if (indexName != null) {
write.rollbackForeignKeys()
write.dropAllForeignKeys()
.append(platformDdl.dropIndex(indexName, tableName)).endOfStatement();
}
write.rollbackForeignKeys().end();
write.dropAllForeignKeys().end();
}
@@ -471,7 +471,7 @@ public class BaseTableDdl implements TableDdl {
.append(platformDdl.createIndex(createIndex.getIndexName(), createIndex.getTableName(), cols))
.endOfStatement();
writer.rollback()
writer.dropAll()
.append(platformDdl.dropIndex(createIndex.getIndexName(), createIndex.getTableName()))
.endOfStatement();
}
@@ -520,7 +520,6 @@ public class BaseTableDdl implements TableDdl {
List<Column> columns = addColumn.getColumn();
for (Column column : columns) {
alterTableAddColumn(writer.apply(), tableName, column, false);
alterTableDropColumn(writer.rollback(), tableName, column.getName());
}
if (isTrue(addColumn.isWithHistory())) {
@@ -529,13 +528,11 @@ public class BaseTableDdl implements TableDdl {
for (Column column : columns) {
regenerateHistoryTriggers(tableName, HistoryTableUpdate.Change.ADD, column.getName());
alterTableAddColumn(writer.apply(), historyTable, column, true);
alterTableDropColumn(writer.rollback(), historyTable, column.getName());
}
}
// add a bit of whitespace
writer.apply().end();
writer.rollback().end();
}
/**
@@ -642,21 +639,6 @@ public class BaseTableDdl implements TableDdl {
if (hasValue(ddl)) {
writer.apply().append(ddl).endOfStatement();
// reverse and generate the rollback statement
String currentType = alter.getCurrentType();
String type = alter.getType();
Boolean currentNotnull = alter.isCurrentNotnull();
Boolean notnull = alter.isNotnull();
alter.setCurrentType(type);
alter.setType(currentType);
alter.setNotnull(currentNotnull);
alter.setCurrentNotnull(notnull);
// write the rollback
ddl = platformDdl.alterColumnBaseAttributes(alter);
writer.rollback().append(ddl).endOfStatement();
if (isTrue(alter.isWithHistory()) && alter.getType() != null) {
// mysql and sql server column type change allowing nulls in the history table column
AlterColumn alterHistoryColumn = new AlterColumn();
@@ -667,11 +649,6 @@ public class BaseTableDdl implements TableDdl {
// write the apply to history table
writer.apply().append(histColumnDdl).endOfStatement();
// write the rollback from history table
alterHistoryColumn.setType(currentType);
histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn);
writer.rollback().append(histColumnDdl).endOfStatement();
}
}
}
@@ -689,8 +666,6 @@ public class BaseTableDdl implements TableDdl {
String ddl = platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isNotnull());
if (hasValue(ddl)) {
writer.apply().append(ddl).endOfStatement();
ddl = platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isCurrentNotnull());
writer.rollback().append(ddl).endOfStatement();
}
}
@@ -699,14 +674,10 @@ public class BaseTableDdl implements TableDdl {
String ddl = platformDdl.alterColumnType(alter.getTableName(), alter.getColumnName(), alter.getType());
if (hasValue(ddl)) {
writer.apply().append(ddl).endOfStatement();
ddl = platformDdl.alterColumnType(alter.getTableName(), alter.getColumnName(), alter.getCurrentType());
writer.rollback().append(ddl).endOfStatement();
if (isTrue(alter.isWithHistory())) {
// apply same type change to matching column in the history table
ddl = platformDdl.alterColumnType(historyTable(alter.getTableName()), alter.getColumnName(), alter.getType());
writer.apply().append(ddl).endOfStatement();
ddl = platformDdl.alterColumnType(historyTable(alter.getTableName()), alter.getColumnName(), alter.getCurrentType());
writer.rollback().append(ddl).endOfStatement();
}
}
}
@@ -762,7 +733,7 @@ public class BaseTableDdl implements TableDdl {
.append(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols))
.endOfStatement();
writer.rollbackForeignKeys()
writer.dropAllForeignKeys()
.append(platformDdl.dropIndex(uqName, alter.getTableName()))
.endOfStatement();
}
@@ -69,31 +69,17 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
*/
protected void updateTriggers(DdlWrite writer, MTable table, HistoryTableUpdate update) throws IOException {
DbTriggerUpdate triggerUpdate = createDbTriggerUpdate(writer, table);
writer.applyHistory().append("-- changes: ").append(update.description()).newLine();
String description = update.description();
List<String> includedColumns = columnNamesForApply(table);
DdlBuffer apply = writer.applyHistory();
apply.append("-- changes: ").append(description).newLine();
triggerUpdate.prepare(DdlWrite.Mode.APPLY, includedColumns);
updateHistoryTriggers(triggerUpdate);
// put a reverted version into the rollback buffer
update.toRevertedColumns(includedColumns);
DdlBuffer rollback = writer.rollback();
rollback.append("-- revert changes: ").append(description).newLine();
triggerUpdate.prepare(DdlWrite.Mode.ROLLBACK, includedColumns);
updateHistoryTriggers(triggerUpdate);
updateHistoryTriggers(createDbTriggerUpdate(writer, table));
}
protected DbTriggerUpdate createDbTriggerUpdate(DdlWrite writer, MTable table) {
List<String> columns = columnNamesForApply(table);
String baseTableName = table.getName();
String historyTableName = historyTableName(baseTableName);
return new DbTriggerUpdate(baseTableName, historyTableName, writer);
return new DbTriggerUpdate(baseTableName, historyTableName, writer, columns);
}
@Override
@@ -124,9 +110,8 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
String baseTable = table.getName();
String whenCreatedColumn = table.getWhenCreatedColumn();
// rollback changes in appropriate order
dropTriggers(writer.rollback(), baseTable);
dropHistoryTableEtc(writer.rollback(), baseTable);
dropTriggers(writer.dropAll(), baseTable);
dropHistoryTableEtc(writer.dropAll(), baseTable);
addHistoryTable(writer, table, whenCreatedColumn);
createStoredFunction(writer, table);
@@ -295,7 +280,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
* the column.
* </p>
*/
protected List<String> columnNamesForApply(MTable table) throws IOException {
protected List<String> columnNamesForApply(MTable table) {
return table.allHistoryColumns(true);
}
@@ -16,36 +16,27 @@ public class DbTriggerUpdate {
private final DdlWrite writer;
private DdlWrite.Mode mode;
private final List<String> columns;
private List<String> includedColumns;
public DbTriggerUpdate(String baseTableName, String historyTableName, DdlWrite writer) {
public DbTriggerUpdate(String baseTableName, String historyTableName, DdlWrite writer, List<String> columns) {
this.baseTableName = baseTableName;
this.historyTableName = historyTableName;
this.writer = writer;
}
/**
* Prepare for use given the mode and columns included in history.
*/
public void prepare(DdlWrite.Mode mode, List<String> includedColumns) {
this.mode = mode;
this.includedColumns = includedColumns;
this.columns = columns;
}
/**
* Return the appropriate buffer for the current mode.
*/
public DdlBuffer historyBuffer() {
return writer.historyBuffer(mode);
return writer.applyHistory();
}
/**
* Return the appropriate drop dependency buffer for the current mode.
*/
public DdlBuffer dropDependencyBuffer() {
return writer.dropDependencies(mode);
return writer.applyDropDependencies();
}
/**
@@ -66,7 +57,7 @@ public class DbTriggerUpdate {
* Return the included columns.
*/
public List<String> getColumns() {
return includedColumns;
return columns;
}
}
@@ -39,22 +39,6 @@ public class HistoryTableUpdate {
return change.name().toLowerCase()+" "+column;
}
private void revert(List<String> includedColumns) {
switch (change) {
case ADD:
case INCLUDE: {
includedColumns.remove(column);
break;
}
case EXCLUDE:
case DROP: {
includedColumns.add(column);
break;
}
default:
throw new IllegalStateException("Unexpected change "+change);
}
}
}
private final String baseTable;
@@ -76,17 +60,6 @@ public class HistoryTableUpdate {
return columnChanges.toString();
}
/**
* Reverse the apply changes which equates to removing any newly added or
* included columns.
*/
public void toRevertedColumns(List<String> includedColumns) {
for (Column columnChange : columnChanges) {
columnChange.revert(includedColumns);
}
}
/**
* Add a comment for column added, dropped, included or excluded.
*/
@@ -27,8 +27,6 @@ public class MySqlHistoryDdl extends DbTriggerBasedHistoryDdl {
DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
update.prepare(DdlWrite.Mode.APPLY, columnNamesForApply(table));
addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
}
@@ -117,13 +117,13 @@ public class CurrentModel {
/**
* Return the 'Drop' DDL.
*/
public String getDropDdl() throws IOException {
public String getDropAllDdl() throws IOException {
createDdl();
StringBuilder ddl = new StringBuilder(2000);
ddl.append(write.rollbackForeignKeys().getBuffer());
ddl.append(write.rollback().getBuffer());
ddl.append(write.dropAllForeignKeys().getBuffer());
ddl.append(write.dropAll().getBuffer());
return ddl.toString();
}
@@ -74,18 +74,7 @@ public class PlatformDdlWriter {
} finally {
applyWriter.close();
}
if (!config.isSuppressRollback() && !write.isApplyRollbackEmpty()) {
FileWriter applyRollbackWriter = createWriter(resourcePath, fullVersion, config.getRollbackPath(), config.getRollbackSuffix());
try {
writeApplyRollbackDdl(applyRollbackWriter, write);
applyRollbackWriter.flush();
} finally {
applyRollbackWriter.close();
}
}
}
}
protected FileWriter createWriter(File path, String fullVersion, String subPath, String suffix) throws IOException {
@@ -123,18 +112,6 @@ public class PlatformDdlWriter {
writer.append(write.applyHistory().getBuffer());
}
/**
* Write the 'Rollback' DDL buffers to the writer.
*/
protected void writeApplyRollbackDdl(Writer writer, DdlWrite write) throws IOException {
// merge the rollback buffers in the appropriate order
prependDropDependencies(writer, write.rollbackDropDependencies());
writer.append("-- reverse changes\n");
writer.append(write.rollbackForeignKeys().getBuffer());
writer.append(write.rollback().getBuffer());
}
private void prependDropDependencies(Writer writer, DdlBuffer buffer) throws IOException {
if (!buffer.isEmpty()) {
writer.append("-- drop dependencies\n");