From 237cdcdd3dfe4176a2c218b91f69920c1106b1d9 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Fri, 5 Feb 2016 11:52:06 +1300 Subject: [PATCH] #554 - DDL - DB Migration with @History and Postgres - views need to be dropped early to support migration changes --- .../dbmigration/ddlgeneration/DdlWrite.java | 41 ++++++++++++++++++- .../platform/PostgresHistoryDdl.java | 12 +++--- .../dbmigration/model/PlatformDdlWriter.java | 12 ++++++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/DdlWrite.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/DdlWrite.java index cc2746045..cff4df133 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/DdlWrite.java +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/DdlWrite.java @@ -12,12 +12,16 @@ public class DdlWrite { private final ModelContainer currentModel; + private final DdlBuffer applyDropDependencies; + private final DdlBuffer apply; private final DdlBuffer applyForeignKeys; private final DdlBuffer applyHistory; + private final DdlBuffer rollbackDropDependencies; + private final DdlBuffer rollbackForeignKeys; private final DdlBuffer rollback; @@ -51,9 +55,11 @@ public class DdlWrite { */ public DdlWrite(MConfiguration configuration, ModelContainer currentModel) { this.currentModel = currentModel; + this.applyDropDependencies = new BaseDdlBuffer(configuration); 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.drop = new BaseDdlBuffer(configuration); @@ -77,7 +83,8 @@ public class DdlWrite { public boolean isApplyEmpty() { return apply.getBuffer().isEmpty() && applyForeignKeys.getBuffer().isEmpty() - && applyHistory.getBuffer().isEmpty(); + && applyHistory.getBuffer().isEmpty() + && applyDropDependencies.getBuffer().isEmpty(); } /** @@ -85,9 +92,25 @@ public class DdlWrite { */ public boolean isApplyRollbackEmpty() { return rollback.getBuffer().isEmpty() - && rollbackForeignKeys.getBuffer().isEmpty(); + && rollbackForeignKeys.getBuffer().isEmpty() + && rollbackDropDependencies.getBuffer().isEmpty(); } + /** + * Return the apply or rollback buffer. + */ + public DdlBuffer buffer(boolean apply) { + return (apply) ? apply() : rollback(); + } + + /** + * Return the apply or rollback drop dependencies buffer. + */ + public DdlBuffer dropDependencies(boolean apply) { + return (apply) ? applyDropDependencies() : rollbackDropDependencies(); + } + + /** * Return true the drop buffers are empty. */ @@ -102,6 +125,13 @@ public class DdlWrite { return apply; } + /** + * Return the buffer that executes early to drop dependencies like views etc. + */ + public DdlBuffer applyDropDependencies() { + return applyDropDependencies; + } + /** * Return the buffer that APPLY DDL is written to for foreign keys and their associated indexes. *

@@ -119,6 +149,13 @@ public class DdlWrite { return applyHistory; } + /** + * Return the buffer that rollback executes early to drop dependencies like views. + */ + public DdlBuffer rollbackDropDependencies() { + return rollbackDropDependencies; + } + /** * Return the buffer that ROLLBACK DDL is written to for foreign keys and associated indexes. */ diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java index 45443702c..e75b0a990 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java @@ -121,7 +121,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { apply.append("-- Regenerated ").append(procedureName).newLine(); apply.append("-- changes: ").append(update.description()).newLine(); - recreateHistoryView(apply, table.getName(), includedColumns); + recreateHistoryView(writer, true, table.getName(), includedColumns); } addFunction(apply, procedureName, historyTable, includedColumns); @@ -134,7 +134,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { rollback.append("-- Revert regenerated ").append(procedureName).newLine(); rollback.append("-- revert changes: ").append(update.description()).newLine(); - recreateHistoryView(rollback, table.getName(), includedColumns); + recreateHistoryView(writer, false, table.getName(), includedColumns); addFunction(rollback, procedureName, historyTable, includedColumns); } } @@ -143,11 +143,13 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { * For postgres 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. */ - private void recreateHistoryView(DdlBuffer buffer, String baseTableName, List includedColumns) throws IOException { + private void recreateHistoryView(DdlWrite writer, boolean apply, String baseTableName, List includedColumns) throws IOException { - buffer.append("drop view if exists ").append(baseTableName).append(viewSuffix).endOfStatement(); + // we need to drop the view early/first before any changes to the tables etc + writer.dropDependencies(apply).append("drop view if exists ").append(baseTableName).append(viewSuffix).endOfStatement(); - createWithHistoryView(buffer, baseTableName, includedColumns); + // recreate the view with specific columns specified (the columns generally are not dropped until later) + createWithHistoryView(writer.buffer(apply), baseTableName, includedColumns); } @Override diff --git a/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java b/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java index a6d4011ac..20a758148 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java +++ b/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java @@ -116,6 +116,12 @@ public class PlatformDdlWriter { protected void writeApplyDdl(Writer writer, DdlWrite write) throws IOException { // merge the apply buffers in the appropriate order + if (!write.applyDropDependencies().isEmpty()) { + writer.append("-- drop dependencies\n"); + writer.append(write.applyDropDependencies().getBuffer()); + writer.append("\n"); + } + writer.append("-- apply changes\n"); writer.append(write.apply().getBuffer()); writer.append(write.applyForeignKeys().getBuffer()); writer.append(write.applyHistory().getBuffer()); @@ -127,6 +133,12 @@ public class PlatformDdlWriter { protected void writeApplyRollbackDdl(Writer writer, DdlWrite write) throws IOException { // merge the rollback buffers in the appropriate order + if (!write.rollbackDropDependencies().isEmpty()) { + writer.append("-- drop dependencies\n"); + writer.append(write.rollbackDropDependencies().getBuffer()); + writer.append("\n"); + } + writer.append("-- reverse changes\n"); writer.append(write.rollbackForeignKeys().getBuffer()); writer.append(write.rollback().getBuffer()); }