mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#557 - DDL - DB Migration refactor - remove drop.ddl and use pendingDrops.
This commit is contained in:
@@ -61,11 +61,6 @@ public class DbMigrationConfig {
|
||||
*/
|
||||
protected String modelPath = "model";
|
||||
|
||||
/**
|
||||
* Subdirectory the drop ddl scripts go into.
|
||||
*/
|
||||
protected String dropPath = "drop";
|
||||
|
||||
/**
|
||||
* Subdirectory the rollback ddl scripts go into.
|
||||
*/
|
||||
@@ -76,11 +71,6 @@ public class DbMigrationConfig {
|
||||
*/
|
||||
protected String applySuffix = ".sql";
|
||||
|
||||
/**
|
||||
* Default drop script suffix to ddl so that it isn't picked up by FlywayDb.
|
||||
*/
|
||||
protected String dropSuffix = ".drop.ddl";
|
||||
|
||||
/**
|
||||
* Default rollback script suffix to ddl so that it isn't picked up by FlywayDb.
|
||||
*/
|
||||
@@ -90,6 +80,11 @@ public class DbMigrationConfig {
|
||||
|
||||
protected boolean includeGeneratedFileComment;
|
||||
|
||||
/**
|
||||
* The version of a pending drop that should be generated as the next migration.
|
||||
*/
|
||||
protected String generatePendingDrop;
|
||||
|
||||
/**
|
||||
* Return the DB platform to generate migration DDL for.
|
||||
*
|
||||
@@ -140,20 +135,6 @@ public class DbMigrationConfig {
|
||||
this.modelPath = modelPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relative path for the drop ddl scripts (defaults to drop).
|
||||
*/
|
||||
public String getDropPath() {
|
||||
return dropPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the relative path for the drop ddl scripts (defaults to drop).
|
||||
*/
|
||||
public void setDropPath(String dropPath) {
|
||||
this.dropPath = dropPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relative path for the rollback ddl scripts (defaults to rollback).
|
||||
*/
|
||||
@@ -210,20 +191,6 @@ public class DbMigrationConfig {
|
||||
this.applySuffix = applySuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop script suffix (defaults to ddl so that it isn't picked up by FlywayDb).
|
||||
*/
|
||||
public String getDropSuffix() {
|
||||
return dropSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the drop script suffix (defaults to ddl so that it isn't picked up by FlywayDb).
|
||||
*/
|
||||
public void setDropSuffix(String dropSuffix) {
|
||||
this.dropSuffix = dropSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the rollback script suffix (defaults to ddl so that it isn't picked up by FlywayDb).
|
||||
*/
|
||||
@@ -252,6 +219,20 @@ public class DbMigrationConfig {
|
||||
this.includeGeneratedFileComment = includeGeneratedFileComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the migration version (or "next") to generate pending drops for.
|
||||
*/
|
||||
public String getGeneratePendingDrop() {
|
||||
return generatePendingDrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the migration version (or "next") to generate pending drops for.
|
||||
*/
|
||||
public void setGeneratePendingDrop(String generatePendingDrop) {
|
||||
this.generatePendingDrop = generatePendingDrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the migration version.
|
||||
* <p>
|
||||
@@ -275,7 +256,6 @@ public class DbMigrationConfig {
|
||||
* into a single directory.
|
||||
*/
|
||||
public void singleDirectory() {
|
||||
this.dropPath = "";
|
||||
this.rollbackPath = "";
|
||||
this.modelPath = "";
|
||||
}
|
||||
@@ -291,13 +271,12 @@ public class DbMigrationConfig {
|
||||
} else {
|
||||
modelPath = properties.get("migration.modelPath", modelPath);
|
||||
rollbackPath = properties.get("migration.rollbackPath", rollbackPath);
|
||||
dropPath = properties.get("migration.dropPath", dropPath);
|
||||
}
|
||||
applySuffix = properties.get("migration.applySuffix", applySuffix);
|
||||
dropSuffix = properties.get("migration.dropSuffix", dropSuffix);
|
||||
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);
|
||||
@@ -324,7 +303,6 @@ public class DbMigrationConfig {
|
||||
return generate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by EbeanServer on start.
|
||||
*
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.avaje.ebean.dbmigration.migrationreader.MigrationXmlWriter;
|
||||
import com.avaje.ebean.dbmigration.model.CurrentModel;
|
||||
import com.avaje.ebean.dbmigration.model.MConfiguration;
|
||||
import com.avaje.ebean.dbmigration.model.MigrationModel;
|
||||
import com.avaje.ebean.dbmigration.model.MigrationVersion;
|
||||
import com.avaje.ebean.dbmigration.model.ModelContainer;
|
||||
import com.avaje.ebean.dbmigration.model.ModelDiff;
|
||||
import com.avaje.ebean.dbmigration.model.PlatformDdlWriter;
|
||||
@@ -201,46 +202,15 @@ public class DbMigration {
|
||||
if (!online) {
|
||||
DbOffline.setRunningMigration();
|
||||
}
|
||||
|
||||
setDefaults();
|
||||
|
||||
try {
|
||||
Request request = createRequest();
|
||||
|
||||
File migrationDir = getMigrationDirectory();
|
||||
File modelDir = getModelDirectory(migrationDir);
|
||||
|
||||
MigrationModel migrationModel = new MigrationModel(modelDir, migrationConfig.getModelSuffix());
|
||||
ModelContainer migrated = migrationModel.read();
|
||||
|
||||
CurrentModel currentModel = new CurrentModel(server, constraintNaming);
|
||||
ModelContainer current = currentModel.read();
|
||||
|
||||
ModelDiff diff = new ModelDiff(migrated);
|
||||
diff.compareTo(current);
|
||||
|
||||
if (diff.isEmpty()) {
|
||||
logger.info("no changes detected - no migration written");
|
||||
return;
|
||||
}
|
||||
|
||||
// there were actually changes to write
|
||||
Migration dbMigration = diff.getMigration();
|
||||
|
||||
String fullVersion = getFullVersion(migrationModel);
|
||||
|
||||
logger.info("generating migration:{}", fullVersion);
|
||||
if (!writeMigrationXml(dbMigration, modelDir, fullVersion)) {
|
||||
logger.warn("migration already exists, not generating DDL");
|
||||
|
||||
String pendingVersion = generatePendingDrop();
|
||||
if (pendingVersion != null) {
|
||||
generatePendingDrop(request, pendingVersion);
|
||||
} else {
|
||||
if (databasePlatform != null) {
|
||||
// writer needs the current model to provide table/column details for
|
||||
// history ddl generation (triggers, history tables etc)
|
||||
DdlWrite write = new DdlWrite(new MConfiguration(), current);
|
||||
PlatformDdlWriter writer = createDdlWriter(databasePlatform, "");
|
||||
writer.processMigration(dbMigration, write, migrationDir , fullVersion);
|
||||
}
|
||||
writeExtraPlatformDdl(fullVersion, currentModel, dbMigration, migrationDir);
|
||||
generateDiff(request);
|
||||
}
|
||||
|
||||
} finally {
|
||||
@@ -250,10 +220,127 @@ public class DbMigration {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDiff(Request request) throws IOException {
|
||||
|
||||
if (request.hasPendingDrops()) {
|
||||
logger.info("Pending un-applied drops in versions {}", request.getPendingDrops());
|
||||
}
|
||||
|
||||
ModelDiff diff = request.createDiff();
|
||||
if (diff.isEmpty()) {
|
||||
logger.info("no changes detected - no migration written");
|
||||
} else {
|
||||
// there were actually changes to write
|
||||
generateMigration(request, diff.getMigration(), null);
|
||||
}
|
||||
}
|
||||
|
||||
private void generatePendingDrop(Request request, String pendingVersion) throws IOException {
|
||||
|
||||
Migration migration = request.migrationForPendingDrop(pendingVersion);
|
||||
|
||||
generateMigration(request, migration, pendingVersion);
|
||||
if (request.hasPendingDrops()) {
|
||||
logger.info("... remaining pending un-applied drops in versions {}", request.getPendingDrops());
|
||||
}
|
||||
}
|
||||
|
||||
private Request createRequest() {
|
||||
return new Request();
|
||||
}
|
||||
|
||||
private class Request {
|
||||
|
||||
final File migrationDir;
|
||||
final File modelDir;
|
||||
final MigrationModel migrationModel;
|
||||
final CurrentModel currentModel;
|
||||
final ModelContainer migrated;
|
||||
final ModelContainer current;
|
||||
|
||||
private Request() {
|
||||
this.migrationDir = getMigrationDirectory();
|
||||
this.modelDir = getModelDirectory(migrationDir);
|
||||
this.migrationModel = new MigrationModel(modelDir, migrationConfig.getModelSuffix());
|
||||
this.migrated = migrationModel.read();
|
||||
this.currentModel = new CurrentModel(server, constraintNaming);
|
||||
this.current = currentModel.read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there are pending un-applied drops.
|
||||
*/
|
||||
public boolean hasPendingDrops() {
|
||||
return migrated.hasPendingDrops();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the migration for the pending drops for a given version.
|
||||
*/
|
||||
public Migration migrationForPendingDrop(String pendingVersion) {
|
||||
|
||||
Migration migration = migrated.migrationForPendingDrop(pendingVersion);
|
||||
|
||||
// register any remaining pending drops
|
||||
migrated.registerPendingHistoryDropColumns(current);
|
||||
return migration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of versions that have pending un-applied drops.
|
||||
*/
|
||||
public List<String> getPendingDrops() {
|
||||
return migrated.getPendingDrops();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an return the diff of the current model to the migration model.
|
||||
*/
|
||||
public ModelDiff createDiff() {
|
||||
ModelDiff diff = new ModelDiff(migrated);
|
||||
diff.compareTo(current);
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateMigration(Request request, Migration dbMigration, String dropsFor) throws IOException {
|
||||
|
||||
String fullVersion = getFullVersion(request.migrationModel, dropsFor);
|
||||
|
||||
logger.info("generating migration:{}", fullVersion);
|
||||
if (!writeMigrationXml(dbMigration, request.modelDir, fullVersion)) {
|
||||
logger.warn("migration already exists, not generating DDL");
|
||||
|
||||
} else {
|
||||
if (databasePlatform != null) {
|
||||
// writer needs the current model to provide table/column details for
|
||||
// history ddl generation (triggers, history tables etc)
|
||||
DdlWrite write = new DdlWrite(new MConfiguration(), request.current);
|
||||
PlatformDdlWriter writer = createDdlWriter(databasePlatform, "");
|
||||
writer.processMigration(dbMigration, write, request.migrationDir , fullVersion);
|
||||
}
|
||||
writeExtraPlatformDdl(fullVersion, request.currentModel, dbMigration, request.migrationDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the next pending drop changeSet should be generated as the next migration.
|
||||
*/
|
||||
private String generatePendingDrop() {
|
||||
|
||||
String nextDrop = System.getProperty("ddl.migration.pendingDrop");
|
||||
if (nextDrop != null) {
|
||||
return nextDrop;
|
||||
}
|
||||
return migrationConfig.getGeneratePendingDrop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full version for the migration being generated.
|
||||
*
|
||||
* The full version can contain a comment suffix after a "__" double underscore.
|
||||
*/
|
||||
private String getFullVersion(MigrationModel migrationModel) {
|
||||
private String getFullVersion(MigrationModel migrationModel, String dropsFor) {
|
||||
|
||||
String version = migrationConfig.getVersion();
|
||||
if (version == null) {
|
||||
@@ -261,10 +348,14 @@ public class DbMigration {
|
||||
}
|
||||
|
||||
String fullVersion = version;
|
||||
if (migrationConfig.getName() != null) {
|
||||
fullVersion += "__" + toUnderScore(migrationConfig.getName());
|
||||
|
||||
String name = migrationConfig.getName();
|
||||
if (name != null) {
|
||||
fullVersion += "__" + toUnderScore(name);
|
||||
} else if (dropsFor != null) {
|
||||
fullVersion += "__" + toUnderScore("dropsFor_" + MigrationVersion.trim(dropsFor));
|
||||
|
||||
} else if (version.equals(initialVersion)) {
|
||||
fullVersion += "__initial";
|
||||
}
|
||||
return fullVersion;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,7 @@ public class DdlWrite {
|
||||
|
||||
public enum Mode {
|
||||
APPLY,
|
||||
ROLLBACK,
|
||||
DROP
|
||||
ROLLBACK
|
||||
}
|
||||
|
||||
private final ModelContainer currentModel;
|
||||
@@ -32,28 +31,6 @@ public class DdlWrite {
|
||||
|
||||
private final DdlBuffer rollback;
|
||||
|
||||
/**
|
||||
* For DDL that drops tables and columns etc.
|
||||
*
|
||||
* This DDL typically can not run automatically in production as there is most commonly
|
||||
* existing servers running the application using these tables and columns. Typically
|
||||
* these drop statements may be executed AFTER all the servers in the application have
|
||||
* migrated onto new code.
|
||||
*/
|
||||
private final DdlBuffer drop;
|
||||
|
||||
/**
|
||||
* For use when History is turned off for a base table or history is no longer
|
||||
* desired on specific columns. This DDL should typically execute manually after review
|
||||
* by DBA's.
|
||||
*/
|
||||
private final DdlBuffer dropHistory;
|
||||
|
||||
/**
|
||||
* Buffer used to drop dependencies early in the 'drop script'.
|
||||
*/
|
||||
private final DdlBuffer dropDropDependencies;
|
||||
|
||||
/**
|
||||
* Create without any configuration or current model (no history support).
|
||||
*/
|
||||
@@ -73,9 +50,6 @@ public class DdlWrite {
|
||||
this.rollbackDropDependencies = new BaseDdlBuffer(configuration);
|
||||
this.rollbackForeignKeys = new BaseDdlBuffer(configuration);
|
||||
this.rollback = new BaseDdlBuffer(configuration);
|
||||
this.drop = new BaseDdlBuffer(configuration);
|
||||
this.dropHistory = new BaseDdlBuffer(configuration);
|
||||
this.dropDropDependencies = new BaseDdlBuffer(configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +89,6 @@ public class DdlWrite {
|
||||
switch (mode) {
|
||||
case APPLY: return apply();
|
||||
case ROLLBACK: return rollback();
|
||||
case DROP: return drop();
|
||||
default:
|
||||
throw new IllegalStateException("Invalid mode" + mode);
|
||||
}
|
||||
@@ -128,7 +101,6 @@ public class DdlWrite {
|
||||
switch (mode) {
|
||||
case APPLY: return applyHistory();
|
||||
case ROLLBACK: return rollback();
|
||||
case DROP: return dropHistory();
|
||||
default:
|
||||
throw new IllegalStateException("Invalid mode" + mode);
|
||||
}
|
||||
@@ -142,20 +114,11 @@ public class DdlWrite {
|
||||
switch (mode) {
|
||||
case APPLY: return applyDropDependencies();
|
||||
case ROLLBACK: return rollbackDropDependencies();
|
||||
case DROP: return dropDropDependencies();
|
||||
default:
|
||||
throw new IllegalStateException("Invalid mode" + mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true the drop buffers are empty.
|
||||
*/
|
||||
public boolean isDropEmpty() {
|
||||
return drop.getBuffer().isEmpty() && dropHistory.getBuffer().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that APPLY DDL is written to.
|
||||
*/
|
||||
@@ -216,26 +179,8 @@ public class DdlWrite {
|
||||
return rollback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that destructive changes are written to. This is typically drop table and
|
||||
* drop column.
|
||||
*/
|
||||
public DdlBuffer drop() {
|
||||
return drop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that is used when history is no longer required on a table or specific columns.
|
||||
*/
|
||||
public DdlBuffer dropHistory() {
|
||||
return dropHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that executes early for 'drop' script.
|
||||
*/
|
||||
public DdlBuffer dropDropDependencies() {
|
||||
return dropDropDependencies;
|
||||
return apply;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-36
@@ -71,37 +71,23 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
DbTriggerUpdate triggerUpdate = createDbTriggerUpdate(writer, table);
|
||||
|
||||
if (update.hasApplyChanges()) {
|
||||
// includes add, include and exclude column changes
|
||||
String description = update.description();
|
||||
List<String> includedColumns = columnNamesForApply(table);
|
||||
|
||||
String applyChangeDescription = update.descriptionForApply();
|
||||
List<String> includedColumns = columnNamesForApply(table);
|
||||
DdlBuffer apply = writer.applyHistory();
|
||||
apply.append("-- changes: ").append(description).newLine();
|
||||
|
||||
DdlBuffer apply = writer.applyHistory();
|
||||
apply.append("-- changes: ").append(applyChangeDescription).newLine();
|
||||
triggerUpdate.prepare(DdlWrite.Mode.APPLY, includedColumns);
|
||||
updateHistoryTriggers(triggerUpdate);
|
||||
|
||||
triggerUpdate.prepare(DdlWrite.Mode.APPLY, includedColumns);
|
||||
updateHistoryTriggers(triggerUpdate);
|
||||
// put a reverted version into the rollback buffer
|
||||
update.toRevertedColumns(includedColumns);
|
||||
|
||||
// put a reverted version into the rollback buffer
|
||||
update.toRevertedColumns(includedColumns);
|
||||
DdlBuffer rollback = writer.rollback();
|
||||
rollback.append("-- revert changes: ").append(description).newLine();
|
||||
|
||||
DdlBuffer rollback = writer.rollback();
|
||||
rollback.append("-- revert changes: ").append(applyChangeDescription).newLine();
|
||||
|
||||
triggerUpdate.prepare(DdlWrite.Mode.ROLLBACK, includedColumns);
|
||||
updateHistoryTriggers(triggerUpdate);//writer, DdlWrite.Mode.ROLLBACK, baseTableName, historyTableName, includedColumns);
|
||||
}
|
||||
|
||||
if (update.hasDropChanges()) {
|
||||
// effectively applies the dropped columns changes to history triggers
|
||||
|
||||
DdlBuffer drop = writer.dropHistory();
|
||||
drop.append("-- changes: ").append(update.descriptionForDrop()).newLine();
|
||||
|
||||
triggerUpdate.prepare(DdlWrite.Mode.DROP, columnNamesForDrop(table));
|
||||
updateHistoryTriggers(triggerUpdate);//writer, DdlWrite.Mode.DROP, baseTableName, historyTableName, columnNamesForDrop(table));
|
||||
}
|
||||
triggerUpdate.prepare(DdlWrite.Mode.ROLLBACK, includedColumns);
|
||||
updateHistoryTriggers(triggerUpdate);
|
||||
}
|
||||
|
||||
protected DbTriggerUpdate createDbTriggerUpdate(DdlWrite writer, MTable table) {
|
||||
@@ -116,11 +102,10 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
String baseTable = dropHistoryTable.getBaseTable();
|
||||
|
||||
// drop in appropriate order
|
||||
dropTriggers(writer.dropHistory(), baseTable);
|
||||
dropHistoryTableEtc(writer.dropHistory(), baseTable);
|
||||
dropTriggers(writer.applyDropDependencies(), baseTable);
|
||||
dropHistoryTableEtc(writer.applyDropDependencies(), baseTable);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
|
||||
@@ -315,11 +300,4 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
return table.allHistoryColumns(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column names included in history for the drop script.
|
||||
*/
|
||||
protected List<String> columnNamesForDrop(MTable table) throws IOException {
|
||||
|
||||
return table.allHistoryColumns(false);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-59
@@ -10,7 +10,6 @@ import java.util.List;
|
||||
*/
|
||||
public class HistoryTableUpdate {
|
||||
|
||||
|
||||
/**
|
||||
* Column change type.
|
||||
*/
|
||||
@@ -32,12 +31,12 @@ public class HistoryTableUpdate {
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return change.name().toLowerCase()+" "+column;
|
||||
public String toString() {
|
||||
return description();
|
||||
}
|
||||
|
||||
private boolean isChangeFor(boolean apply) {
|
||||
return apply ? change != Change.DROP : change == Change.DROP;
|
||||
public String description() {
|
||||
return change.name().toLowerCase()+" "+column;
|
||||
}
|
||||
|
||||
private void revert(List<String> includedColumns) {
|
||||
@@ -47,12 +46,11 @@ public class HistoryTableUpdate {
|
||||
includedColumns.remove(column);
|
||||
break;
|
||||
}
|
||||
case EXCLUDE: {
|
||||
case EXCLUDE:
|
||||
case DROP: {
|
||||
includedColumns.add(column);
|
||||
break;
|
||||
}
|
||||
case DROP:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected change "+change);
|
||||
}
|
||||
@@ -70,60 +68,12 @@ public class HistoryTableUpdate {
|
||||
this.baseTable = baseTable;
|
||||
}
|
||||
|
||||
private boolean isChangeFor(boolean apply) {
|
||||
for (Column columnChange : columnChanges) {
|
||||
if (columnChange.isChangeFor(apply)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the change includes apply changes (ADD, INCLUDE, EXCLUDE).
|
||||
*/
|
||||
public boolean hasApplyChanges() {
|
||||
return isChangeFor(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the change includes DROP column.
|
||||
*/
|
||||
public boolean hasDropChanges() {
|
||||
return isChangeFor(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of the changes that cause the history trigger/function
|
||||
* to be regenerated (added, included or excluded columns).
|
||||
* to be regenerated (added, included, excluded and dropped columns).
|
||||
*/
|
||||
public String descriptionForApply() {
|
||||
return descriptionFor(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of the changes that cause the history trigger/function
|
||||
* to be regenerated in the drop script (dropped columns only).
|
||||
*/
|
||||
public String descriptionForDrop() {
|
||||
return descriptionFor(false);
|
||||
}
|
||||
|
||||
private String descriptionFor(boolean apply) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(90);
|
||||
boolean first = true;
|
||||
for (Column column : columnChanges) {
|
||||
if (column.isChangeFor(apply)) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(column.description());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
public String description() {
|
||||
return columnChanges.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* </choice>
|
||||
* </sequence>
|
||||
* <attribute name="type" use="required" type="{http://ebean-orm.github.io/xml/ns/dbmigration}changeSetType" />
|
||||
* <attribute name="dropsFor" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="generated" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="author" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="comment" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
@@ -62,6 +63,8 @@ public class ChangeSet {
|
||||
protected List<Object> changeSetChildren;
|
||||
@XmlAttribute(name = "type", required = true)
|
||||
protected ChangeSetType type;
|
||||
@XmlAttribute(name = "dropsFor")
|
||||
protected String dropsFor;
|
||||
@XmlAttribute(name = "generated")
|
||||
protected Boolean generated;
|
||||
@XmlAttribute(name = "author")
|
||||
@@ -134,6 +137,30 @@ public class ChangeSet {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dropsFor property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getDropsFor() {
|
||||
return dropsFor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dropsFor property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setDropsFor(String value) {
|
||||
this.dropsFor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the generated property.
|
||||
*
|
||||
|
||||
@@ -15,7 +15,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <simpleType name="changeSetType">
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
|
||||
* <enumeration value="apply"/>
|
||||
* <enumeration value="drop"/>
|
||||
* <enumeration value="pendingDrops"/>
|
||||
* <enumeration value="baseline"/>
|
||||
* </restriction>
|
||||
* </simpleType>
|
||||
@@ -28,8 +28,8 @@ public enum ChangeSetType {
|
||||
|
||||
@XmlEnumValue("apply")
|
||||
APPLY("apply"),
|
||||
@XmlEnumValue("drop")
|
||||
DROP("drop"),
|
||||
@XmlEnumValue("pendingDrops")
|
||||
PENDING_DROPS("pendingDrops"),
|
||||
@XmlEnumValue("baseline")
|
||||
BASELINE("baseline");
|
||||
private final String value;
|
||||
|
||||
@@ -132,14 +132,14 @@ public class MTable {
|
||||
*/
|
||||
public MTable createDraftTable() {
|
||||
|
||||
draftTable = new MTable(name+"_draft");
|
||||
draftTable = new MTable(name + "_draft");
|
||||
draftTable.draft = true;
|
||||
draftTable.whenCreatedColumn = whenCreatedColumn;
|
||||
// compoundKeys
|
||||
// compoundUniqueConstraints
|
||||
draftTable.identityType = identityType;
|
||||
|
||||
for (MColumn col: allColumns()) {
|
||||
for (MColumn col : allColumns()) {
|
||||
draftTable.addColumn(col.copyForDraft());
|
||||
}
|
||||
|
||||
@@ -546,20 +546,19 @@ public class MTable {
|
||||
// These dropColumns should occur on the history
|
||||
// table as well as the base table
|
||||
dropColumn.setWithHistory(Boolean.TRUE);
|
||||
newTable.registerDroppedColumn(existingColumn.getName(), columnPosition);
|
||||
}
|
||||
|
||||
modelDiff.addDropColumn(dropColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a dropped column with it's previous column position.
|
||||
* We need this for history triggers and views as we don't actually drop the
|
||||
* column until the 'drop script' is run so the 'apply script' for history changes
|
||||
* still needs to include the columns that are going to be dropped.
|
||||
* Register a pending un-applied drop column.
|
||||
* <p>
|
||||
* This means this column still needs to be included in history views/triggers etc even
|
||||
* though it is not part of the current model.
|
||||
*/
|
||||
protected void registerDroppedColumn(String name, int columnPosition) {
|
||||
droppedColumns.add(new DroppedColumn(name, columnPosition));
|
||||
public void registerPendingDropColumn(String columnName) {
|
||||
droppedColumns.add(new DroppedColumn(columnName, 100));
|
||||
}
|
||||
|
||||
private static class DroppedColumn implements Comparable<DroppedColumn> {
|
||||
@@ -573,7 +572,7 @@ public class MTable {
|
||||
|
||||
@Override
|
||||
public int compareTo(DroppedColumn o) {
|
||||
return Integer.compare(o.columnPosition, columnPosition);
|
||||
return (o.columnPosition < columnPosition) ? -1 : ((o.columnPosition == columnPosition) ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,7 +587,7 @@ public class MTable {
|
||||
/**
|
||||
* Check if there are duplicate foreign keys.
|
||||
* <p>
|
||||
* This can occur when an ManyToMany relates back to itself.
|
||||
* This can occur when an ManyToMany relates back to itself.
|
||||
* </p>
|
||||
*/
|
||||
public void checkDuplicateForeignKeys() {
|
||||
@@ -639,7 +638,7 @@ public class MTable {
|
||||
*/
|
||||
private String extractBaseTable(String references) {
|
||||
int lastDot = references.lastIndexOf('.');
|
||||
return references.substring(0,lastDot);
|
||||
return references.substring(0, lastDot);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,7 +647,7 @@ public class MTable {
|
||||
*/
|
||||
private String deriveReferences(String references, String draftTableName) {
|
||||
int lastDot = references.lastIndexOf('.');
|
||||
return draftTableName+"."+references.substring(lastDot+1);
|
||||
return draftTableName + "." + references.substring(lastDot + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class MigrationModel {
|
||||
List<MigrationResource> resources = new ArrayList<MigrationResource>();
|
||||
|
||||
for (File xmlFile: xmlFiles) {
|
||||
resources.add(new MigrationResource(xmlFile));
|
||||
resources.add(new MigrationResource(xmlFile, createVersion(xmlFile)));
|
||||
}
|
||||
|
||||
// sort into version order before applying
|
||||
@@ -60,7 +60,7 @@ public class MigrationModel {
|
||||
|
||||
for (MigrationResource migrationResource: resources) {
|
||||
logger.debug("read {}", migrationResource);
|
||||
model.apply(migrationResource.read());
|
||||
model.apply(migrationResource.read(), migrationResource.getVersion());
|
||||
}
|
||||
|
||||
// remember the last version
|
||||
@@ -69,6 +69,12 @@ public class MigrationModel {
|
||||
}
|
||||
}
|
||||
|
||||
private MigrationVersion createVersion(File xmlFile) {
|
||||
String fileName = xmlFile.getName();
|
||||
String versionName = fileName.substring(0, fileName.length() - modelSuffix.length());
|
||||
return MigrationVersion.parse(versionName);
|
||||
}
|
||||
|
||||
public String getNextVersion(String initialVersion) {
|
||||
|
||||
return lastVersion == null ? initialVersion : lastVersion.nextVersion();
|
||||
|
||||
@@ -17,9 +17,9 @@ public class MigrationResource implements Comparable<MigrationResource> {
|
||||
/**
|
||||
* Construct with a migration xml file.
|
||||
*/
|
||||
public MigrationResource(File migrationFile) {
|
||||
public MigrationResource(File migrationFile, MigrationVersion version) {
|
||||
this.migrationFile = migrationFile;
|
||||
this.version = MigrationVersion.parse(migrationFile.getName());
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The version of a migration used so that migrations are processed in order.
|
||||
*/
|
||||
@@ -15,23 +17,74 @@ public class MigrationVersion implements Comparable<MigrationVersion> {
|
||||
*/
|
||||
private final int[] ordering;
|
||||
|
||||
private MigrationVersion(String raw, int[] ordering) {
|
||||
private final boolean[] underscores;
|
||||
|
||||
private final String comment;
|
||||
|
||||
private MigrationVersion(String raw, int[] ordering, boolean[] underscores, String comment) {
|
||||
this.raw = raw;
|
||||
this.ordering = ordering;
|
||||
this.underscores = underscores;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the version comment.
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the version in raw form.
|
||||
*/
|
||||
public String getRaw() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the trimmed version excluding version comment and un-parsable string.
|
||||
*/
|
||||
public String asString() {
|
||||
return formattedVersion(false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the trimmed version with any underscores replaced with '.'
|
||||
*/
|
||||
public String normalised() {
|
||||
return formattedVersion(true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next version based on this version.
|
||||
*/
|
||||
public String nextVersion() {
|
||||
return formattedVersion(false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version part of the string.
|
||||
*
|
||||
* Normalised means always use '.' delimiters (no underscores).
|
||||
* NextVersion means bump/increase the last version number by 1.
|
||||
*/
|
||||
private String formattedVersion(boolean normalised, boolean nextVersion) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < ordering.length; i++) {
|
||||
if (i < ordering.length -1 ) {
|
||||
sb.append(ordering[i]).append(".");
|
||||
if (i < ordering.length - 1) {
|
||||
sb.append(ordering[i]);
|
||||
if (normalised) {
|
||||
sb.append('.');
|
||||
} else {
|
||||
sb.append(underscores[i] ? '_' : '.');
|
||||
}
|
||||
} else {
|
||||
sb.append(ordering[i]+1);
|
||||
sb.append((nextVersion) ? ordering[i] + 1 : ordering[i]);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
@@ -54,33 +107,54 @@ public class MigrationVersion implements Comparable<MigrationVersion> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw version string and just return the leading version number;
|
||||
*/
|
||||
public static String trim(String raw) {
|
||||
return parse(raw).asString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw version string into a MigrationVersion.
|
||||
*/
|
||||
public static MigrationVersion parse(String raw) {
|
||||
|
||||
String value = raw.replace("__",".");
|
||||
value = value.replace('_','.');
|
||||
String comment = "";
|
||||
String value = raw;
|
||||
int commentStart = raw.indexOf("__");
|
||||
if (commentStart > -1) {
|
||||
// trim off the trailing comment
|
||||
comment = raw.substring(commentStart + 2);
|
||||
value = value.substring(0, commentStart);
|
||||
}
|
||||
|
||||
value = value.replace('_', '.');
|
||||
|
||||
String[] sections = value.split("\\.");
|
||||
|
||||
boolean[] underscores = new boolean[sections.length];
|
||||
int[] ordering = new int[sections.length];
|
||||
|
||||
int delimiterPos = 0;
|
||||
int stopIndex = 0;
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
try {
|
||||
ordering[i] = Integer.parseInt(sections[i]);
|
||||
stopIndex++;
|
||||
|
||||
delimiterPos += sections[i].length();
|
||||
underscores[i] = (delimiterPos < raw.length() - 1 && raw.charAt(delimiterPos) == '_');
|
||||
delimiterPos++;
|
||||
} catch (NumberFormatException e) {
|
||||
// stop parsing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int[] actualOrder = new int[stopIndex];
|
||||
System.arraycopy(ordering, 0, actualOrder, 0, stopIndex);
|
||||
int[] actualOrder = Arrays.copyOf(ordering, stopIndex);
|
||||
boolean[] actualUnderscores = Arrays.copyOf(underscores, stopIndex);
|
||||
|
||||
return new MigrationVersion(raw, actualOrder);
|
||||
return new MigrationVersion(raw, actualOrder, actualUnderscores, comment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.AddHistoryTable;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSetType;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateIndex;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
@@ -28,15 +29,16 @@ public class ModelContainer {
|
||||
/**
|
||||
* All the tables in the model.
|
||||
*/
|
||||
private Map<String, MTable> tables = new LinkedHashMap<String, MTable>();
|
||||
private final Map<String, MTable> tables = new LinkedHashMap<String, MTable>();
|
||||
|
||||
/**
|
||||
* All the non unique non foreign key indexes.
|
||||
*/
|
||||
private Map<String, MIndex> indexes = new LinkedHashMap<String, MIndex>();
|
||||
private final Map<String, MIndex> indexes = new LinkedHashMap<String, MIndex>();
|
||||
|
||||
private final PendingDrops pendingDrops = new PendingDrops();
|
||||
|
||||
public ModelContainer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,14 +84,31 @@ public class ModelContainer {
|
||||
/**
|
||||
* Apply a migration with associated changeSets to the model.
|
||||
*/
|
||||
public void apply(Migration migration) {
|
||||
public void apply(Migration migration, MigrationVersion version) {
|
||||
|
||||
List<ChangeSet> changeSets = migration.getChangeSet();
|
||||
for (ChangeSet changeSet : changeSets) {
|
||||
applyChangeSet(changeSet);
|
||||
boolean pending = changeSet.getType() == ChangeSetType.PENDING_DROPS;
|
||||
if (pending) {
|
||||
// un-applied drop columns etc
|
||||
pendingDrops.add(version, changeSet);
|
||||
} else if (isDropsFor(changeSet)) {
|
||||
// applied drops (so no longer pending)
|
||||
pendingDrops.remove(MigrationVersion.parse(changeSet.getDropsFor()));
|
||||
}
|
||||
if (!isDropsFor(changeSet)) {
|
||||
applyChangeSet(changeSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the changeSet contains drops for a previous PENDING_DROPS changeSet.
|
||||
*/
|
||||
private boolean isDropsFor(ChangeSet changeSet) {
|
||||
return changeSet.getDropsFor() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a changeSet to the model.
|
||||
*/
|
||||
@@ -245,4 +264,44 @@ public class ModelContainer {
|
||||
|
||||
indexes.put(indexName, new MIndex(indexName, tableName, columnNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there are pending drops.
|
||||
*/
|
||||
public boolean hasPendingDrops() {
|
||||
return !pendingDrops.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of versions containing un-applied pending drops.
|
||||
*/
|
||||
public List<String> getPendingDrops() {
|
||||
return pendingDrops.pendingDrops();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the migration for the pending drops for a given version.
|
||||
*/
|
||||
public Migration migrationForPendingDrop(String pendingVersion) {
|
||||
return pendingDrops.migrationForVersion(pendingVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the drop columns on history tables that have not been applied yet.
|
||||
*/
|
||||
public void registerPendingHistoryDropColumns(ModelContainer newModel) {
|
||||
pendingDrops.registerPendingHistoryDropColumns(newModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a drop column on a history tables that has not been applied yet.
|
||||
*/
|
||||
public void registerPendingDropColumn(DropColumn dropColumn) {
|
||||
|
||||
MTable table = getTable(dropColumn.getTableName());
|
||||
if (table == null) {
|
||||
throw new IllegalArgumentException("Table ["+dropColumn.getTableName()+"] not found?");
|
||||
}
|
||||
table.registerPendingDropColumn(dropColumn.getColumnName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class ModelDiff {
|
||||
public ChangeSet getDropChangeSet() {
|
||||
// put the changes into a ChangeSet
|
||||
ChangeSet createChangeSet = new ChangeSet();
|
||||
createChangeSet.setType(ChangeSetType.DROP);
|
||||
createChangeSet.setType(ChangeSetType.PENDING_DROPS);
|
||||
createChangeSet.getChangeSetChildren().addAll(dropChanges);
|
||||
return createChangeSet;
|
||||
}
|
||||
@@ -156,6 +156,7 @@ public class ModelDiff {
|
||||
}
|
||||
}
|
||||
|
||||
baseModel.registerPendingHistoryDropColumns(newModel);
|
||||
}
|
||||
|
||||
protected void addDropTable(MTable existingTable) {
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSetType;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The migrations with pending un-applied drops.
|
||||
*/
|
||||
public class PendingDrops {
|
||||
|
||||
private final LinkedHashMap<String, Entry> map = new LinkedHashMap<String, Entry>();
|
||||
|
||||
/**
|
||||
* Add a 'pending drops' changeSet for the given version.
|
||||
*/
|
||||
public void add(MigrationVersion version, ChangeSet changeSet) {
|
||||
|
||||
Entry entry = map.get(version.normalised());
|
||||
if (entry == null) {
|
||||
entry = new Entry(version);
|
||||
map.put(version.normalised(), entry);
|
||||
}
|
||||
entry.add(changeSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of versions with pending drops.
|
||||
*/
|
||||
public List<String> pendingDrops() {
|
||||
|
||||
List<String> versions = new ArrayList<String>();
|
||||
for (Entry value : map.values()) {
|
||||
versions.add(value.version.asString());
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the pending drops for a version (as they have been applied).
|
||||
*/
|
||||
public void remove(MigrationVersion version) {
|
||||
map.remove(version.normalised());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there are no pending drops.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the migration for the pending drops from a version.
|
||||
* <p>
|
||||
* The value of version can be "next" to find the first un-applied pending drops.
|
||||
* </p>
|
||||
*/
|
||||
public Migration migrationForVersion(String pendingVersion) {
|
||||
|
||||
Entry entry = getChangeSets(pendingVersion);
|
||||
|
||||
Migration migration = new Migration();
|
||||
for (ChangeSet changeSet : entry.list) {
|
||||
changeSet.setType(ChangeSetType.APPLY);
|
||||
changeSet.setDropsFor(entry.version.asString());
|
||||
migration.getChangeSet().add(changeSet);
|
||||
}
|
||||
|
||||
return migration;
|
||||
}
|
||||
|
||||
private Entry getChangeSets(String pendingVersion) {
|
||||
|
||||
if ("next".equalsIgnoreCase(pendingVersion)) {
|
||||
Iterator<Entry> it = map.values().iterator();
|
||||
if (it.hasNext()) {
|
||||
Entry first = it.next();
|
||||
it.remove();
|
||||
return first;
|
||||
}
|
||||
} else {
|
||||
Entry remove = map.remove(MigrationVersion.parse(pendingVersion).normalised());
|
||||
if (remove != null) {
|
||||
return remove;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No pending changeSets for version [" + pendingVersion + "] found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Register pending drop columns on history tables to the new model.
|
||||
*/
|
||||
public void registerPendingHistoryDropColumns(ModelContainer newModel) {
|
||||
|
||||
for (Entry entry : map.values()) {
|
||||
for (ChangeSet changeSet : entry.list) {
|
||||
for (Object change : changeSet.getChangeSetChildren()) {
|
||||
if (change instanceof DropColumn) {
|
||||
DropColumn dropColumn = (DropColumn) change;
|
||||
if (Boolean.TRUE.equals(dropColumn.isWithHistory())) {
|
||||
newModel.registerPendingDropColumn(dropColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class Entry {
|
||||
|
||||
final MigrationVersion version;
|
||||
|
||||
final List<ChangeSet> list = new ArrayList<ChangeSet>();
|
||||
|
||||
Entry(MigrationVersion version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
void add(ChangeSet changeSet) {
|
||||
list.add(changeSet);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSetType;
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
|
||||
import java.io.File;
|
||||
@@ -44,7 +45,7 @@ public class PlatformDdlWriter {
|
||||
|
||||
List<ChangeSet> changeSets = dbMigration.getChangeSet();
|
||||
for (ChangeSet changeSet : changeSets) {
|
||||
if (!changeSet.getChangeSetChildren().isEmpty()) {
|
||||
if (isApply(changeSet)) {
|
||||
handler.generate(write, changeSet);
|
||||
}
|
||||
}
|
||||
@@ -53,6 +54,13 @@ public class PlatformDdlWriter {
|
||||
writePlatformDdl(write, writePath, fullVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the changeSet is APPLY and not empty.
|
||||
*/
|
||||
private boolean isApply(ChangeSet changeSet) {
|
||||
return changeSet.getType() == ChangeSetType.APPLY && !changeSet.getChangeSetChildren().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the ddl files.
|
||||
*/
|
||||
@@ -78,15 +86,6 @@ public class PlatformDdlWriter {
|
||||
}
|
||||
}
|
||||
|
||||
if (!write.isDropEmpty()) {
|
||||
FileWriter dropWriter = createWriter(resourcePath, fullVersion, config.getDropPath(), config.getDropSuffix());
|
||||
try {
|
||||
writeDropDdl(dropWriter, write);
|
||||
dropWriter.flush();
|
||||
} finally {
|
||||
dropWriter.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected FileWriter createWriter(File path, String fullVersion, String subPath, String suffix) throws IOException {
|
||||
@@ -136,17 +135,6 @@ public class PlatformDdlWriter {
|
||||
writer.append(write.rollback().getBuffer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the 'Drop' DDL buffers to the writer.
|
||||
*/
|
||||
protected void writeDropDdl(Writer writer, DdlWrite write) throws IOException {
|
||||
|
||||
// merge the rollback buffers in the appropriate order
|
||||
prependDropDependencies(writer, write.dropDropDependencies());
|
||||
writer.append(write.dropHistory().getBuffer());
|
||||
writer.append(write.drop().getBuffer());
|
||||
}
|
||||
|
||||
private void prependDropDependencies(Writer writer, DdlBuffer buffer) throws IOException {
|
||||
if (!buffer.isEmpty()) {
|
||||
writer.append("-- drop dependencies\n");
|
||||
|
||||
Reference in New Issue
Block a user