#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
@@ -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);
}
}