mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
DbMigration supports altering UniqueConstraints and foreign keys (#1279)
* NEW: Ebean reads version from pop.properties and prints it at start up * DDL generation and migration can append a header and platformMigration is prepared to append epilog & prolog to scripts * FIX: Set identity only, if it is not the platform default type * Updated reference scripts * ADD basic support for foreign key migration * DbMigration detects alter foreign keys * tests
This commit is contained in:
committed by
Rob Bygrave
parent
a64a244745
commit
da7bb834e7
@@ -1,6 +1,7 @@
|
||||
package io.ebeaninternal.dbmigration.model;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.DdlHelp;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns;
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AddTableComment;
|
||||
@@ -10,6 +11,7 @@ import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
import io.ebeaninternal.dbmigration.migration.ForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.IdentityType;
|
||||
import io.ebeaninternal.dbmigration.migration.UniqueConstraint;
|
||||
import org.slf4j.Logger;
|
||||
@@ -165,9 +167,36 @@ public class MTable {
|
||||
for (Column column : cols) {
|
||||
addColumn(column);
|
||||
}
|
||||
List<UniqueConstraint> uqConstraints = createTable.getUniqueConstraint();
|
||||
for (UniqueConstraint uq : uqConstraints) {
|
||||
MCompoundUniqueConstraint mUq = new MCompoundUniqueConstraint(
|
||||
SplitColumns.split(uq.getColumnNames()), uq.isOneToOne(), uq.getName());
|
||||
mUq.setNullableColumns(SplitColumns.split(uq.getNullableColumns()));
|
||||
uniqueConstraints.add(mUq);
|
||||
}
|
||||
|
||||
for (ForeignKey fk : createTable.getForeignKey()) {
|
||||
if (DdlHelp.isDropForeignKey(fk.getColumnNames())) {
|
||||
removeForeignKey(fk.getName());
|
||||
} else {
|
||||
addForeignKey(fk.getName(), fk.getRefTableName(), fk.getIndexName(), fk.getColumnNames(), fk.getRefColumnNames());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addForeignKey(String name, String refTableName, String indexName, String columnNames,
|
||||
String refColumnNames) {
|
||||
MCompoundForeignKey foreignKey = new MCompoundForeignKey(name, refTableName, indexName);
|
||||
String[] cols = SplitColumns.split(columnNames);
|
||||
String[] refCols = SplitColumns.split(refColumnNames);
|
||||
for (int i = 0; i < cols.length && i < refCols.length; i++) {
|
||||
foreignKey.addColumnPair(cols[i], refCols[i]);
|
||||
}
|
||||
addForeignKey(foreignKey);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct typically from EbeanServer meta data.
|
||||
*/
|
||||
@@ -236,17 +265,7 @@ public class MTable {
|
||||
}
|
||||
|
||||
for (MCompoundUniqueConstraint constraint : uniqueConstraints) {
|
||||
UniqueConstraint uq = new UniqueConstraint();
|
||||
uq.setName(constraint.getName());
|
||||
String[] columns = constraint.getColumns();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(columns[i]);
|
||||
}
|
||||
uq.setColumnNames(sb.toString());
|
||||
UniqueConstraint uq = constraint.getUniqueConstraint();
|
||||
createTable.getUniqueConstraint().add(uq);
|
||||
}
|
||||
|
||||
@@ -271,6 +290,25 @@ public class MTable {
|
||||
}
|
||||
}
|
||||
|
||||
compareColumns(modelDiff, newTable);
|
||||
|
||||
if (MColumn.different(comment, newTable.comment)) {
|
||||
AddTableComment addTableComment = new AddTableComment();
|
||||
addTableComment.setName(name);
|
||||
if (newTable.comment == null) {
|
||||
addTableComment.setComment(DdlHelp.DROP_COMMENT);
|
||||
} else {
|
||||
addTableComment.setComment(newTable.comment);
|
||||
}
|
||||
modelDiff.addTableComment(addTableComment);
|
||||
}
|
||||
|
||||
|
||||
compareCompoundKeys(modelDiff, newTable);
|
||||
compareUniqueKeys(modelDiff, newTable);
|
||||
}
|
||||
|
||||
private void compareColumns(ModelDiff modelDiff, MTable newTable) {
|
||||
addColumn = null;
|
||||
|
||||
Map<String, MColumn> newColumnMap = newTable.getColumns();
|
||||
@@ -303,16 +341,39 @@ public class MTable {
|
||||
if (addColumn != null) {
|
||||
modelDiff.addAddColumn(addColumn);
|
||||
}
|
||||
}
|
||||
|
||||
if (MColumn.different(comment, newTable.comment)) {
|
||||
AddTableComment addTableComment = new AddTableComment();
|
||||
addTableComment.setName(name);
|
||||
if (newTable.comment == null) {
|
||||
addTableComment.setComment(DdlHelp.DROP_COMMENT);
|
||||
} else {
|
||||
addTableComment.setComment(newTable.comment);
|
||||
}
|
||||
modelDiff.addTableComment(addTableComment);
|
||||
|
||||
private void compareCompoundKeys(ModelDiff modelDiff, MTable newTable) {
|
||||
List<MCompoundForeignKey> newKeys = new ArrayList<>(newTable.getCompoundKeys());
|
||||
List<MCompoundForeignKey> currentKeys = new ArrayList<>(getCompoundKeys());
|
||||
|
||||
// remove keys that have not changed
|
||||
currentKeys.removeAll(newTable.getCompoundKeys());
|
||||
newKeys.removeAll(getCompoundKeys());
|
||||
|
||||
for (MCompoundForeignKey currentKey : currentKeys) {
|
||||
modelDiff.addAlterForeignKey(currentKey.dropForeignKey(name));
|
||||
}
|
||||
|
||||
for (MCompoundForeignKey newKey : newKeys) {
|
||||
modelDiff.addAlterForeignKey(newKey.addForeignKey(name));
|
||||
}
|
||||
}
|
||||
|
||||
private void compareUniqueKeys(ModelDiff modelDiff, MTable newTable) {
|
||||
List<MCompoundUniqueConstraint> newKeys = new ArrayList<>(newTable.getUniqueConstraints());
|
||||
List<MCompoundUniqueConstraint> currentKeys = new ArrayList<>(getUniqueConstraints());
|
||||
|
||||
// remove keys that have not changed
|
||||
currentKeys.removeAll(newTable.getUniqueConstraints());
|
||||
newKeys.removeAll(getUniqueConstraints());
|
||||
|
||||
for (MCompoundUniqueConstraint currentKey: currentKeys) {
|
||||
modelDiff.addUniqueConstraint(currentKey.dropUniqueConstraint(name));
|
||||
}
|
||||
for (MCompoundUniqueConstraint newKey: newKeys) {
|
||||
modelDiff.addUniqueConstraint(newKey.addUniqueConstraint(name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,6 +717,29 @@ public class MTable {
|
||||
return draftTableName + "." + references.substring(lastDot + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds information which columns are nullable or not to the compound indices.
|
||||
*/
|
||||
public void updateCompoundIndices() {
|
||||
for (MCompoundUniqueConstraint uniq : uniqueConstraints) {
|
||||
List<String> nullableColumns = new ArrayList<>();
|
||||
for (String columnName : uniq.getColumns()) {
|
||||
MColumn col = getColumn(columnName);
|
||||
if (col == null) {
|
||||
throw new IllegalStateException("Column '" + columnName + "' not found in table " + getName());
|
||||
}
|
||||
if (!col.isNotnull()) {
|
||||
nullableColumns.add(columnName);
|
||||
}
|
||||
}
|
||||
uniq.setNullableColumns(nullableColumns.toArray(new String[nullableColumns.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeForeignKey(String name) {
|
||||
compoundKeys.removeIf(fk -> fk.getName().equals(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the indexes on the foreign keys as they are covered by unique constraints.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user