diff --git a/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java b/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java index 65b9f0cca..44905aa02 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java +++ b/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java @@ -3,6 +3,7 @@ package io.ebeaninternal.dbmigration.model; import io.ebeaninternal.dbmigration.migration.ChangeSet; import io.ebeaninternal.dbmigration.migration.ChangeSetType; import io.ebeaninternal.dbmigration.migration.DropColumn; +import io.ebeaninternal.dbmigration.migration.DropHistoryTable; import io.ebeaninternal.dbmigration.migration.DropTable; import io.ebeaninternal.dbmigration.migration.Migration; @@ -207,10 +208,26 @@ public class PendingDrops { } else if (pendingDrop instanceof DropTable && dropTableIn((DropTable) pendingDrop, appliedDrops)) { iterator.remove(); + + } else if (pendingDrop instanceof DropHistoryTable && dropHistoryTableIn((DropHistoryTable) pendingDrop, appliedDrops)) { + iterator.remove(); + } } } + /** + * Return true if the pendingDrop is contained in the appliedDrops. + */ + private boolean dropHistoryTableIn(DropHistoryTable pendingDrop, ChangeSet appliedDrops) { + for (Object o : appliedDrops.getChangeSetChildren()) { + if (o instanceof DropHistoryTable && sameHistoryTable(pendingDrop, (DropHistoryTable) o)) { + return true; + } + } + return false; + } + /** * Return true if the pendingDrop is contained in the appliedDrops. */ @@ -235,6 +252,13 @@ public class PendingDrops { return false; } + /** + * Return true if the DropHistoryTable match by base-table name. + */ + private boolean sameHistoryTable(DropHistoryTable pendingDrop, DropHistoryTable o) { + return pendingDrop.getBaseTable().equals(o.getBaseTable()); + } + /** * Return true if the DropTable match by table name. */ diff --git a/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java b/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java new file mode 100644 index 000000000..10fd869d6 --- /dev/null +++ b/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java @@ -0,0 +1,85 @@ +package io.ebeaninternal.dbmigration; + +import io.ebean.EbeanServer; +import io.ebean.EbeanServerFactory; +import io.ebean.annotation.Platform; +import io.ebean.config.ServerConfig; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.StrictAssertions.assertThatThrownBy; + + +/** + * This is the Migrationscript generator. It generates 3 migrationscript for the models + * @author Roland Praml, FOCONIS AG + * + */ +public class DbMigrationDropHistoryTest { + + private static final Logger logger = LoggerFactory.getLogger(DbMigrationDropHistoryTest.class); + + @Test + public void invokeTest() throws IOException { + main(null); + } + + public static void main(String[] args) throws IOException { + + logger.info("start"); + + DefaultDbMigration migration = new DefaultDbMigration(); + + // We use src/test/resources as output directory (so we see in GIT if files will change) + + migration.setPathToResources("src/test/resources"); + + ServerConfig config = new ServerConfig(); + config.setName("migrationtest-history"); + config.loadFromProperties(); + config.setRegister(false); + config.setDefaultServer(false); + + + config.setPackages(Arrays.asList("misc.migration.history.v1_0")); + EbeanServer server = EbeanServerFactory.create(config); + migration.setServer(server); + + // First, we clean up the output-directory + assertThat(migration.getMigrationDirectory().getAbsolutePath()).contains("migrationtest-history"); + Files.walk(migration.getMigrationDirectory().toPath()) + .filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete); + + // then we generate migration scripts for v1_0 + assertThat(migration.generateMigration()).isEqualTo("1.0__initial"); + // and we check repeatative calls + assertThat(migration.generateMigration()).isNull(); + + // and now for v1_1 + config.setPackages(Arrays.asList("misc.migration.history.v1_1")); + server = EbeanServerFactory.create(config); + migration.setServer(server); + assertThat(migration.generateMigration()).isEqualTo("1.1"); + assertThat(migration.generateMigration()).isNull(); // subsequent call + + + + System.setProperty("ddl.migration.pendingDropsFor", "1.1"); + assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1"); + assertThatThrownBy(()->migration.generateMigration()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("No 'pendingDrops'"); // subsequent call + System.clearProperty("ddl.migration.pendingDropsFor"); + + logger.info("end"); + } + +} diff --git a/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java b/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java index 602cbb7c3..635a9b9ac 100644 --- a/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java +++ b/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java @@ -15,6 +15,7 @@ import java.nio.file.Path; import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** @@ -85,6 +86,11 @@ public class DbMigrationGenerateTest { System.setProperty("ddl.migration.pendingDropsFor", "1.1"); assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1"); + + assertThatThrownBy(()->migration.generateMigration()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("No 'pendingDrops'"); // subsequent call + System.clearProperty("ddl.migration.pendingDropsFor"); assertThat(migration.generateMigration()).isNull(); // subsequent call @@ -98,6 +104,10 @@ public class DbMigrationGenerateTest { System.setProperty("ddl.migration.pendingDropsFor", "1.3"); assertThat(migration.generateMigration()).isEqualTo("1.4__dropsFor_1.3"); + assertThatThrownBy(()->migration.generateMigration()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("No 'pendingDrops'"); // subsequent call + System.clearProperty("ddl.migration.pendingDropsFor"); assertThat(migration.generateMigration()).isNull(); // subsequent call diff --git a/src/test/java/misc/migration/history/v1_0/EHistory7.java b/src/test/java/misc/migration/history/v1_0/EHistory7.java new file mode 100644 index 000000000..28ca8c5de --- /dev/null +++ b/src/test/java/misc/migration/history/v1_0/EHistory7.java @@ -0,0 +1,24 @@ +package misc.migration.history.v1_0; + + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import io.ebean.annotation.History; + +/** + * detects a bug where dropHistoryTable is not applied correctly + * + * @author Roland Praml, FOCONIS AG + * + */ +@Entity +@Table(name = "migtest_e_history7") +@History +public class EHistory7 { + + @Id + Integer id; + +} diff --git a/src/test/java/misc/migration/history/v1_1/EHistory7.java b/src/test/java/misc/migration/history/v1_1/EHistory7.java new file mode 100644 index 000000000..7b658368c --- /dev/null +++ b/src/test/java/misc/migration/history/v1_1/EHistory7.java @@ -0,0 +1,21 @@ +package misc.migration.history.v1_1; + + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * detects a bug where dropHistoryTable is not applied correctly + * + * @author Roland Praml, FOCONIS AG + * + */ +@Entity +@Table(name = "migtest_e_history7") +public class EHistory7 { + + @Id + Integer id; + +} diff --git a/src/test/resources/dbmigration/migrationtest-history/1.0__initial.sql b/src/test/resources/dbmigration/migrationtest-history/1.0__initial.sql new file mode 100644 index 000000000..16fa48f95 --- /dev/null +++ b/src/test/resources/dbmigration/migrationtest-history/1.0__initial.sql @@ -0,0 +1,17 @@ +-- Migrationscripts for ebean unittest DbMigrationDropHistoryTest +-- apply changes +create table migtest_e_history7 ( + id integer auto_increment not null, + constraint pk_migtest_e_history7 primary key (id) +); + +alter table migtest_e_history7 add column sys_period_start datetime(6) default now(6); +alter table migtest_e_history7 add column sys_period_end datetime(6); +create table migtest_e_history7_history( + id integer, + sys_period_start datetime(6), + sys_period_end datetime(6) +); +create view migtest_e_history7_with_history as select * from migtest_e_history7 union all select * from migtest_e_history7_history; + +create trigger migtest_e_history7_history_upd before update,delete on migtest_e_history7 for each row call "io.ebean.config.dbplatform.h2.H2HistoryTrigger"; diff --git a/src/test/resources/dbmigration/migrationtest-history/1.2__dropsFor_1.1.sql b/src/test/resources/dbmigration/migrationtest-history/1.2__dropsFor_1.1.sql new file mode 100644 index 000000000..692d93f76 --- /dev/null +++ b/src/test/resources/dbmigration/migrationtest-history/1.2__dropsFor_1.1.sql @@ -0,0 +1,10 @@ +-- Migrationscripts for ebean unittest DbMigrationDropHistoryTest +-- drop dependencies +drop trigger migtest_e_history7_history_upd; +drop view migtest_e_history7_with_history; +alter table migtest_e_history7 drop column sys_period_start; +alter table migtest_e_history7 drop column sys_period_end; +drop table migtest_e_history7_history; + + +-- apply changes diff --git a/src/test/resources/dbmigration/migrationtest-history/R__multi_comments.sql b/src/test/resources/dbmigration/migrationtest-history/R__multi_comments.sql new file mode 100644 index 000000000..0ede0c9eb --- /dev/null +++ b/src/test/resources/dbmigration/migrationtest-history/R__multi_comments.sql @@ -0,0 +1,3 @@ + + -- h2 and postgres script + \ No newline at end of file diff --git a/src/test/resources/dbmigration/migrationtest-history/R__order_views.sql b/src/test/resources/dbmigration/migrationtest-history/R__order_views.sql new file mode 100644 index 000000000..2872cc37e --- /dev/null +++ b/src/test/resources/dbmigration/migrationtest-history/R__order_views.sql @@ -0,0 +1,8 @@ + + + create or replace view order_agg_vw as + select d.order_id, sum(d.order_qty * d.unit_price) as order_total, + sum(d.ship_qty * d.unit_price) as ship_total + from o_order_detail d + group by d.order_id + \ No newline at end of file diff --git a/src/test/resources/dbmigration/migrationtest-history/model/1.0__initial.model.xml b/src/test/resources/dbmigration/migrationtest-history/model/1.0__initial.model.xml new file mode 100644 index 000000000..52d70c793 --- /dev/null +++ b/src/test/resources/dbmigration/migrationtest-history/model/1.0__initial.model.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/dbmigration/migrationtest-history/model/1.1.model.xml b/src/test/resources/dbmigration/migrationtest-history/model/1.1.model.xml new file mode 100644 index 000000000..8c0a04b2b --- /dev/null +++ b/src/test/resources/dbmigration/migrationtest-history/model/1.1.model.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/test/resources/dbmigration/migrationtest-history/model/1.2__dropsFor_1.1.model.xml b/src/test/resources/dbmigration/migrationtest-history/model/1.2__dropsFor_1.1.model.xml new file mode 100644 index 000000000..4cfc4672f --- /dev/null +++ b/src/test/resources/dbmigration/migrationtest-history/model/1.2__dropsFor_1.1.model.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/test/resources/ebean.properties b/src/test/resources/ebean.properties index 40d0c41db..5080db655 100644 --- a/src/test/resources/ebean.properties +++ b/src/test/resources/ebean.properties @@ -171,3 +171,15 @@ ebean.migrationtest.migration.appName=migrationtest ebean.migrationtest.migration.migrationPath=dbmigration/migrationtest ebean.migrationtest.migration.strict=true +# parameters for migration test +datasource.migrationtest-history.username=SA +datasource.migrationtest-history.password=SA +datasource.migrationtest-history.databaseUrl=jdbc:h2:mem:migration +datasource.migrationtest-history.databaseDriver=org.h2.Driver +ebean.migrationtest-history.applyPrefix=V +ebean.migrationtest-history.ddl.generate=false +ebean.migrationtest-history.ddl.run=false +ebean.migrationtest-history.ddl.header=-- Migrationscripts for ebean unittest DbMigrationDropHistoryTest +ebean.migrationtest-history.migration.appName=migrationtest-history +ebean.migrationtest-history.migration.migrationPath=dbmigration/migrationtest-history +ebean.migrationtest-history.migration.strict=true