mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
249 lines
6.5 KiB
Java
249 lines
6.5 KiB
Java
package com.avaje.ebean.dbmigration.model;
|
|
|
|
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
|
import com.avaje.ebean.dbmigration.migration.AddHistoryTable;
|
|
import com.avaje.ebean.dbmigration.migration.AddTableComment;
|
|
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.DropColumn;
|
|
import com.avaje.ebean.dbmigration.migration.DropHistoryTable;
|
|
import com.avaje.ebean.dbmigration.migration.DropIndex;
|
|
import com.avaje.ebean.dbmigration.migration.Migration;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Used to prepare a diff in terms of changes required to migrate from
|
|
* the base model to the newer model.
|
|
*/
|
|
public class ModelDiff {
|
|
|
|
/**
|
|
* The base model to which we compare the newer model.
|
|
*/
|
|
private final ModelContainer baseModel;
|
|
|
|
/**
|
|
* List of 'create' type changes.
|
|
*/
|
|
private final List<Object> applyChanges = new ArrayList<Object>();
|
|
|
|
/**
|
|
* List of 'drop' type changes. Expected to be placed into a separate DDL script.
|
|
*/
|
|
private final List<Object> dropChanges = new ArrayList<Object>();
|
|
|
|
/**
|
|
* Construct with a base model.
|
|
*/
|
|
public ModelDiff(ModelContainer baseModel) {
|
|
this.baseModel = baseModel;
|
|
}
|
|
|
|
/**
|
|
* Construct with a base model.
|
|
*/
|
|
public ModelDiff() {
|
|
this.baseModel = new ModelContainer();
|
|
}
|
|
|
|
|
|
/**
|
|
* Return true if the apply and drop changes are both empty.
|
|
* This means there are no migration changes.
|
|
*/
|
|
public boolean isEmpty() {
|
|
return applyChanges.isEmpty() && dropChanges.isEmpty();
|
|
}
|
|
|
|
/**
|
|
* Return the diff as a migration potentially containing
|
|
* an apply changeSet and a drop changeSet.
|
|
*/
|
|
public Migration getMigration() {
|
|
|
|
Migration migration = new Migration();
|
|
if (!applyChanges.isEmpty()) {
|
|
// add a non empty apply changeSet
|
|
migration.getChangeSet().add(getApplyChangeSet());
|
|
}
|
|
|
|
if (!dropChanges.isEmpty()) {
|
|
// add a non empty drop changeSet
|
|
migration.getChangeSet().add(getDropChangeSet());
|
|
}
|
|
return migration;
|
|
}
|
|
|
|
/**
|
|
* Return the list of 'apply' changes.
|
|
*/
|
|
List<Object> getApplyChanges() {
|
|
return applyChanges;
|
|
}
|
|
|
|
/**
|
|
* Return the list of 'drop' changes.
|
|
*/
|
|
List<Object> getDropChanges() {
|
|
return dropChanges;
|
|
}
|
|
|
|
/**
|
|
* Return the 'apply' changeSet.
|
|
*/
|
|
public ChangeSet getApplyChangeSet() {
|
|
// put the changes into a ChangeSet
|
|
ChangeSet applyChangeSet = new ChangeSet();
|
|
applyChangeSet.setType(ChangeSetType.APPLY);
|
|
applyChangeSet.getChangeSetChildren().addAll(applyChanges);
|
|
return applyChangeSet;
|
|
}
|
|
|
|
/**
|
|
* Return the 'drop' changeSet.
|
|
*/
|
|
ChangeSet getDropChangeSet() {
|
|
// put the changes into a ChangeSet
|
|
ChangeSet createChangeSet = new ChangeSet();
|
|
createChangeSet.setType(ChangeSetType.PENDING_DROPS);
|
|
createChangeSet.getChangeSetChildren().addAll(dropChanges);
|
|
return createChangeSet;
|
|
}
|
|
|
|
/**
|
|
* Compare to a 'newer' model and collect the differences.
|
|
*/
|
|
public void compareTo(ModelContainer newModel) {
|
|
|
|
Map<String, MTable> newTables = newModel.getTables();
|
|
for (MTable newTable : newTables.values()) {
|
|
|
|
MTable currentTable = baseModel.getTable(newTable.getName());
|
|
if (currentTable == null) {
|
|
addNewTable(newTable);
|
|
} else {
|
|
compareTables(currentTable, newTable);
|
|
}
|
|
}
|
|
|
|
// search for tables that are no longer used
|
|
for (MTable existingTable : baseModel.getTables().values()) {
|
|
if (!newTables.containsKey(existingTable.getName())) {
|
|
addDropTable(existingTable);
|
|
}
|
|
}
|
|
|
|
Map<String, MIndex> newIndexes = newModel.getIndexes();
|
|
for (MIndex newIndex : newIndexes.values()) {
|
|
MIndex currentIndex = baseModel.getIndex(newIndex.getIndexName());
|
|
if (currentIndex == null) {
|
|
addCreateIndex(newIndex.createIndex());
|
|
} else {
|
|
compareIndexes(currentIndex, newIndex);
|
|
}
|
|
}
|
|
|
|
// search for indexes that are no longer used
|
|
for (MIndex existingIndex : baseModel.getIndexes().values()) {
|
|
if (!newIndexes.containsKey(existingIndex.getIndexName())) {
|
|
addDropIndex(existingIndex.dropIndex());
|
|
}
|
|
}
|
|
|
|
// 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) {
|
|
dropChanges.add(existingTable.dropTable());
|
|
}
|
|
|
|
/**
|
|
* Add CreateTable to the 'apply' changes.
|
|
*/
|
|
protected void addNewTable(MTable newTable) {
|
|
applyChanges.add(newTable.createTable());
|
|
}
|
|
|
|
/**
|
|
* Compare tables looking for add/drop/modify columns etc.
|
|
*/
|
|
protected void compareTables(MTable currentTable, MTable newTable) {
|
|
|
|
currentTable.compare(this, newTable);
|
|
}
|
|
|
|
/**
|
|
* Compare tables looking for add/drop/modify columns etc.
|
|
*/
|
|
protected void compareIndexes(MIndex currentIndex, MIndex newIndex) {
|
|
|
|
currentIndex.compare(this, newIndex);
|
|
}
|
|
|
|
/**
|
|
* Add the AlterColumn to the 'apply' changes.
|
|
*/
|
|
public void addAlterColumn(AlterColumn alterColumn) {
|
|
applyChanges.add(alterColumn);
|
|
}
|
|
|
|
/**
|
|
* Add the AlterColumn to the 'apply' changes.
|
|
*/
|
|
public void addAddColumn(AddColumn addColumn) {
|
|
applyChanges.add(addColumn);
|
|
}
|
|
|
|
/**
|
|
* Add the DropColumn to the 'drop' changes.
|
|
*/
|
|
public void addDropColumn(DropColumn dropColumn) {
|
|
dropChanges.add(dropColumn);
|
|
}
|
|
|
|
/**
|
|
* Add the AddHistoryTable to apply changes.
|
|
*/
|
|
public void addAddHistoryTable(AddHistoryTable addHistoryTable) {
|
|
applyChanges.add(addHistoryTable);
|
|
}
|
|
|
|
/**
|
|
* Add the DropHistoryTable to the 'drop history' changes.
|
|
*/
|
|
public void addDropHistoryTable(DropHistoryTable dropHistoryTable) {
|
|
dropChanges.add(dropHistoryTable);
|
|
}
|
|
|
|
/**
|
|
* Add the DropIndex to the 'apply' changes.
|
|
*/
|
|
public void addDropIndex(DropIndex dropIndex) {
|
|
applyChanges.add(dropIndex);
|
|
}
|
|
|
|
/**
|
|
* Add the CreateIndex to the 'apply' changes.
|
|
*/
|
|
public void addCreateIndex(CreateIndex createIndex) {
|
|
applyChanges.add(createIndex);
|
|
}
|
|
|
|
/**
|
|
* Add a table comment to the 'apply' changes.
|
|
*/
|
|
public void addTableComment(AddTableComment addTableComment) {
|
|
applyChanges.add(addTableComment);
|
|
}
|
|
}
|