mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#374 - Update ModelDiff and migration generation
This commit is contained in:
@@ -14,8 +14,10 @@ import com.avaje.ebean.config.dbplatform.MySqlPlatform;
|
||||
import com.avaje.ebean.config.dbplatform.Oracle10Platform;
|
||||
import com.avaje.ebean.config.dbplatform.PostgresPlatform;
|
||||
import com.avaje.ebean.config.dbplatform.SQLitePlatform;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
import com.avaje.ebean.dbmigration.model.CurrentModel;
|
||||
import com.avaje.ebean.dbmigration.model.MConfiguration;
|
||||
import com.avaje.ebean.dbmigration.model.MigrationModel;
|
||||
import com.avaje.ebean.dbmigration.model.ModelContainer;
|
||||
import com.avaje.ebean.dbmigration.model.ModelDdlWriter;
|
||||
@@ -83,6 +85,9 @@ public class DbMigration {
|
||||
|
||||
public void runMigration() throws IOException {
|
||||
|
||||
// use this flag to stop other plugins like full DDL generation
|
||||
DbOffline.setRunningMigration();
|
||||
|
||||
setDefaults();
|
||||
|
||||
try {
|
||||
@@ -99,13 +104,20 @@ public class DbMigration {
|
||||
diff.compareTo(current);
|
||||
Migration dbMigration = diff.getMigration();
|
||||
|
||||
// writer needs the current model to provide table/column details for
|
||||
// history ddl generation (triggers, history tables etc)
|
||||
DdlWrite write = new DdlWrite(new MConfiguration(), currentModel.read());
|
||||
|
||||
ModelDdlWriter writer = new ModelDdlWriter(databasePlatform, serverConfig);
|
||||
writer.processMigration(dbMigration);
|
||||
if (!writer.processMigration(dbMigration, write)) {
|
||||
logger.info("no changes detected - no migration written");
|
||||
|
||||
File writePath = getWritePath();
|
||||
|
||||
logger.info("migration writing version {} to {}", nextMajorVersion, writePath.getAbsolutePath());
|
||||
writer.writeMigration(writePath, nextMajorVersion);
|
||||
} else {
|
||||
// there were actually changes to write
|
||||
File writePath = getWritePath();
|
||||
logger.info("migration writing version {} to {}", nextMajorVersion, writePath.getAbsolutePath());
|
||||
writer.writeMigration(writePath, nextMajorVersion);
|
||||
}
|
||||
|
||||
} finally {
|
||||
DbOffline.reset();
|
||||
@@ -114,7 +126,6 @@ public class DbMigration {
|
||||
|
||||
protected void setDefaults() {
|
||||
if (server == null) {
|
||||
String set = DbOffline.getPlatform();
|
||||
setServer(Ebean.getDefaultServer());
|
||||
}
|
||||
if (databasePlatform == null) {
|
||||
|
||||
@@ -13,6 +13,8 @@ public class DbOffline {
|
||||
|
||||
private static final String KEY = "ebean.dboffline";
|
||||
|
||||
private static boolean runningMigration;
|
||||
|
||||
public static void setPlatform(DbPlatformName dbPlatform) {
|
||||
System.setProperty(KEY, dbPlatform.name());
|
||||
}
|
||||
@@ -33,8 +35,29 @@ public class DbOffline {
|
||||
return getPlatform() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the migration is runing. This typically means don't run the
|
||||
* plugins like full DDL generation.
|
||||
*/
|
||||
public static boolean isRunningMigration() {
|
||||
return runningMigration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the migration is running is order to stop other plugins
|
||||
* like the full DDL generation from executing.
|
||||
*/
|
||||
public static void setRunningMigration() {
|
||||
runningMigration = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the offline platform and runningMigration flag.
|
||||
*/
|
||||
public static void reset() {
|
||||
runningMigration = false;
|
||||
System.clearProperty(KEY);
|
||||
logger.info("reset");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -121,6 +121,12 @@ public class BaseTableDdl implements TableDdl {
|
||||
|
||||
writeUniqueOneToOneConstraints(writer, createTable);
|
||||
|
||||
if (isTrue(createTable.isWithHistory())) {
|
||||
// create history with rollback before the
|
||||
// associated drop table is written to rollback
|
||||
createWithHistory(writer, createTable.getName());
|
||||
}
|
||||
|
||||
// add drop table to the rollback buffer - do this before
|
||||
// we drop the related sequence (if sequences are used)
|
||||
dropTable(writer.rollback(), tableName);
|
||||
@@ -136,10 +142,6 @@ public class BaseTableDdl implements TableDdl {
|
||||
|
||||
writeAddForeignKeys(writer, createTable);
|
||||
|
||||
if (isTrue(createTable.isWithHistory())) {
|
||||
createWithHistory(writer, createTable.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,6 +505,70 @@ public class BaseTableDdl implements TableDdl {
|
||||
alterColumnAddUniqueOneToOneConstraint(writer, alterColumn);
|
||||
}
|
||||
|
||||
boolean alterBaseAttributes = false;
|
||||
if (hasValue(alterColumn.getType())) {
|
||||
alterColumnType(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (hasValue(alterColumn.getDefaultValue())) {
|
||||
alterColumnDefaultValue(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (alterColumn.isNotnull() != null) {
|
||||
alterColumnNotnull(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
|
||||
if (alterBaseAttributes) {
|
||||
alterColumnBaseAttributes(writer, alterColumn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is mysql specific - alter all the base attributes of the column together.
|
||||
*/
|
||||
protected void alterColumnBaseAttributes(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
String ddl = platformDdl.alterColumnBaseAttributes(alter);
|
||||
if (hasValue(ddl)) {
|
||||
writer.apply().append(ddl).endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String defaultValue = alter.getDefaultValue();
|
||||
|
||||
String ddl = platformDdl.alterColumnDefaultValue(tableName, columnName, defaultValue);
|
||||
if (hasValue(ddl)) {
|
||||
writer.apply().append(ddl).endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
Boolean notnull = alter.isNotnull();
|
||||
|
||||
String ddl = platformDdl.alterColumnNotnull(tableName, columnName, notnull);
|
||||
if (hasValue(ddl)) {
|
||||
writer.apply().append(ddl).endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
protected void alterColumnType(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String type = alter.getType();
|
||||
|
||||
String ddl = platformDdl.alterColumnType(tableName, columnName, type);
|
||||
if (hasValue(ddl)) {
|
||||
writer.apply().append(ddl).endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
protected void alterColumnAddForeignKey(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbIdentity;
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
|
||||
/**
|
||||
* MS SQL Server platform specific DDL.
|
||||
@@ -48,4 +49,27 @@ public class MsSqlServerDdl extends PlatformDdl {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String notnullClause = notnull ? " not null" : "";
|
||||
|
||||
return "alter table " + tableName + " alter column " + columnName + " " + type + notnullClause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbIdentity;
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
|
||||
/**
|
||||
* MySql specific DDL.
|
||||
@@ -10,6 +11,7 @@ public class MySqlDdl extends PlatformDdl {
|
||||
|
||||
public MySqlDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) {
|
||||
super(platformTypes, dbIdentity);
|
||||
this.alterColumn = "modify";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,4 +30,36 @@ public class MySqlDdl extends PlatformDdl {
|
||||
return "alter table " + tableName + " drop foreign key " + fkName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
|
||||
String suffix = isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + defaultValue;
|
||||
|
||||
// use alter
|
||||
return "alter table " + tableName + " alter " + columnName + " " + suffix;
|
||||
}
|
||||
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String notnullClause = notnull ? " not null" : "";
|
||||
|
||||
// use modify
|
||||
return "alter table " + tableName + " modify " + columnName + " " + type + notnullClause;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ public class Oracle10Ddl extends PlatformDdl {
|
||||
this.dropSequenceIfExists = "drop sequence ";
|
||||
this.dropTableCascade = " cascade constraints purge";
|
||||
this.foreignKeyRestrict = "";
|
||||
this.alterColumn = "modify";
|
||||
this.columnSetNotnull = "not null";
|
||||
this.columnSetNull = "null";
|
||||
this.columnSetDefault = "default";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.avaje.ebean.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.util.PlatformTypeConverter;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.util.VowelRemover;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.IdentityType;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
@@ -52,6 +51,19 @@ public class PlatformDdl {
|
||||
|
||||
protected String dropIndexIfExists = "drop index if exists ";
|
||||
|
||||
|
||||
protected String alterColumn = "alter column";
|
||||
|
||||
protected String columnSetType = "";
|
||||
|
||||
protected String columnSetDefault = "set default";
|
||||
|
||||
protected String columnDropDefault = "drop default";
|
||||
|
||||
protected String columnSetNotnull = "set not null";
|
||||
|
||||
protected String columnSetNull = "set null";
|
||||
|
||||
/**
|
||||
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
|
||||
*/
|
||||
@@ -171,4 +183,32 @@ public class PlatformDdl {
|
||||
public void historyIncludeColumn(DdlWrite writer, AlterColumn alterColumn) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + columnSetType + type;
|
||||
}
|
||||
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
|
||||
String suffix = notnull ? columnSetNotnull : columnSetNull;
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix;
|
||||
}
|
||||
|
||||
public boolean isDropDefault(String defaultValue) {
|
||||
return "DROP DEFAULT".equals(defaultValue);
|
||||
}
|
||||
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
|
||||
String suffix = isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + defaultValue;
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix;
|
||||
}
|
||||
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
// by default do nothing, only used by mysql as it can only modify the column with the
|
||||
// full column definition
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ public class PostgresDdl extends PlatformDdl {
|
||||
super(platformTypes, dbIdentity);
|
||||
this.historyDdl = new PostgresHistoryDdl();
|
||||
this.dropTableCascade = " cascade";
|
||||
this.columnSetType = "type ";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+45
-31
@@ -36,93 +36,108 @@ public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
|
||||
String baseTable = table.getName();
|
||||
|
||||
// rollback trigger then function
|
||||
DdlBuffer rollback = writer.rollback();
|
||||
rollback.append("drop trigger if exists ").append(triggerName(baseTable)).append(" on ").append(baseTable).append(" cascade").endOfStatement();
|
||||
rollback.append("drop function if exists ").append(procedureName(baseTable)).append("()").endOfStatement();
|
||||
rollback.end();
|
||||
|
||||
addHistoryTable(writer, table);
|
||||
addStoredFunction(writer, table);
|
||||
addTrigger(writer, table);
|
||||
}
|
||||
|
||||
protected String normalise(String tableName) {
|
||||
return constraintNaming.normaliseTable(tableName);
|
||||
}
|
||||
|
||||
protected String historyTableName(String baseTableName) {
|
||||
return baseTableName + historySuffix;
|
||||
return normalise(baseTableName) + historySuffix;
|
||||
}
|
||||
|
||||
protected String procedureName(String baseTableName) {
|
||||
return baseTableName + "_history_version";
|
||||
return normalise(baseTableName) + "_history_version";
|
||||
}
|
||||
|
||||
protected String triggerName(String baseTableName) {
|
||||
return baseTableName + "_history_upd";
|
||||
return normalise(baseTableName) + "_history_upd";
|
||||
}
|
||||
|
||||
public void addHistoryTable(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = constraintNaming.normaliseTable(table.getName());
|
||||
String baseTableName = table.getName();
|
||||
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
DdlBuffer apply = writer.applyHistory();
|
||||
|
||||
buffer
|
||||
apply
|
||||
.append("alter table ").append(baseTableName)
|
||||
.append(" add column ").append(sysPeriod).append(" tstzrange not null")
|
||||
.endOfStatement().end();
|
||||
.endOfStatement();
|
||||
|
||||
buffer
|
||||
apply
|
||||
.append("create table ").append(baseTableName).append(historySuffix)
|
||||
.append(" (like ").append(baseTableName).append(")")
|
||||
.endOfStatement().end();
|
||||
.endOfStatement();
|
||||
|
||||
buffer
|
||||
apply
|
||||
.append("create view ").append(baseTableName).append(viewSuffix)
|
||||
.append(" as select * from").append(baseTableName)
|
||||
.append(" union all select * from").append(baseTableName).append(historySuffix)
|
||||
.append(" as select * from ").append(baseTableName)
|
||||
.append(" union all select * from ").append(baseTableName).append(historySuffix)
|
||||
.endOfStatement().end();
|
||||
|
||||
// rollback changes in appropriate order
|
||||
DdlBuffer rollback = writer.rollback();
|
||||
rollback.append("drop view ").append(baseTableName).append(viewSuffix).endOfStatement();
|
||||
rollback.append("alter table ").append(baseTableName).append(" drop column ").append(sysPeriod).endOfStatement();
|
||||
rollback.append("drop table ").append(baseTableName).append(historySuffix).endOfStatement().end();
|
||||
}
|
||||
|
||||
public void addTrigger(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = constraintNaming.normaliseTable(table.getName());
|
||||
String baseTableName = table.getName();
|
||||
String procedureName = procedureName(baseTableName);
|
||||
String triggerName = triggerName(baseTableName);
|
||||
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
buffer
|
||||
DdlBuffer apply = writer.applyHistory();
|
||||
apply
|
||||
.append("create trigger ").append(triggerName).newLine()
|
||||
.append(" before insert or update or delete on ").append(baseTableName).newLine()
|
||||
.append(" for each row execute procedure ").append(procedureName).append("();").newLine().newLine();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addStoredFunction(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = constraintNaming.normaliseTable(table.getName());
|
||||
String procedureName = procedureName(baseTableName);
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
String procedureName = procedureName(table.getName());
|
||||
|
||||
buffer
|
||||
DdlBuffer apply = writer.applyHistory();
|
||||
apply
|
||||
.append("create or replace function ").append(procedureName).append("() returns trigger as $$").newLine()
|
||||
.append("begin").newLine();
|
||||
buffer
|
||||
apply
|
||||
.append(" if (TG_OP = 'INSERT') then").newLine()
|
||||
.append(" NEW.").append(sysPeriod).append(" = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" return new;").newLine().newLine();
|
||||
buffer
|
||||
apply
|
||||
.append(" elsif (TG_OP = 'UPDATE') then").newLine();
|
||||
appendInsertIntoHistory(buffer, table);
|
||||
buffer
|
||||
appendInsertIntoHistory(apply, table);
|
||||
apply
|
||||
.append(" NEW.").append(sysPeriod).append(" = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" return new;").newLine().newLine();
|
||||
buffer
|
||||
apply
|
||||
.append(" elsif (TG_OP = 'DELETE') then").newLine();
|
||||
appendInsertIntoHistory(buffer, table);
|
||||
buffer
|
||||
appendInsertIntoHistory(apply, table);
|
||||
apply
|
||||
.append(" return old;").newLine().newLine();
|
||||
|
||||
buffer
|
||||
apply
|
||||
.append(" end if;").newLine()
|
||||
.append("end;").newLine()
|
||||
.append("$$ LANGUAGE plpgsql;").newLine();
|
||||
|
||||
buffer.end();
|
||||
apply.end();
|
||||
}
|
||||
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, MTable table) throws IOException {
|
||||
@@ -138,7 +153,6 @@ public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
protected void appendColumnNames(DdlBuffer buffer, MTable table, String columnPrefix) throws IOException {
|
||||
|
||||
//id, line1, line2, city, country_code, version, when_created, when_updated
|
||||
Collection<MColumn> columns = table.getColumns().values();
|
||||
int i = 0;
|
||||
for (MColumn column : columns) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}column" maxOccurs="unbounded"/>
|
||||
* </sequence>
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
@@ -42,6 +43,8 @@ public class AddColumn {
|
||||
protected List<Column> column;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
|
||||
/**
|
||||
* Gets the value of the column property.
|
||||
@@ -96,4 +99,28 @@ public class AddColumn {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the withHistory property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the withHistory property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setWithHistory(Boolean value) {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,13 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="columnName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="currentType" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="defaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="currentDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="currentNotnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="checkConstraintName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
@@ -50,12 +54,20 @@ public class AlterColumn {
|
||||
protected String columnName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
@XmlAttribute(name = "type")
|
||||
protected String type;
|
||||
@XmlAttribute(name = "currentType")
|
||||
protected String currentType;
|
||||
@XmlAttribute(name = "defaultValue")
|
||||
protected String defaultValue;
|
||||
@XmlAttribute(name = "currentDefaultValue")
|
||||
protected String currentDefaultValue;
|
||||
@XmlAttribute(name = "notnull")
|
||||
protected Boolean notnull;
|
||||
@XmlAttribute(name = "currentNotnull")
|
||||
protected Boolean currentNotnull;
|
||||
@XmlAttribute(name = "historyExclude")
|
||||
protected Boolean historyExclude;
|
||||
@XmlAttribute(name = "checkConstraint")
|
||||
@@ -129,6 +141,30 @@ public class AlterColumn {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the withHistory property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the withHistory property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setWithHistory(Boolean value) {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the type property.
|
||||
*
|
||||
@@ -153,6 +189,30 @@ public class AlterColumn {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the currentType property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCurrentType() {
|
||||
return currentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the currentType property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCurrentType(String value) {
|
||||
this.currentType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the defaultValue property.
|
||||
*
|
||||
@@ -177,6 +237,30 @@ public class AlterColumn {
|
||||
this.defaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the currentDefaultValue property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCurrentDefaultValue() {
|
||||
return currentDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the currentDefaultValue property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCurrentDefaultValue(String value) {
|
||||
this.currentDefaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the notnull property.
|
||||
*
|
||||
@@ -201,6 +285,30 @@ public class AlterColumn {
|
||||
this.notnull = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the currentNotnull property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isCurrentNotnull() {
|
||||
return currentNotnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the currentNotnull property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setCurrentNotnull(Boolean value) {
|
||||
this.currentNotnull = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the historyExclude property.
|
||||
*
|
||||
|
||||
@@ -50,7 +50,8 @@ public class ChangeSet {
|
||||
@XmlElement(name = "createTable", type = CreateTable.class),
|
||||
@XmlElement(name = "dropTable", type = DropTable.class),
|
||||
@XmlElement(name = "renameTable", type = RenameTable.class),
|
||||
@XmlElement(name = "createHistoryTable", type = CreateHistoryTable.class),
|
||||
@XmlElement(name = "addHistoryTable", type = AddHistoryTable.class),
|
||||
@XmlElement(name = "dropHistoryTable", type = DropHistoryTable.class),
|
||||
@XmlElement(name = "addColumn", type = AddColumn.class),
|
||||
@XmlElement(name = "dropColumn", type = DropColumn.class),
|
||||
@XmlElement(name = "alterColumn", type = AlterColumn.class),
|
||||
@@ -89,7 +90,8 @@ public class ChangeSet {
|
||||
* {@link CreateTable }
|
||||
* {@link DropTable }
|
||||
* {@link RenameTable }
|
||||
* {@link CreateHistoryTable }
|
||||
* {@link AddHistoryTable }
|
||||
* {@link DropHistoryTable }
|
||||
* {@link AddColumn }
|
||||
* {@link DropColumn }
|
||||
* {@link AlterColumn }
|
||||
|
||||
@@ -158,11 +158,11 @@ public class ObjectFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link CreateHistoryTable }
|
||||
* Create an instance of {@link AddHistoryTable }
|
||||
*
|
||||
*/
|
||||
public CreateHistoryTable createCreateHistoryTable() {
|
||||
return new CreateHistoryTable();
|
||||
public AddHistoryTable createAddHistoryTable() {
|
||||
return new AddHistoryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,6 +173,14 @@ public class ObjectFactory {
|
||||
return new RenameColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AlterHistoryTable }
|
||||
*
|
||||
*/
|
||||
public AlterHistoryTable createAlterHistoryTable() {
|
||||
return new AlterHistoryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Migration }
|
||||
*
|
||||
|
||||
@@ -133,7 +133,7 @@ public class CurrentModel {
|
||||
if (write == null) {
|
||||
ChangeSet createChangeSet = getChangeSet();
|
||||
|
||||
write = new DdlWrite();
|
||||
write = new DdlWrite(new MConfiguration(), model);
|
||||
|
||||
DdlHandler handler = handler();
|
||||
handler.generate(write, createChangeSet);
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.avaje.ebean.dbmigration.migration.Column;
|
||||
public class MColumn {
|
||||
|
||||
private final String name;
|
||||
private final String type;
|
||||
private String type;
|
||||
private String checkConstraint;
|
||||
private String checkConstraintName;
|
||||
private String defaultValue;
|
||||
@@ -30,6 +30,11 @@ public class MColumn {
|
||||
*/
|
||||
private String uniqueOneToOne;
|
||||
|
||||
/**
|
||||
* Temporary variable used when building the alter column changes.
|
||||
*/
|
||||
private AlterColumn alterColumn;
|
||||
|
||||
public MColumn(Column column) {
|
||||
this.name = column.getName();
|
||||
this.type = column.getType();
|
||||
@@ -200,40 +205,57 @@ public class MColumn {
|
||||
return val != null && !val.isEmpty();
|
||||
}
|
||||
|
||||
AlterColumn alterColumn;
|
||||
|
||||
private AlterColumn getAlterColumn(String tableName) {
|
||||
private AlterColumn getAlterColumn(String tableName, boolean tableWithHistory) {
|
||||
if (alterColumn == null) {
|
||||
alterColumn = new AlterColumn();
|
||||
alterColumn.setColumnName(name);
|
||||
alterColumn.setTableName(tableName);
|
||||
if (tableWithHistory) {
|
||||
alterColumn.setWithHistory(Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
return alterColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the column meta data and return true if there is a change that means
|
||||
* the history table column needs
|
||||
|
||||
*/
|
||||
public void compare(ModelDiff modelDiff, MTable table, MColumn newColumn) {
|
||||
|
||||
boolean tableWithHistory = table.isWithHistory();
|
||||
String tableName = table.getName();
|
||||
|
||||
// set to null and check at the end
|
||||
this.alterColumn = null;
|
||||
|
||||
if (different(type, newColumn.type)) {
|
||||
getAlterColumn(tableName).setType(newColumn.type);
|
||||
}
|
||||
boolean changeType = false;
|
||||
boolean changeNotnull = false;
|
||||
|
||||
if (historyExclude != newColumn.historyExclude) {
|
||||
getAlterColumn(tableName).setHistoryExclude(newColumn.historyExclude);
|
||||
getAlterColumn(tableName, tableWithHistory).setHistoryExclude(newColumn.historyExclude);
|
||||
}
|
||||
|
||||
if (different(type, newColumn.type)) {
|
||||
changeType = true;
|
||||
getAlterColumn(tableName, tableWithHistory).setType(newColumn.type);
|
||||
}
|
||||
if (notnull != newColumn.notnull) {
|
||||
getAlterColumn(tableName).setNotnull(newColumn.notnull);
|
||||
changeNotnull = true;
|
||||
getAlterColumn(tableName, tableWithHistory).setNotnull(newColumn.notnull);
|
||||
}
|
||||
if (different(defaultValue, newColumn.defaultValue)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
alter.setDefaultValue(newColumn.defaultValue);
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (newColumn.defaultValue == null) {
|
||||
alter.setDefaultValue("DROP DEFAULT");
|
||||
} else {
|
||||
alter.setDefaultValue(newColumn.defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (different(checkConstraint, newColumn.checkConstraint)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(checkConstraint)) {
|
||||
alter.setDropCheckConstraint(checkConstraintName);
|
||||
}
|
||||
@@ -244,7 +266,7 @@ public class MColumn {
|
||||
}
|
||||
if (different(references, newColumn.references)) {
|
||||
// foreign key change
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(foreignKeyName)) {
|
||||
alter.setDropForeignKey(foreignKeyName);
|
||||
}
|
||||
@@ -260,7 +282,7 @@ public class MColumn {
|
||||
}
|
||||
|
||||
if (different(unique, newColumn.unique)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(unique)) {
|
||||
alter.setDropUnique(unique);
|
||||
}
|
||||
@@ -269,7 +291,7 @@ public class MColumn {
|
||||
}
|
||||
}
|
||||
if (different(uniqueOneToOne, newColumn.uniqueOneToOne)) {
|
||||
AlterColumn alter = getAlterColumn(tableName);
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(uniqueOneToOne)) {
|
||||
alter.setDropUnique(uniqueOneToOne);
|
||||
}
|
||||
@@ -280,6 +302,62 @@ public class MColumn {
|
||||
|
||||
if (alterColumn != null) {
|
||||
modelDiff.addAlterColumn(alterColumn);
|
||||
// we need the current type, notnull together for some db's
|
||||
if (!changeType) {
|
||||
alterColumn.setCurrentType(type);
|
||||
}
|
||||
if (!changeNotnull) {
|
||||
alterColumn.setCurrentNotnull(notnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes based on the AlterColumn request.
|
||||
*/
|
||||
public void apply(AlterColumn alterColumn) {
|
||||
|
||||
if (hasValue(alterColumn.getDropCheckConstraint())) {
|
||||
checkConstraint = null;
|
||||
}
|
||||
if (hasValue(alterColumn.getDropForeignKey())) {
|
||||
foreignKeyName = null;
|
||||
}
|
||||
if (hasValue(alterColumn.getDropForeignKeyIndex())) {
|
||||
foreignKeyIndex = null;
|
||||
}
|
||||
if (hasValue(alterColumn.getDropUnique())) {
|
||||
unique = null;
|
||||
uniqueOneToOne = null;
|
||||
}
|
||||
|
||||
if (hasValue(alterColumn.getType())) {
|
||||
type = alterColumn.getType();
|
||||
}
|
||||
if (hasValue(alterColumn.getDefaultValue())) {
|
||||
defaultValue = alterColumn.getDefaultValue();
|
||||
}
|
||||
if (hasValue(alterColumn.getCheckConstraint())) {
|
||||
checkConstraint = alterColumn.getCheckConstraint();
|
||||
}
|
||||
if (hasValue(alterColumn.getCheckConstraintName())) {
|
||||
checkConstraintName = alterColumn.getCheckConstraintName();
|
||||
}
|
||||
if (hasValue(alterColumn.getUnique())) {
|
||||
unique = alterColumn.getUnique();
|
||||
}
|
||||
if (hasValue(alterColumn.getUniqueOneToOne())) {
|
||||
uniqueOneToOne = alterColumn.getUniqueOneToOne();
|
||||
}
|
||||
if (hasValue(alterColumn.getReferences())) {
|
||||
references = alterColumn.getReferences();
|
||||
}
|
||||
if (hasValue(alterColumn.getForeignKeyName())) {
|
||||
foreignKeyName = alterColumn.getForeignKeyName();
|
||||
}
|
||||
if (hasValue(alterColumn.getForeignKeyIndex())) {
|
||||
foreignKeyIndex = alterColumn.getForeignKeyIndex();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
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.AlterColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.DropHistoryTable;
|
||||
import com.avaje.ebean.dbmigration.migration.IdentityType;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -52,7 +55,7 @@ public class MTable {
|
||||
private int sequenceInitial;
|
||||
private int sequenceAllocate;
|
||||
|
||||
private Boolean withHistory;
|
||||
private boolean withHistory;
|
||||
|
||||
private Map<String, MColumn> columns = new LinkedHashMap<String, MColumn>();
|
||||
|
||||
@@ -71,7 +74,7 @@ public class MTable {
|
||||
this.comment = createTable.getComment();
|
||||
this.tablespace = createTable.getTablespace();
|
||||
this.indexTablespace = createTable.getIndexTablespace();
|
||||
this.withHistory = createTable.isWithHistory();
|
||||
this.withHistory = Boolean.TRUE.equals(createTable.isWithHistory());
|
||||
this.sequenceName = createTable.getSequenceName();
|
||||
this.sequenceInitial = toInt(createTable.getSequenceInitial());
|
||||
this.sequenceAllocate = toInt(createTable.getSequenceAllocate());
|
||||
@@ -97,11 +100,13 @@ public class MTable {
|
||||
createTable.setComment(comment);
|
||||
createTable.setTablespace(tablespace);
|
||||
createTable.setIndexTablespace(indexTablespace);
|
||||
createTable.setWithHistory(withHistory);
|
||||
createTable.setSequenceName(sequenceName);
|
||||
createTable.setSequenceInitial(toBigInteger(sequenceInitial));
|
||||
createTable.setSequenceAllocate(toBigInteger(sequenceAllocate));
|
||||
createTable.setIdentityType(identityType);
|
||||
if (withHistory) {
|
||||
createTable.setWithHistory(Boolean.TRUE);
|
||||
}
|
||||
|
||||
for (MColumn column : this.columns.values()) {
|
||||
createTable.getColumn().add(column.createColumn());
|
||||
@@ -116,6 +121,20 @@ public class MTable {
|
||||
|
||||
public void compare(ModelDiff modelDiff, MTable newTable) {
|
||||
|
||||
if (withHistory != newTable.withHistory) {
|
||||
if (withHistory) {
|
||||
DropHistoryTable dropHistoryTable = new DropHistoryTable();
|
||||
dropHistoryTable.setBaseTable(name);
|
||||
modelDiff.addDropHistoryTable(dropHistoryTable);
|
||||
|
||||
} else {
|
||||
AddHistoryTable addHistoryTable = new AddHistoryTable();
|
||||
addHistoryTable.setBaseTable(name);
|
||||
//addHistoryTable.setWhenCreatedColumn();
|
||||
modelDiff.addAddHistoryTable(addHistoryTable);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: compare indexes?
|
||||
// TODO: compare primary key
|
||||
|
||||
@@ -129,6 +148,8 @@ public class MTable {
|
||||
if (localColumn == null) {
|
||||
diffNewColumn(newColumn);
|
||||
} else {
|
||||
// note that if there are alter column changes in here then
|
||||
// the table withHistory is taken into account
|
||||
localColumn.compare(modelDiff, this, newColumn);
|
||||
mappedColumns.add(newColumn.getName());
|
||||
}
|
||||
@@ -142,9 +163,13 @@ public class MTable {
|
||||
}
|
||||
|
||||
if (addColumn != null) {
|
||||
if (withHistory) {
|
||||
// These addColumns need to occur on the history
|
||||
// table as well as the base table
|
||||
addColumn.setWithHistory(Boolean.TRUE);
|
||||
}
|
||||
modelDiff.addAddColumn(addColumn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,6 +182,19 @@ public class MTable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply AddColumn migration.
|
||||
*/
|
||||
public void apply(AlterColumn alterColumn) {
|
||||
checkTableName(alterColumn.getTableName());
|
||||
String columnName = alterColumn.getColumnName();
|
||||
MColumn existingColumn = columns.get(columnName);
|
||||
if (existingColumn == null) {
|
||||
throw new IllegalStateException("Column ["+columnName+"] does not exist for AlterColumn change?");
|
||||
}
|
||||
existingColumn.apply(alterColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply DropColumn migration.
|
||||
*/
|
||||
@@ -189,10 +227,14 @@ public class MTable {
|
||||
return indexTablespace;
|
||||
}
|
||||
|
||||
public Boolean getWithHistory() {
|
||||
public boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
public void setWithHistory() {
|
||||
withHistory = true;
|
||||
}
|
||||
|
||||
public Map<String, MColumn> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
@@ -62,6 +63,8 @@ public class ModelContainer {
|
||||
for (Object change : changeSetChildren) {
|
||||
if (change instanceof CreateTable) {
|
||||
applyChange((CreateTable) change);
|
||||
} else if (change instanceof AlterColumn) {
|
||||
applyChange((AlterColumn) change);
|
||||
} else if (change instanceof AddColumn) {
|
||||
applyChange((AddColumn) change);
|
||||
} else if (change instanceof DropColumn) {
|
||||
@@ -93,6 +96,17 @@ public class ModelContainer {
|
||||
table.apply(addColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a AddColumn change to the model.
|
||||
*/
|
||||
protected void applyChange(AlterColumn alterColumn) {
|
||||
MTable table = tables.get(alterColumn.getTableName());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("Table [" + alterColumn.getTableName() + "] does not exist in model?");
|
||||
}
|
||||
table.apply(alterColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a DropColumn change to the model.
|
||||
*/
|
||||
|
||||
@@ -27,22 +27,30 @@ public class ModelDdlWriter {
|
||||
|
||||
private DdlWrite write;
|
||||
|
||||
int changeSetCount;
|
||||
|
||||
public ModelDdlWriter(DatabasePlatform platform, ServerConfig serverConfig) {
|
||||
this.platform = platform;
|
||||
this.serverConfig = serverConfig;
|
||||
}
|
||||
|
||||
public void processMigration(Migration dbMigration) throws IOException {
|
||||
public boolean processMigration(Migration dbMigration, DdlWrite write) throws IOException {
|
||||
|
||||
this.changeSetCount = 0;
|
||||
this.dbMigration = dbMigration;
|
||||
this.write = new DdlWrite();
|
||||
this.write = write;
|
||||
|
||||
DdlHandler handler = handler();
|
||||
|
||||
List<ChangeSet> changeSets = dbMigration.getChangeSet();
|
||||
for (ChangeSet changeSet : changeSets) {
|
||||
handler.generate(write, changeSet);
|
||||
if (!changeSet.getChangeSetChildren().isEmpty()) {
|
||||
changeSetCount++;
|
||||
handler.generate(write, changeSet);
|
||||
}
|
||||
}
|
||||
|
||||
return changeSetCount > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
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.AlterColumn;
|
||||
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.DropHistoryTable;
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -31,6 +33,11 @@ public class ModelDiff {
|
||||
*/
|
||||
private final List<Object> dropChanges = new ArrayList<Object>();
|
||||
|
||||
/**
|
||||
* List of 'drop' type changes. Expected to be placed into a separate DDL script.
|
||||
*/
|
||||
private final List<Object> dropHistoryChanges = new ArrayList<Object>();
|
||||
|
||||
/**
|
||||
* Construct with a base model.
|
||||
*/
|
||||
@@ -45,6 +52,27 @@ public class ModelDiff {
|
||||
this.baseModel = new ModelContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the diff as a migration potentially containing
|
||||
* an apply changeSet and a drop changeSet.
|
||||
*/
|
||||
public Migration getMigration() {
|
||||
|
||||
Migration migration = new Migration();
|
||||
ChangeSet applyChangeSet = getApplyChangeSet();
|
||||
if (!applyChangeSet.getChangeSetChildren().isEmpty()) {
|
||||
// add a non empty apply changeSet
|
||||
migration.getChangeSet().add(applyChangeSet);
|
||||
}
|
||||
|
||||
ChangeSet dropChangeSet = getDropChangeSet();
|
||||
if (!dropChangeSet.getChangeSetChildren().isEmpty()) {
|
||||
// add a non empty drop changeSet
|
||||
migration.getChangeSet().add(dropChangeSet);
|
||||
}
|
||||
return migration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of 'create' changes.
|
||||
*/
|
||||
@@ -52,6 +80,16 @@ public class ModelDiff {
|
||||
return createChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of 'drop' changes.
|
||||
*/
|
||||
public List<Object> getDropChanges() {
|
||||
return dropChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 'apply' changeSet.
|
||||
*/
|
||||
public ChangeSet getApplyChangeSet() {
|
||||
// put the changes into a ChangeSet
|
||||
ChangeSet createChangeSet = new ChangeSet();
|
||||
@@ -60,6 +98,9 @@ public class ModelDiff {
|
||||
return createChangeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 'drop' changeSet.
|
||||
*/
|
||||
public ChangeSet getDropChangeSet() {
|
||||
// put the changes into a ChangeSet
|
||||
ChangeSet createChangeSet = new ChangeSet();
|
||||
@@ -68,21 +109,6 @@ public class ModelDiff {
|
||||
return createChangeSet;
|
||||
}
|
||||
|
||||
public Migration getMigration() {
|
||||
|
||||
Migration migration = new Migration();
|
||||
migration.getChangeSet().add(getApplyChangeSet());
|
||||
migration.getChangeSet().add(getDropChangeSet());
|
||||
return migration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of 'drop' changes.
|
||||
*/
|
||||
public List<Object> getDropChanges() {
|
||||
return dropChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a 'newer' model and collect the differences.
|
||||
*/
|
||||
@@ -116,18 +142,41 @@ public class ModelDiff {
|
||||
protected void compareTables(MTable currentTable, MTable newTable) {
|
||||
|
||||
currentTable.compare(this, newTable);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the AlterColumn to the 'apply' changes.
|
||||
*/
|
||||
public void addAlterColumn(AlterColumn alterColumn) {
|
||||
createChanges.add(alterColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the AlterColumn to the 'apply' changes.
|
||||
*/
|
||||
public void addAddColumn(AddColumn addColumn) {
|
||||
createChanges.add(addColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the DropColumn to the 'drop' changes.
|
||||
*/
|
||||
public void addDropColumn(DropColumn dropColumn) {
|
||||
dropChanges.add(dropColumn);
|
||||
}
|
||||
|
||||
public void addAddColumn(AddColumn addColumn) {
|
||||
createChanges.add(addColumn);
|
||||
/**
|
||||
* Add the AddHistoryTable to apply changes.
|
||||
*/
|
||||
public void addAddHistoryTable(AddHistoryTable addHistoryTable) {
|
||||
createChanges.add(addHistoryTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the DropHistoryTable to the 'drop history' changes.
|
||||
*/
|
||||
public void addDropHistoryTable(DropHistoryTable dropHistoryTable) {
|
||||
dropHistoryChanges.add(dropHistoryTable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,9 @@ public class ModelBuildBeanVisitor implements BeanVisitor {
|
||||
}
|
||||
|
||||
MTable table = new MTable(descriptor.getBaseTable());
|
||||
|
||||
if (descriptor.isHistorySupport()) {
|
||||
table.setWithHistory();
|
||||
}
|
||||
setIdentity(descriptor, table);
|
||||
|
||||
// add the table to the model
|
||||
|
||||
@@ -146,7 +146,9 @@ public class DefaultContainer implements SpiContainer {
|
||||
|
||||
// generate and run DDL if required
|
||||
// if there are any other tasks requiring action in their plugins, do them as well
|
||||
server.executePlugins(online);
|
||||
if (!DbOffline.isRunningMigration()) {
|
||||
server.executePlugins(online);
|
||||
}
|
||||
|
||||
// initialise prior to registering with clusterManager
|
||||
server.initialise();
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
<!--<xsd:element ref="application" minOccurs="0" maxOccurs="unbounded"/>-->
|
||||
<!--</xsd:sequence>-->
|
||||
<!--</xsd:complexType>-->
|
||||
<!--</xsd:element>-->
|
||||
|
||||
<!--<xsd:element name="application">-->
|
||||
<!--<xsd:complexType>-->
|
||||
@@ -173,13 +172,19 @@
|
||||
|
||||
<!-- HISTORY -->
|
||||
|
||||
<xsd:element name="createHistoryTable">
|
||||
<xsd:element name="addHistoryTable">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="baseTable" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="whenCreatedColumn" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="alterHistoryTable">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="baseTable" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="dropHistoryTable">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="baseTable" type="xsd:string" use="required"/>
|
||||
@@ -194,6 +199,7 @@
|
||||
<xsd:element ref="column" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="tableName" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="withHistory" type="xsd:boolean"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -208,9 +214,13 @@
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="columnName" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="tableName" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="withHistory" type="xsd:boolean"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="currentType" type="xsd:string"/>
|
||||
<xsd:attribute name="defaultValue" type="xsd:string"/>
|
||||
<xsd:attribute name="currentDefaultValue" type="xsd:string"/>
|
||||
<xsd:attribute name="notnull" type="xsd:boolean"/>
|
||||
<xsd:attribute name="currentNotnull" type="xsd:boolean"/>
|
||||
<xsd:attribute name="historyExclude" type="xsd:boolean"/>
|
||||
<xsd:attribute name="checkConstraint" type="xsd:string"/>
|
||||
<xsd:attribute name="checkConstraintName" type="xsd:string"/>
|
||||
@@ -319,7 +329,8 @@
|
||||
<xsd:element ref="dropTable" maxOccurs="unbounded"/>
|
||||
<xsd:element ref="renameTable" maxOccurs="unbounded"/>
|
||||
|
||||
<xsd:element ref="createHistoryTable" maxOccurs="unbounded"/>
|
||||
<xsd:element ref="addHistoryTable" maxOccurs="unbounded"/>
|
||||
<xsd:element ref="dropHistoryTable" maxOccurs="unbounded"/>
|
||||
|
||||
<xsd:element ref="addColumn" maxOccurs="unbounded"/>
|
||||
<xsd:element ref="dropColumn" maxOccurs="unbounded"/>
|
||||
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.H2Platform;
|
||||
import com.avaje.ebean.config.dbplatform.MsSqlServer2005Platform;
|
||||
import com.avaje.ebean.config.dbplatform.MySqlPlatform;
|
||||
import com.avaje.ebean.config.dbplatform.Oracle10Platform;
|
||||
import com.avaje.ebean.config.dbplatform.PostgresPlatform;
|
||||
import com.avaje.ebean.dbmigration.migration.AlterColumn;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
public class PlatformDdl_AlterColumnTest {
|
||||
|
||||
PlatformDdl h2Ddl = new H2Platform().getPlatformDdl();
|
||||
PlatformDdl pgDdl = new PostgresPlatform().getPlatformDdl();
|
||||
PlatformDdl mysqlDdl = new MySqlPlatform().getPlatformDdl();
|
||||
PlatformDdl oraDdl = new Oracle10Platform().getPlatformDdl();
|
||||
PlatformDdl sqlServerDdl = new MsSqlServer2005Platform().getPlatformDdl();
|
||||
|
||||
|
||||
AlterColumn alterNotNull() {
|
||||
AlterColumn alterColumn = new AlterColumn();
|
||||
alterColumn.setTableName("mytab");
|
||||
alterColumn.setColumnName("acol");
|
||||
alterColumn.setCurrentType("varchar(5)");
|
||||
alterColumn.setNotnull(Boolean.TRUE);
|
||||
|
||||
return alterColumn;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnBaseAttributes() throws Exception {
|
||||
|
||||
AlterColumn alterColumn = alterNotNull();
|
||||
assertNull(h2Ddl.alterColumnBaseAttributes(alterColumn));
|
||||
assertNull(pgDdl.alterColumnBaseAttributes(alterColumn));
|
||||
assertNull(oraDdl.alterColumnBaseAttributes(alterColumn));
|
||||
|
||||
String sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(5) not null", sql);
|
||||
|
||||
sql = sqlServerDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab alter column acol varchar(5) not null", sql);
|
||||
|
||||
alterColumn.setNotnull(Boolean.FALSE);
|
||||
sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(5)", sql);
|
||||
|
||||
alterColumn.setNotnull(null);
|
||||
alterColumn.setType("varchar(100)");
|
||||
|
||||
sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(100)", sql);
|
||||
|
||||
alterColumn.setCurrentNotnull(Boolean.TRUE);
|
||||
sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(100) not null", sql);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnType() throws Exception {
|
||||
|
||||
String sql = h2Ddl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertEquals("alter table mytab alter column acol varchar(20)", sql);
|
||||
|
||||
sql = pgDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertEquals("alter table mytab alter column acol type varchar(20)", sql);
|
||||
|
||||
sql = sqlServerDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertEquals("alter table mytab alter column acol varchar(20)", sql);
|
||||
|
||||
sql = oraDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertEquals("alter table mytab modify acol varchar(20)", sql);
|
||||
|
||||
sql = mysqlDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertNull(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnNotnull() throws Exception {
|
||||
|
||||
String sql = h2Ddl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertEquals("alter table mytab alter column acol set not null", sql);
|
||||
|
||||
sql = pgDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertEquals("alter table mytab alter column acol set not null", sql);
|
||||
|
||||
sql = oraDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertEquals("alter table mytab modify acol not null", sql);
|
||||
|
||||
sql = mysqlDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertNull(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnNull() throws Exception {
|
||||
|
||||
String sql = h2Ddl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertEquals("alter table mytab alter column acol set null", sql);
|
||||
|
||||
sql = pgDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertEquals("alter table mytab alter column acol set null", sql);
|
||||
|
||||
sql = oraDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertEquals("alter table mytab modify acol null", sql);
|
||||
|
||||
sql = mysqlDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertNull(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnDefaultValue() throws Exception {
|
||||
|
||||
String sql = h2Ddl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab alter column acol set default 'hi'", sql);
|
||||
|
||||
sql = pgDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab alter column acol set default 'hi'", sql);
|
||||
|
||||
sql = oraDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab modify acol default 'hi'", sql);
|
||||
|
||||
sql = mysqlDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab alter acol set default 'hi'", sql);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnDropDefault() throws Exception {
|
||||
|
||||
String sql = h2Ddl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab alter column acol drop default", sql);
|
||||
|
||||
sql = pgDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab alter column acol drop default", sql);
|
||||
|
||||
sql = oraDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab modify acol drop default", sql);
|
||||
|
||||
sql = mysqlDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab alter acol drop default", sql);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,7 +35,7 @@ public class ModelContainerApplyTest {
|
||||
assertThat(foo.getComment()).isEqualTo("comment");
|
||||
assertThat(foo.getTablespace()).isEqualTo("fooSpace");
|
||||
assertThat(foo.getIndexTablespace()).isEqualTo("fooIndexSpace");
|
||||
assertThat(foo.getWithHistory()).isEqualTo(true);
|
||||
assertThat(foo.isWithHistory()).isEqualTo(true);
|
||||
assertThat(foo.getColumns()).containsKeys("col1", "col3", "added_to_foo");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user