#564 - DDL DB Migration - migration generation on history table, pending drop columns missing in the history view and tigger

This commit is contained in:
Robin Bygrave
2016-02-12 21:28:19 +13:00
parent 4848c24a0a
commit f8804f8d18
17 changed files with 486 additions and 154 deletions
@@ -220,6 +220,9 @@ public class DbMigration {
}
}
/**
* Generate the diff migration.
*/
private void generateDiff(Request request) throws IOException {
List<String> pendingDrops = request.getPendingDrops();
@@ -227,15 +230,18 @@ public class DbMigration {
logger.info("Pending un-applied drops in versions {}", pendingDrops);
}
ModelDiff diff = request.createDiff();
if (diff.isEmpty()) {
Migration migration = request.createDiffMigration();
if (migration == null) {
logger.info("no changes detected - no migration written");
} else {
// there were actually changes to write
generateMigration(request, diff.getMigration(), null);
generateMigration(request, migration, null);
}
}
/**
* Generate the migration based on the pendingDrops from a prior version.
*/
private void generatePendingDrop(Request request, String pendingVersion) throws IOException {
Migration migration = request.migrationForPendingDrop(pendingVersion);
@@ -290,12 +296,12 @@ public class DbMigration {
}
/**
* Create an return the diff of the current model to the migration model.
* Create and return the diff of the current model to the migration model.
*/
public ModelDiff createDiff() {
public Migration createDiffMigration() {
ModelDiff diff = new ModelDiff(migrated);
diff.compareTo(current);
return diff;
return diff.isEmpty() ? null : diff.getMigration();
}
}
@@ -159,12 +159,7 @@ public class CurrentModel {
ModelDiff diff = new ModelDiff();
diff.compareTo(model);
List<Object> applyChanges = diff.getApplyChanges();
// put the changes into a ChangeSet
ChangeSet applyChangeSet = new ChangeSet();
applyChangeSet.getChangeSetChildren().addAll(applyChanges);
return applyChangeSet;
return diff.getApplyChangeSet();
}
}
@@ -356,8 +356,9 @@ public class MTable {
return withHistory;
}
public void setWithHistory(boolean withHistory) {
public MTable setWithHistory(boolean withHistory) {
this.withHistory = withHistory;
return this;
}
public List<String> allHistoryColumns(boolean includeDropped) {
@@ -13,7 +13,6 @@ import com.avaje.ebean.dbmigration.migration.DropIndex;
import com.avaje.ebean.dbmigration.migration.DropTable;
import com.avaje.ebean.dbmigration.migration.Migration;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -45,8 +44,7 @@ public class ModelContainer {
* Adjust the FK references on all the draft tables.
*/
public void adjustDraftReferences() {
Collection<MTable> tables = this.tables.values();
for (MTable table : tables) {
for (MTable table : this.tables.values()) {
if (table.isDraft()) {
table.adjustReferences(this);
}
@@ -94,7 +92,7 @@ public class ModelContainer {
pendingDrops.add(version, changeSet);
} else if (isDropsFor(changeSet)) {
pendingDrops.appliedDropsFor(MigrationVersion.parse(changeSet.getDropsFor()));
pendingDrops.appliedDropsFor(changeSet);
}
if (!isDropsFor(changeSet)) {
applyChangeSet(changeSet);
@@ -286,10 +284,26 @@ public class ModelContainer {
pendingDrops.registerPendingHistoryDropColumns(newModel);
}
/**
* Register any pending drop columns on history tables. These columns are now not in the current
* logical model but we still need to include them in the history views and triggers until they
* are actually dropped.
*/
public void registerPendingHistoryDropColumns(ChangeSet changeSet) {
for (Object change : changeSet.getChangeSetChildren()) {
if (change instanceof DropColumn) {
DropColumn dropColumn = (DropColumn) change;
if (Boolean.TRUE.equals(dropColumn.isWithHistory())) {
registerPendingDropColumn(dropColumn);
}
}
}
}
/**
* Register a drop column on a history tables that has not been applied yet.
*/
public void registerPendingDropColumn(DropColumn dropColumn) {
private void registerPendingDropColumn(DropColumn dropColumn) {
MTable table = getTable(dropColumn.getTableName());
if (table == null) {
@@ -66,16 +66,14 @@ public class ModelDiff {
public Migration getMigration() {
Migration migration = new Migration();
ChangeSet applyChangeSet = getApplyChangeSet();
if (!applyChangeSet.getChangeSetChildren().isEmpty()) {
if (!applyChanges.isEmpty()) {
// add a non empty apply changeSet
migration.getChangeSet().add(applyChangeSet);
migration.getChangeSet().add(getApplyChangeSet());
}
ChangeSet dropChangeSet = getDropChangeSet();
if (!dropChangeSet.getChangeSetChildren().isEmpty()) {
if (!dropChanges.isEmpty()) {
// add a non empty drop changeSet
migration.getChangeSet().add(dropChangeSet);
migration.getChangeSet().add(getDropChangeSet());
}
return migration;
}
@@ -83,14 +81,14 @@ public class ModelDiff {
/**
* Return the list of 'apply' changes.
*/
public List<Object> getApplyChanges() {
List<Object> getApplyChanges() {
return applyChanges;
}
/**
* Return the list of 'drop' changes.
*/
public List<Object> getDropChanges() {
List<Object> getDropChanges() {
return dropChanges;
}
@@ -108,7 +106,7 @@ public class ModelDiff {
/**
* Return the 'drop' changeSet.
*/
public ChangeSet getDropChangeSet() {
ChangeSet getDropChangeSet() {
// put the changes into a ChangeSet
ChangeSet createChangeSet = new ChangeSet();
createChangeSet.setType(ChangeSetType.PENDING_DROPS);
@@ -156,7 +154,12 @@ public class ModelDiff {
}
}
// register un-applied ones from the previous migrations
baseModel.registerPendingHistoryDropColumns(newModel);
if (!dropChanges.isEmpty()) {
// register new ones created just now as part of this diff
newModel.registerPendingHistoryDropColumns(getDropChangeSet());
}
}
protected void addDropTable(MTable existingTable) {
@@ -3,6 +3,7 @@ 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.DropTable;
import com.avaje.ebean.dbmigration.migration.Migration;
import java.util.ArrayList;
@@ -48,9 +49,12 @@ public class PendingDrops {
* All the pending drops for this migration version have been applied so we need
* to remove the (unsuppressed) pending drops for this version.
*/
public boolean appliedDropsFor(MigrationVersion version) {
public boolean appliedDropsFor(ChangeSet changeSet) {
MigrationVersion version = MigrationVersion.parse(changeSet.getDropsFor());
Entry entry = map.get(version.normalised());
if (entry.removeDrops()) {
if (entry.removeDrops(changeSet)) {
// it had no suppressForever changeSets so remove completely
map.remove(version.normalised());
return true;
@@ -70,8 +74,11 @@ public class PendingDrops {
Entry entry = getEntry(pendingVersion);
Migration migration = new Migration();
for (ChangeSet changeSet : entry.list) {
Iterator<ChangeSet> it = entry.list.iterator();
while (it.hasNext()) {
ChangeSet changeSet = it.next();
if (!isSuppressForever(changeSet)) {
it.remove();
changeSet.setType(ChangeSetType.APPLY);
changeSet.setDropsFor(entry.version.asString());
migration.getChangeSet().add(changeSet);
@@ -113,14 +120,7 @@ public class PendingDrops {
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);
}
}
}
newModel.registerPendingHistoryDropColumns(changeSet);
}
}
}
@@ -129,10 +129,16 @@ public class PendingDrops {
* Return true if there is an Entry for the given version.
*/
boolean testContainsEntryFor(MigrationVersion version) {
return map.containsKey(version.normalised());
}
/**
* Return the Entry for the given version.
*/
Entry testGetEntryFor(MigrationVersion version) {
return map.get(version.normalised());
}
static class Entry {
final MigrationVersion version;
@@ -175,18 +181,79 @@ public class PendingDrops {
* Remove the drops that are not suppressForever and return true if that
* removed all the changeSets (and there are no suppressForever ones).
*/
boolean removeDrops() {
boolean removeDrops(ChangeSet appliedDrops) {
Iterator<ChangeSet> iterator = list.iterator();
while (iterator.hasNext()) {
ChangeSet next = iterator.next();
if (!isSuppressForever(next)) {
iterator.remove();
removeMatchingChanges(next, appliedDrops);
if (next.getChangeSetChildren().isEmpty()) {
iterator.remove();
}
}
}
return list.isEmpty();
}
/**
* Remove the applied drops from the pending ones matching by table name and column name.
*/
private void removeMatchingChanges(ChangeSet pendingDrops, ChangeSet appliedDrops) {
List<Object> pending = pendingDrops.getChangeSetChildren();
Iterator<Object> iterator = pending.iterator();
while (iterator.hasNext()) {
Object pendingDrop = iterator.next();
if (pendingDrop instanceof DropColumn && dropColumnIn((DropColumn)pendingDrop, appliedDrops)) {
iterator.remove();
} else if (pendingDrop instanceof DropTable && dropTableIn((DropTable)pendingDrop, appliedDrops)) {
iterator.remove();
}
}
}
/**
* Return true if the pendingDrop is contained in the appliedDrops.
*/
private boolean dropTableIn(DropTable pendingDrop, ChangeSet appliedDrops) {
for (Object o : appliedDrops.getChangeSetChildren()) {
if (o instanceof DropTable && sameTable(pendingDrop, (DropTable)o)) {
return true;
}
}
return false;
}
/**
* Return true if the pendingDrop is contained in the appliedDrops.
*/
private boolean dropColumnIn(DropColumn pendingDrop, ChangeSet appliedDrops) {
for (Object o : appliedDrops.getChangeSetChildren()) {
if (o instanceof DropColumn && sameColumn(pendingDrop, (DropColumn) o)) {
return true;
}
}
return false;
}
/**
* Return true if the DropTable match by table name.
*/
private boolean sameTable(DropTable pendingDrop, DropTable o) {
return pendingDrop.getName().equals(o.getName());
}
/**
* Return true if the DropColumns match by table and column name.
*/
private boolean sameColumn(DropColumn pending, DropColumn o) {
return pending.getColumnName().equals(o.getColumnName())
&& pending.getTableName().equals(o.getTableName());
}
}
private static boolean isSuppressForever(ChangeSet next) {
@@ -1,6 +1,7 @@
package com.avaje.ebean.dbmigration.model;
import com.avaje.ebean.dbmigration.migration.ChangeSet;
import com.avaje.ebean.dbmigration.migration.DropColumn;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
@@ -16,12 +17,10 @@ public class EntryTest {
assertThat(entry.hasPendingDrops()).isFalse();
}
@Test
public void test_when_normal() throws Exception {
PendingDrops.Entry entry = createEntry();
entry.add(new ChangeSet());
PendingDrops.Entry entry = createEntry(new ChangeSet());
assertThat(entry.hasPendingDrops()).isTrue();
}
@@ -29,11 +28,10 @@ public class EntryTest {
@Test
public void test_when_suppressOnly() throws Exception {
PendingDrops.Entry entry = createEntry();
ChangeSet cs = new ChangeSet();
cs.setSuppressDropsForever(Boolean.TRUE);
entry.add(cs);
PendingDrops.Entry entry = createEntry(cs);
assertThat(entry.hasPendingDrops()).isFalse();
}
@@ -41,12 +39,10 @@ public class EntryTest {
@Test
public void test_when_both() throws Exception {
PendingDrops.Entry entry = createEntry();
ChangeSet cs = new ChangeSet();
cs.setSuppressDropsForever(Boolean.TRUE);
entry.add(cs);
entry.add(new ChangeSet());
PendingDrops.Entry entry = createEntry(cs, new ChangeSet());
assertThat(entry.hasPendingDrops()).isTrue();
}
@@ -60,21 +56,19 @@ public class EntryTest {
}
@Test
public void test_containsSuppressForever_when_not() {
public void test_containsSuppressForever_when_notSuppress() {
PendingDrops.Entry entry = createEntry();
entry.add(new ChangeSet());
PendingDrops.Entry entry = createEntry(new ChangeSet());
assertThat(entry.containsSuppressForever()).isFalse();
}
@Test
public void test_containsSuppressForever_when_does() {
public void test_containsSuppressForever_when_suppress() {
PendingDrops.Entry entry = createEntry();
ChangeSet cs = new ChangeSet();
cs.setSuppressDropsForever(Boolean.TRUE);
entry.add(cs);
PendingDrops.Entry entry = createEntry(cs);
assertThat(entry.containsSuppressForever()).isTrue();
}
@@ -82,45 +76,76 @@ public class EntryTest {
@Test
public void test_containsSuppressForever_when_mixed() {
PendingDrops.Entry entry = createEntry();
ChangeSet cs = new ChangeSet();
cs.setSuppressDropsForever(Boolean.TRUE);
entry.add(cs);
entry.add(new ChangeSet());
PendingDrops.Entry entry = createEntry(cs, new ChangeSet());
assertThat(entry.containsSuppressForever()).isTrue();
}
@Test
public void test_removeDrops_when_empty() {
public void test_removeDrops_when_columnsMatch() {
PendingDrops.Entry entry = createEntry();
assertThat(entry.removeDrops()).isTrue();
ChangeSet pending = changeSet("one", "two");
PendingDrops.Entry entry = createEntry(pending);
assertThat(entry.removeDrops(changeSet("one","two"))).isTrue();
assertThat(entry.list).asList().doesNotContain(pending);
}
@Test
public void test_removeDrops_when_notSuppressed() {
public void test_removeDrops_when_subset() {
PendingDrops.Entry entry = createEntry();
entry.add(new ChangeSet());
assertThat(entry.removeDrops()).isTrue();
DropColumn dropColumnTwo = col("two");
ChangeSet pending = changeSet("one");
pending.getChangeSetChildren().add(dropColumnTwo);
PendingDrops.Entry entry = createEntry(pending);
assertThat(entry.removeDrops(changeSet("one"))).isFalse();
assertThat(entry.list).asList().containsExactly(pending);
assertThat(pending.getChangeSetChildren()).asList().containsExactly(dropColumnTwo);
}
@Test
public void test_removeDrops_when_containsSuppressed() {
public void test_removeDrops_when_columnsMatch_butSuppressed() {
ChangeSet pending = changeSet("one", "two");
pending.setSuppressDropsForever(Boolean.TRUE);
PendingDrops.Entry entry = createEntry(pending);
assertThat(entry.removeDrops(changeSet("one","two"))).isFalse();
assertThat(entry.list).asList().contains(pending);
assertThat(pending.getChangeSetChildren()).asList().hasSize(2);
}
static ChangeSet changeSet(String... colName) {
PendingDrops.Entry entry = createEntry();
entry.add(new ChangeSet());
ChangeSet cs = new ChangeSet();
cs.setSuppressDropsForever(Boolean.TRUE);
entry.add(cs);
for (String col : colName) {
cs.getChangeSetChildren().add(col(col));
}
return cs;
}
assertThat(entry.removeDrops()).isFalse();
static DropColumn col(String colName) {
DropColumn drop = new DropColumn();
drop.setColumnName(colName);
drop.setTableName("tab");
return drop;
}
@NotNull
private PendingDrops.Entry createEntry() {
MigrationVersion version = MigrationVersion.parse("1.1");
return new PendingDrops.Entry(version);
static PendingDrops.Entry createEntry(ChangeSet... pending) {
PendingDrops.Entry entry = new PendingDrops.Entry(MigrationVersion.parse("1.1"));
for (ChangeSet changeSet: pending) {
entry.add(changeSet);
}
return entry;
}
}
@@ -14,7 +14,7 @@ import static org.assertj.core.api.Assertions.*;
public class MTableTest {
MTable base() {
static MTable base() {
MTable table = new MTable("tab");
table.addColumn(new MColumn("id","bigint"));
table.addColumn(new MColumn("name","varchar(20)"));
@@ -23,7 +23,7 @@ public class MTableTest {
return table;
}
MTable newTable() {
static MTable newTable() {
MTable table = new MTable("tab");
table.addColumn(new MColumn("id","bigint"));
table.addColumn(new MColumn("name","varchar(20)"));
@@ -32,7 +32,7 @@ public class MTableTest {
return table;
}
MTable newTableAdd2Columns() {
static MTable newTableAdd2Columns() {
MTable table = new MTable("tab");
table.addColumn(new MColumn("id","bigint"));
table.addColumn(new MColumn("name","varchar(20)"));
@@ -42,7 +42,7 @@ public class MTableTest {
return table;
}
MTable newTableModifiedColumn() {
static MTable newTableModifiedColumn() {
MColumn modCol = new MColumn("name", "varchar(30)");// modified type
modCol.setNotnull(true);
@@ -0,0 +1,93 @@
package com.avaje.ebean.dbmigration.model;
import com.avaje.ebean.dbmigration.migration.Migration;
import com.avaje.ebean.dbmigration.migrationreader.MigrationXmlReader;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class ModelContainerTest {
@Test
public void apply_when_noPendingDrops_then_emptyPending() throws Exception {
ModelContainer container = new ModelContainer();
container.apply(mig("1.0.model.xml"), ver("1.1"));
assertThat(container.getPendingDrops()).isEmpty();
}
@Test
public void apply_when_pendingDrops_then_registeredHistoryTable() throws Exception {
ModelContainer base = container_1_1();
MTable table = base.getTable("document");
assertThat(table.allHistoryColumns(true)).doesNotContain("zing");
container_1_1().registerPendingHistoryDropColumns(base);
assertThat(table.allHistoryColumns(true)).contains("zing");
assertThat(table.allHistoryColumns(false)).doesNotContain("zing");
}
@Test
public void apply_when_pendingDropsApplied_then_droppedTableNotInHistory() throws Exception {
ModelContainer container = container_1_1();
container.apply(mig("1.1_2__drops.model.xml"), ver("1.1_2"));
ModelContainer base = container_1_1();
container.registerPendingHistoryDropColumns(base);
assertThat(base.getTable("document").allHistoryColumns(false)).doesNotContain("zing");
assertThat(base.getTable("document").allHistoryColumns(true)).doesNotContain("zing");
}
@Test
public void apply_when_apply_partial_pendingDrops_then_some_remainder() throws Exception {
ModelContainer container = container_2_1();
container.apply(mig("2.2__drops.model.xml"), ver("2.2"));
ModelContainer base = container_2_1();
container.registerPendingHistoryDropColumns(base);
List<String> normalColumns = base.getTable("document").allHistoryColumns(false);
List<String> historyColumns = base.getTable("document").allHistoryColumns(true);
assertThat(historyColumns).contains("zong","boom","baz","bar");
assertThat(normalColumns).doesNotContain("zing","zong","boom","baz","bar");
}
@NotNull
private ModelContainer container_2_1() {
ModelContainer container = new ModelContainer();
container.apply(mig("2.0.model.xml"), ver("2.0"));
container.apply(mig("2.1.model.xml"), ver("2.1"));
return container;
}
@NotNull
private ModelContainer container_1_1() {
ModelContainer container = new ModelContainer();
container.apply(mig("1.0.model.xml"), ver("1.0"));
container.apply(mig("1.1.model.xml"), ver("1.1"));
return container;
}
private MigrationVersion ver(String version) {
return MigrationVersion.parse(version);
}
private Migration mig(String path) {
return MigrationXmlReader.read(ModelContainerTest.class.getResourceAsStream(path));
}
}
@@ -0,0 +1,27 @@
package com.avaje.ebean.dbmigration.model;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class ModelDiffTest {
@Test
public void test_compareTo_with_dropColumnOnHistoryTable_then_historyColumnRegistered() throws Exception {
ModelContainer base = new ModelContainer();
base.addTable(MTableTest.base().setWithHistory(true));
ModelContainer newModel = new ModelContainer();
newModel.addTable(MTableTest.newTable().setWithHistory(true));
ModelDiff diff = new ModelDiff(base);
diff.compareTo(newModel);
MTable tab = newModel.getTable("tab");
assertThat(tab.allHistoryColumns(true)).contains("status");
assertThat(tab.allColumns()).extracting("name").doesNotContain("status");
}
}
@@ -13,63 +13,80 @@ import static org.assertj.core.api.Assertions.assertThat;
public class PendingDropsTest {
@Test
public void testAdd() throws Exception {
static final MigrationVersion V1_1 = MigrationVersion.parse("1.1");
ChangeSet cs = new ChangeSet();
static final MigrationVersion V1_2 = MigrationVersion.parse("1.2");
@Test
public void test_add() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
pendingDrops.add(MigrationVersion.parse("1.1"), cs);
pendingDrops.add(V1_1, new ChangeSet());
}
@Test
public void test_add_appliedDropsFor() throws Exception {
public void test_appliedDropsFor_when_matchesSome_then_removesMatched() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
assertThat(pendingDrops.pendingDrops()).isEmpty();
pendingDrops.add(MigrationVersion.parse("1.1"), new ChangeSet());
assertThat(pendingDrops.pendingDrops()).containsExactly("1.1");
DropColumn one = col("one");
DropColumn two = col("two");
pendingDrops.add(V1_1, changeSet(one,two));
pendingDrops.add(V1_1, changeSet("three","four"));
assertThat(pendingDrops.testGetEntryFor(V1_1).list).asList().hasSize(2);
pendingDrops.appliedDropsFor(MigrationVersion.parse("1_1"));
assertThat(pendingDrops.pendingDrops()).isEmpty();
ChangeSet applied = changeSet("two");
applied.setDropsFor("1.1");
assertThat(pendingDrops.appliedDropsFor(applied)).isFalse();
assertThat(pendingDrops.testGetEntryFor(V1_1).list).asList().hasSize(2);
assertThat(pendingDrops.testGetEntryFor(V1_1).list.get(0).getChangeSetChildren()).asList().containsExactly(one);
}
@Test
public void test_add_appliedDropsFor_whenSuppressed() throws Exception {
public void test_appliedDropsFor_when_matchesAll_then_removesChangeSet() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
assertThat(pendingDrops.pendingDrops()).isEmpty();
pendingDrops.add(MigrationVersion.parse("1.1"), newSuppressForeverChangeSet());
assertThat(pendingDrops.pendingDrops()).isEmpty();
DropColumn one = col("one");
DropColumn two = col("two");
pendingDrops.add(V1_1, changeSet(one,two));
pendingDrops.add(V1_1, changeSet("three","four"));
assertThat(pendingDrops.testGetEntryFor(V1_1).list).asList().hasSize(2);
pendingDrops.appliedDropsFor(MigrationVersion.parse("1_1"));
ChangeSet applied = changeSet("two","one");
applied.setDropsFor("1.1");
assertThat(pendingDrops.appliedDropsFor(applied)).isFalse();
assertThat(pendingDrops.testGetEntryFor(V1_1).list).asList().hasSize(1);
}
@Test
public void test_add_appliedDropsFor_whenBoth() throws Exception {
public void test_appliedDropsFor_when_changeSetSuppressed_isIgnored() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
assertThat(pendingDrops.pendingDrops()).isEmpty();
pendingDrops.add(MigrationVersion.parse("1.1"), newSuppressForeverChangeSet());
pendingDrops.add(MigrationVersion.parse("1.1"), new ChangeSet());
assertThat(pendingDrops.pendingDrops()).containsExactly("1.1");
DropColumn one = col("one");
ChangeSet changeSet = changeSet(one);
changeSet.setSuppressDropsForever(true);
pendingDrops.add(V1_1, changeSet);
pendingDrops.appliedDropsFor(MigrationVersion.parse("1_1"));
assertThat(pendingDrops.pendingDrops()).isEmpty();
ChangeSet applied = changeSet("one");
applied.setDropsFor("1.1");
assertThat(pendingDrops.appliedDropsFor(applied)).isFalse();
assertThat(pendingDrops.testGetEntryFor(V1_1).list).asList().hasSize(1);
}
@Test
public void test_pendingDrops() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
assertThat(pendingDrops.pendingDrops()).isEmpty();
pendingDrops.add(MigrationVersion.parse("1.1"), new ChangeSet());
pendingDrops.add(MigrationVersion.parse("1.2"), new ChangeSet());
pendingDrops.add(V1_1, new ChangeSet());
pendingDrops.add(V1_2, new ChangeSet());
assertThat(pendingDrops.pendingDrops()).containsExactly("1.1", "1.2");
}
@@ -79,10 +96,10 @@ public class PendingDropsTest {
PendingDrops pendingDrops = new PendingDrops();
assertThat(pendingDrops.pendingDrops()).isEmpty();
pendingDrops.add(MigrationVersion.parse("1.1"), newSuppressForeverChangeSet());
pendingDrops.add(V1_1, newSuppressForeverChangeSet());
assertThat(pendingDrops.pendingDrops()).isEmpty();
pendingDrops.add(MigrationVersion.parse("1.2"), new ChangeSet());
pendingDrops.add(V1_2, new ChangeSet());
assertThat(pendingDrops.pendingDrops()).containsExactly("1.2");
}
@@ -92,29 +109,23 @@ public class PendingDropsTest {
PendingDrops pendingDrops = new PendingDrops();
assertThat(pendingDrops.pendingDrops()).isEmpty();
pendingDrops.add(MigrationVersion.parse("1.1"), newSuppressForeverChangeSet());
pendingDrops.add(MigrationVersion.parse("1.1"), new ChangeSet());
pendingDrops.add(V1_1, newSuppressForeverChangeSet());
pendingDrops.add(V1_1, new ChangeSet());
assertThat(pendingDrops.pendingDrops()).containsExactly("1.1");
pendingDrops.add(MigrationVersion.parse("1.2"), new ChangeSet());
pendingDrops.add(V1_2, new ChangeSet());
assertThat(pendingDrops.pendingDrops()).containsExactly("1.1", "1.2");
pendingDrops.appliedDropsFor(MigrationVersion.parse("1_1"));
assertThat(pendingDrops.pendingDrops()).containsExactly("1.2");
pendingDrops.appliedDropsFor(MigrationVersion.parse("1_2"));
assertThat(pendingDrops.pendingDrops()).isEmpty();
}
@Test
public void testMigrationForVersion() throws Exception {
public void test_migrationForVersion() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
ChangeSet applyDropChangeSet1 = new ChangeSet();
ChangeSet applyDropChangeSet2 = new ChangeSet();
MigrationVersion version = MigrationVersion.parse("1.1");
MigrationVersion version = V1_1;
pendingDrops.add(version, applyDropChangeSet1);
pendingDrops.add(version, applyDropChangeSet2);
@@ -125,12 +136,12 @@ public class PendingDropsTest {
}
@Test
public void testMigrationForVersion_when_both() throws Exception {
public void test_migrationForVersion_when_both() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
ChangeSet applyDropChangeSet = new ChangeSet();
MigrationVersion version = MigrationVersion.parse("1.1");
MigrationVersion version = V1_1;
pendingDrops.add(version, newSuppressForeverChangeSet());
pendingDrops.add(version, applyDropChangeSet);
@@ -141,10 +152,10 @@ public class PendingDropsTest {
}
@Test
public void testMigrationForVersion_when_next() throws Exception {
public void test_migrationForVersion_when_next() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
MigrationVersion version = MigrationVersion.parse("1.1");
MigrationVersion version = V1_1;
ChangeSet applyDropChangeSet = new ChangeSet();
pendingDrops.add(version, newSuppressForeverChangeSet());
@@ -157,63 +168,79 @@ public class PendingDropsTest {
}
@Test(expected = IllegalArgumentException.class)
public void testMigrationForVersion_when_next_isSuppressForever() throws Exception {
public void test_migrationForVersion_when_next_isSuppressForever() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
pendingDrops.add(MigrationVersion.parse("1.1"), newSuppressForeverChangeSet());
pendingDrops.add(V1_1, newSuppressForeverChangeSet());
pendingDrops.migrationForVersion("next");
}
@Test(expected = IllegalArgumentException.class)
public void testMigrationForVersion_when_doesNotExist() throws Exception {
public void test_migrationForVersion_when_doesNotExist() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
pendingDrops.migrationForVersion("1_1");
}
@Test(expected = IllegalArgumentException.class)
public void testMigrationForVersion_when_next_doesNotExist() throws Exception {
public void test_migrationForVersion_when_next_doesNotExist() throws Exception {
PendingDrops pendingDrops = new PendingDrops();
pendingDrops.migrationForVersion("next");
}
@Test
public void test_registerPendingHistoryDropColumns() throws Exception {
TDModelContainer modelContainer = new TDModelContainer();
DropColumn drop1 = col("one");
drop1.setWithHistory(Boolean.TRUE);
DropColumn drop2 = col("two");
ChangeSet changeSet = changeSet(drop1, drop2);
PendingDrops pendingDrops = new PendingDrops();
pendingDrops.add(V1_1, changeSet);
pendingDrops.registerPendingHistoryDropColumns(modelContainer);
assertThat(modelContainer.drops).containsExactly(changeSet);
}
class TDModelContainer extends ModelContainer {
List<ChangeSet> drops = new ArrayList<ChangeSet>();
@Override
public void registerPendingHistoryDropColumns(ChangeSet changeSet) {
drops.add(changeSet);
}
}
private ChangeSet newSuppressForeverChangeSet() {
ChangeSet changeSet = new ChangeSet();
changeSet.setSuppressDropsForever(Boolean.TRUE);
return changeSet;
}
static ChangeSet changeSet(String... colNames) {
return EntryTest.changeSet(colNames);
}
@Test
public void testRegisterPendingHistoryDropColumns() throws Exception {
TDModelContainer modelContainer = new TDModelContainer();
DropColumn drop1 = new DropColumn();
drop1.setWithHistory(Boolean.TRUE);
DropColumn drop2 = new DropColumn();
static ChangeSet changeSet(DropColumn... drops) {
ChangeSet changeSet = new ChangeSet();
changeSet.getChangeSetChildren().add(drop1);
changeSet.getChangeSetChildren().add(drop2);
PendingDrops pendingDrops = new PendingDrops();
pendingDrops.add(MigrationVersion.parse("1.1"), changeSet);
pendingDrops.registerPendingHistoryDropColumns(modelContainer);
assertThat(modelContainer.drops).containsExactly(drop1);
}
class TDModelContainer extends ModelContainer {
List<DropColumn> drops = new ArrayList<DropColumn>();
@Override
public void registerPendingDropColumn(DropColumn dropColumn) {
drops.add(dropColumn);
for (DropColumn dropColumn : drops) {
changeSet.getChangeSetChildren().add(dropColumn);
}
return changeSet;
}
static DropColumn col(String colName) {
return EntryTest.col(colName);
}
}
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<createTable name="document" withHistory="true" pkName="pk_document">
<column name="id" type="bigint" primaryKey="true" references="document_draft.id" foreignKeyName="fk_document_id"/>
<column name="title" type="varchar(255)" unique="uq_document_title"/>
<column name="body" type="varchar(255)"/>
<column name="zing" type="varchar(255)"/>
<column name="zong" type="varchar(255)"/>
<column name="version" type="bigint" notnull="true"/>
<column name="when_created" type="timestamp" notnull="true"/>
<column name="when_modified" type="timestamp" notnull="true"/>
</createTable>
</changeSet>
</migration>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<addColumn tableName="document" withHistory="true">
<column name="boom" type="varchar(255)"/>
<column name="baz" type="varchar(255)"/>
<column name="bar" type="varchar(255)"/>
</addColumn>
</changeSet>
<changeSet type="pendingDrops">
<dropColumn columnName="zing" tableName="document" withHistory="true"/>
</changeSet>
</migration>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply" dropsFor="1.1">
<dropColumn columnName="zing" tableName="document" withHistory="true"/>
</changeSet>
</migration>
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<createTable name="document" withHistory="true" pkName="pk_document">
<column name="id" type="bigint" primaryKey="true" references="document_draft.id" foreignKeyName="fk_document_id"/>
<column name="title" type="varchar(255)" unique="uq_document_title"/>
<column name="body" type="varchar(255)"/>
<column name="boom" type="varchar(255)"/>
<column name="baz" type="varchar(255)"/>
<column name="bar" type="varchar(255)"/>
<column name="zing" type="varchar(255)"/>
<column name="zong" type="varchar(255)"/>
<column name="version" type="bigint" notnull="true"/>
<column name="when_created" type="timestamp" notnull="true"/>
<column name="when_modified" type="timestamp" notnull="true"/>
</createTable>
</changeSet>
</migration>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="pendingDrops" suppressDropsForever="true">
<dropColumn columnName="boom" tableName="document" withHistory="true"/>
<dropColumn columnName="baz" tableName="document" withHistory="true"/>
<dropColumn columnName="bar" tableName="document" withHistory="true"/>
</changeSet>
<changeSet type="pendingDrops">
<dropColumn columnName="zing" tableName="document" withHistory="true"/>
<dropColumn columnName="zong" tableName="document" withHistory="true"/>
</changeSet>
</migration>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply" dropsFor="2.1">
<dropColumn columnName="zing" tableName="document" withHistory="true"/>
</changeSet>
</migration>