WIP: Db migration alterColumn ...

This commit is contained in:
Robin Bygrave
2015-08-10 14:26:47 +12:00
parent c0d4dac2b3
commit 845faf74ff
48 changed files with 6924 additions and 424 deletions
File diff suppressed because it is too large Load Diff
+1311
View File
File diff suppressed because it is too large Load Diff
+1311
View File
File diff suppressed because it is too large Load Diff
+1311
View File
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,42 @@
package com.avaje.ebean.config;
/**
* Configuration for the DB migration processing.
*/
public class DbMigrationConfig {
/**
* The application name which is used as the unique code when applying migrations.
*/
private String appName;
/**
* Path where migration
*/
private String resourcePath;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getResourcePath() {
return resourcePath;
}
public void setResourcePath(String resourcePath) {
this.resourcePath = resourcePath;
}
/**
* Load the settings from the PropertiesWrapper.
*/
public void loadSettings(PropertiesWrapper properties) {
appName = properties.get("migration.appName", appName);
resourcePath = properties.get("migration.resourcePath", resourcePath);
}
}
@@ -207,6 +207,11 @@ public class ServerConfig {
*/
private DataSourceConfig dataSourceConfig = new DataSourceConfig();
/**
* The db migration config (migration resource path etc).
*/
private DbMigrationConfig migrationConfig = new DbMigrationConfig();
/**
* Set to true if the DataSource uses autoCommit.
* <p>
@@ -502,7 +507,7 @@ public class ServerConfig {
/**
* Return the JDBC batch mode to use per save(), delete(), insert() or update() request.
* <p>
* This makes sense when a save() or delete() etc cascades and executes multiple child statements. The best caase
* This makes sense when a save() or delete() cascades and executes multiple child statements. The best case
* for this is when saving a master/parent bean this cascade inserts many detail/child beans.
* </p>
* <p>
@@ -620,6 +625,20 @@ public class ServerConfig {
this.databaseSequenceBatchSize = databaseSequenceBatchSize;
}
/**
* Return the DB migration configuration.
*/
public DbMigrationConfig getMigrationConfig() {
return migrationConfig;
}
/**
* Set the DB migration configuration.
*/
public void setMigrationConfig(DbMigrationConfig migrationConfig) {
this.migrationConfig = migrationConfig;
}
/**
* Return the suffix appended to the base table to derive the view that contains the union
* of the base table and the history table in order to support asOf queries.
@@ -1856,6 +1875,8 @@ public class ServerConfig {
*/
protected void loadSettings(PropertiesWrapper p) {
migrationConfig.loadSettings(p);
namingConvention = createNamingConvention(p, namingConvention);
if (namingConvention != null) {
namingConvention.loadFromProperties(p);
@@ -0,0 +1,56 @@
package com.avaje.ebean.dbmigration;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.config.DbMigrationConfig;
import com.avaje.ebean.dbmigration.model.CurrentModel;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
*
*/
public class DbMigration {
private static final Logger logger = LoggerFactory.getLogger(DbMigration.class);
private final SpiEbeanServer server;
private final DbMigrationConfig migrationConfig;
public DbMigration() {
this(Ebean.getDefaultServer());
}
public DbMigration(EbeanServer ebeanServer) {
this.server = (SpiEbeanServer) ebeanServer;
this.migrationConfig = server.getServerConfig().getMigrationConfig();
}
public void writeCurrent() {
CurrentModel currentModel = new CurrentModel(server);
File writeTo = getWritePath();
logger.info("... write to {}", writeTo.getAbsolutePath());
currentModel.writeMigration(writeTo);
}
public File getWritePath() {
File resourceRootDir = new File("./dbmigration-test/resources");
// expect to be a relative path
String resourcePath = migrationConfig.getResourcePath();
File path = new File(resourceRootDir, resourcePath);
if (!path.exists()) {
path.mkdirs();
}
return new File(path, "migration-current.xml");
}
}
@@ -0,0 +1,37 @@
package com.avaje.ebean.dbmigration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class DbOffline {
private static final Logger logger = LoggerFactory.getLogger(DbOffline.class);
private static final String KEY = "ebean.dboffline";
public static final String H2 = "H2";
public static void setPlatform(String platformName) {
System.setProperty(KEY, platformName);
}
public static String getPlatform() {
return System.getProperty(KEY);
}
public static void asH2() {
setPlatform(H2);
}
public static boolean isSet() {
return getPlatform() != null;
}
public static void reset() {
System.clearProperty(KEY);
logger.info("reset");
}
}
@@ -5,6 +5,7 @@ import com.avaje.ebean.dbmigration.ddlgeneration.platform.BaseTableDdl;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.DdlNamingConvention;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
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;
@@ -23,7 +24,7 @@ public class BaseDdlHandler implements DdlHandler {
public BaseDdlHandler(DdlNamingConvention namingConvention, PlatformDdl platformDdl) {
this.tableDdl = new BaseTableDdl(namingConvention, platformDdl);
this.columnDdl = new BaseColumnDdl();
this.columnDdl = new BaseColumnDdl(platformDdl);
}
@Override
@@ -37,6 +38,8 @@ public class BaseDdlHandler implements DdlHandler {
generate(writer, (AddColumn) change);
} else if (change instanceof DropColumn) {
generate(writer, (DropColumn) change);
} else if (change instanceof AlterColumn) {
generate(writer, (AlterColumn) change);
}
}
}
@@ -56,4 +59,8 @@ public class BaseDdlHandler implements DdlHandler {
columnDdl.generate(writer, dropColumn);
}
@Override
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
columnDdl.generate(writer, alterColumn);
}
}
@@ -1,23 +1,28 @@
package com.avaje.ebean.dbmigration.ddlgeneration;
import com.avaje.ebean.dbmigration.migration.AddColumn;
import com.avaje.ebean.dbmigration.migration.AlterColumn;
import com.avaje.ebean.dbmigration.migration.DropColumn;
import java.io.IOException;
/**
* Write AddColumn or DropColumn.
* Write DDL for AddColumn , DropColumn or AlterColumn.
*/
public interface ColumnDdl {
/**
* Write a AddColumn change.
* Write the add column change.
*/
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
/**
* Write a DropColumn change.
* Write the drop column change.
*/
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
/**
* Write the alter column changes.
*/
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
}
@@ -1,6 +1,7 @@
package com.avaje.ebean.dbmigration.ddlgeneration;
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;
@@ -18,4 +19,7 @@ public interface DdlHandler {
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
}
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
}
@@ -4,6 +4,7 @@ import com.avaje.ebean.dbmigration.ddlgeneration.ColumnDdl;
import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
import com.avaje.ebean.dbmigration.migration.AddColumn;
import com.avaje.ebean.dbmigration.migration.AlterColumn;
import com.avaje.ebean.dbmigration.migration.Column;
import com.avaje.ebean.dbmigration.migration.DropColumn;
@@ -14,6 +15,11 @@ import java.util.List;
*/
public class BaseColumnDdl implements ColumnDdl {
protected final PlatformDdl platformDdl;
public BaseColumnDdl(PlatformDdl platformDdl) {
this.platformDdl = platformDdl;
}
@Override
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
@@ -40,6 +46,89 @@ public class BaseColumnDdl implements ColumnDdl {
// are put into a separate changeSet that is run last
}
@Override
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
if (isTrue(alterColumn.isHistoryExclude())) {
historyExcludeColumn(writer, alterColumn);
} else if (isFalse(alterColumn.isHistoryExclude())) {
historyIncludeColumn(writer, alterColumn);
}
if (hasValue(alterColumn.getOldReferences())) {
dropForeignKey(writer, alterColumn);
}
if (hasValue(alterColumn.getNewReferences())) {
addForeignKey(writer, alterColumn);
}
if (isTrue(alterColumn.isUnique())) {
addUniqueConstraint(writer, alterColumn);
} else if (isFalse(alterColumn.isUnique())) {
dropUniqueConstraint(writer, alterColumn);
}
if (isTrue(alterColumn.isUniqueOneToOne())) {
addUniqueOneToOneConstraint(writer, alterColumn);
} else if (isFalse(alterColumn.isUniqueOneToOne())) {
dropUniqueOneToOneConstraint(writer, alterColumn);
}
}
protected void addForeignKey(DdlWrite writer, AlterColumn alterColumn) {
}
protected void dropForeignKey(DdlWrite writer, AlterColumn alterColumn) {
}
protected void dropUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alterColumn) {
}
protected void addUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alterColumn) {
}
protected void dropUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
String tableName = alter.getTableName();
String columnName = alter.getColumnName();
String uqName = platformDdl.namingConvention.uniqueConstraintName(tableName, columnName, 50);
writer.apply()
.append(platformDdl.dropIndex(uqName, tableName))
.endOfStatement();
}
protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
String tableName = alter.getTableName();
String columnName = alter.getColumnName();
String uqName = platformDdl.namingConvention.uniqueConstraintName(tableName, columnName, 50);
String[] cols = {columnName};
writer.apply()
.append(platformDdl.createExternalUniqueForOneToOne(uqName, tableName, cols))
.endOfStatement();
writer.rollbackForeignKeys()
.append(platformDdl.dropIndex(uqName, tableName))
.endOfStatement();
}
protected void historyIncludeColumn(DdlWrite writer, AlterColumn alterColumn) {
platformDdl.historyIncludeColumn(writer, alterColumn);
}
protected void historyExcludeColumn(DdlWrite writer, AlterColumn alterColumn) {
platformDdl.historyExcludeColumn(writer, alterColumn);
}
protected void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
buffer.append("alter table ").append(tableName)
@@ -63,6 +152,14 @@ public class BaseColumnDdl implements ColumnDdl {
}
protected boolean isFalse(Boolean value) {
return value != null && !value;
}
protected boolean isTrue(Boolean value) {
return value != null && value;
}
protected boolean hasValue(String value) {
return value != null && !value.trim().isEmpty();
}
@@ -356,20 +356,6 @@ public class BaseTableDdl implements TableDdl {
appendColumns(pkColumns, buffer);
}
/**
* Write alter table add primary key statement.
*/
public void alterTableAddPrimaryKey(DdlBuffer buffer, String tableName, List<Column> pk) throws IOException {
String[] pkColumns = toColumnNames(pk);
String pkName = determinePrimaryKeyName(tableName);
buffer.append("alter table ").append(tableName);
buffer.append(" add primary key ").append(pkName);
appendColumns(pkColumns, buffer);
buffer.append(")").endOfStatement();
}
/**
* Return as an array of string column names.
*/
@@ -13,6 +13,7 @@ public class MsSqlServerDdl extends PlatformDdl {
this.identitySuffix = " identity(1,1)";
this.foreignKeyRestrict = "";
this.inlineUniqueOneToOne = false;
this.namingConvention.maxConstraintNameLength = 62; //Actually 128
}
@Override
@@ -7,6 +7,7 @@ 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.migration.AlterColumn;
import com.avaje.ebean.dbmigration.migration.IdentityType;
import com.avaje.ebean.dbmigration.model.MTable;
@@ -176,4 +177,12 @@ public class PlatformDdl {
// does nothing by default, really this is a MsSqlServer specific requirement
return "";
}
public void historyExcludeColumn(DdlWrite writer, AlterColumn alterColumn) {
}
public void historyIncludeColumn(DdlWrite writer, AlterColumn alterColumn) {
}
}
@@ -12,6 +12,7 @@ public class PostgresDdl extends PlatformDdl {
super(platformTypes, dbIdentity);
this.historyDdl = new PostgresHistoryDdl(this.namingConvention.normalise);
this.dropTableCascade = " cascade";
this.namingConvention.maxConstraintNameLength = 62;
}
/**
@@ -0,0 +1,384 @@
package com.avaje.ebean.dbmigration.migration;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;attribute name="columnName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="oldDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="newDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="oldCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="newCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="oldReferences" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="newReferences" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlRootElement(name = "alterColumn")
public class AlterColumn {
@XmlAttribute(name = "columnName", required = true)
protected String columnName;
@XmlAttribute(name = "tableName", required = true)
protected String tableName;
@XmlAttribute(name = "type")
protected String type;
@XmlAttribute(name = "notnull")
protected Boolean notnull;
@XmlAttribute(name = "historyExclude")
protected Boolean historyExclude;
@XmlAttribute(name = "unique")
protected Boolean unique;
@XmlAttribute(name = "uniqueOneToOne")
protected Boolean uniqueOneToOne;
@XmlAttribute(name = "oldDefaultValue")
protected String oldDefaultValue;
@XmlAttribute(name = "newDefaultValue")
protected String newDefaultValue;
@XmlAttribute(name = "oldCheckConstraint")
protected String oldCheckConstraint;
@XmlAttribute(name = "newCheckConstraint")
protected String newCheckConstraint;
@XmlAttribute(name = "oldReferences")
protected String oldReferences;
@XmlAttribute(name = "newReferences")
protected String newReferences;
/**
* Gets the value of the columnName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getColumnName() {
return columnName;
}
/**
* Sets the value of the columnName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setColumnName(String value) {
this.columnName = value;
}
/**
* Gets the value of the tableName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getTableName() {
return tableName;
}
/**
* Sets the value of the tableName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setTableName(String value) {
this.tableName = value;
}
/**
* Gets the value of the type property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getType() {
return type;
}
/**
* Sets the value of the type property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setType(String value) {
this.type = value;
}
/**
* Gets the value of the notnull property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isNotnull() {
return notnull;
}
/**
* Sets the value of the notnull property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setNotnull(Boolean value) {
this.notnull = value;
}
/**
* Gets the value of the historyExclude property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isHistoryExclude() {
return historyExclude;
}
/**
* Sets the value of the historyExclude property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setHistoryExclude(Boolean value) {
this.historyExclude = value;
}
/**
* Gets the value of the unique property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isUnique() {
return unique;
}
/**
* Sets the value of the unique property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setUnique(Boolean value) {
this.unique = value;
}
/**
* Gets the value of the uniqueOneToOne property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isUniqueOneToOne() {
return uniqueOneToOne;
}
/**
* Sets the value of the uniqueOneToOne property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setUniqueOneToOne(Boolean value) {
this.uniqueOneToOne = value;
}
/**
* Gets the value of the oldDefaultValue property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getOldDefaultValue() {
return oldDefaultValue;
}
/**
* Sets the value of the oldDefaultValue property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setOldDefaultValue(String value) {
this.oldDefaultValue = value;
}
/**
* Gets the value of the newDefaultValue property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getNewDefaultValue() {
return newDefaultValue;
}
/**
* Sets the value of the newDefaultValue property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setNewDefaultValue(String value) {
this.newDefaultValue = value;
}
/**
* Gets the value of the oldCheckConstraint property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getOldCheckConstraint() {
return oldCheckConstraint;
}
/**
* Sets the value of the oldCheckConstraint property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setOldCheckConstraint(String value) {
this.oldCheckConstraint = value;
}
/**
* Gets the value of the newCheckConstraint property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getNewCheckConstraint() {
return newCheckConstraint;
}
/**
* Sets the value of the newCheckConstraint property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setNewCheckConstraint(String value) {
this.newCheckConstraint = value;
}
/**
* Gets the value of the oldReferences property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getOldReferences() {
return oldReferences;
}
/**
* Sets the value of the oldReferences property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setOldReferences(String value) {
this.oldReferences = value;
}
/**
* Gets the value of the newReferences property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getNewReferences() {
return newReferences;
}
/**
* Sets the value of the newReferences property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setNewReferences(String value) {
this.newReferences = value;
}
}
@@ -51,14 +51,10 @@ public class ChangeSet {
@XmlElement(name = "dropTable", type = DropTable.class),
@XmlElement(name = "renameTable", type = RenameTable.class),
@XmlElement(name = "createHistoryTable", type = CreateHistoryTable.class),
@XmlElement(name = "createView", type = CreateView.class),
@XmlElement(name = "dropView", type = DropView.class),
@XmlElement(name = "renameView", type = RenameView.class),
@XmlElement(name = "addColumn", type = AddColumn.class),
@XmlElement(name = "dropColumn", type = DropColumn.class),
@XmlElement(name = "renameColumn", type = RenameColumn.class),
@XmlElement(name = "addForeignKey", type = AddForeignKey.class),
@XmlElement(name = "dropForeignKey", type = DropForeignKey.class)
@XmlElement(name = "alterColumn", type = AlterColumn.class),
@XmlElement(name = "renameColumn", type = RenameColumn.class)
})
protected List<Object> changeSetChildren;
@XmlAttribute(name = "type", required = true)
@@ -94,14 +90,10 @@ public class ChangeSet {
* {@link DropTable }
* {@link RenameTable }
* {@link CreateHistoryTable }
* {@link CreateView }
* {@link DropView }
* {@link RenameView }
* {@link AddColumn }
* {@link DropColumn }
* {@link AlterColumn }
* {@link RenameColumn }
* {@link AddForeignKey }
* {@link DropForeignKey }
*
*
*/
@@ -23,6 +23,7 @@ import javax.xml.bind.annotation.XmlValue;
* &lt;attribute name="defaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* &lt;attribute name="primaryKey" type="{http://www.w3.org/2001/XMLSchema}boolean" />
@@ -55,6 +56,8 @@ public class Column {
protected Boolean notnull;
@XmlAttribute(name = "checkConstraint")
protected String checkConstraint;
@XmlAttribute(name = "historyExclude")
protected Boolean historyExclude;
@XmlAttribute(name = "unique")
protected Boolean unique;
@XmlAttribute(name = "uniqueOneToOne")
@@ -212,6 +215,30 @@ public class Column {
this.checkConstraint = value;
}
/**
* Gets the value of the historyExclude property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isHistoryExclude() {
return historyExclude;
}
/**
* Sets the value of the historyExclude property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setHistoryExclude(Boolean value) {
this.historyExclude = value;
}
/**
* Gets the value of the unique property.
*
@@ -30,11 +30,19 @@ public class ObjectFactory {
}
/**
* Create an instance of {@link CreateTable }
* Create an instance of {@link Rollback }
*
*/
public CreateTable createCreateTable() {
return new CreateTable();
public Rollback createRollback() {
return new Rollback();
}
/**
* Create an instance of {@link AddColumn }
*
*/
public AddColumn createAddColumn() {
return new AddColumn();
}
/**
@@ -45,6 +53,14 @@ public class ObjectFactory {
return new Column();
}
/**
* Create an instance of {@link CreateTable }
*
*/
public CreateTable createCreateTable() {
return new CreateTable();
}
/**
* Create an instance of {@link UniqueConstraint }
*
@@ -62,11 +78,11 @@ public class ObjectFactory {
}
/**
* Create an instance of {@link DropForeignKey }
* Create an instance of {@link Apply }
*
*/
public DropForeignKey createDropForeignKey() {
return new DropForeignKey();
public Apply createApply() {
return new Apply();
}
/**
@@ -101,6 +117,14 @@ public class ObjectFactory {
return new DropHistoryTable();
}
/**
* Create an instance of {@link AlterColumn }
*
*/
public AlterColumn createAlterColumn() {
return new AlterColumn();
}
/**
* Create an instance of {@link DropColumn }
*
@@ -110,11 +134,11 @@ public class ObjectFactory {
}
/**
* Create an instance of {@link DropView }
* Create an instance of {@link ChangeSet }
*
*/
public DropView createDropView() {
return new DropView();
public ChangeSet createChangeSet() {
return new ChangeSet();
}
/**
@@ -126,19 +150,11 @@ public class ObjectFactory {
}
/**
* Create an instance of {@link Apply }
* Create an instance of {@link DropTable }
*
*/
public Apply createApply() {
return new Apply();
}
/**
* Create an instance of {@link Rollback }
*
*/
public Rollback createRollback() {
return new Rollback();
public DropTable createDropTable() {
return new DropTable();
}
/**
@@ -157,62 +173,6 @@ public class ObjectFactory {
return new RenameColumn();
}
/**
* Create an instance of {@link CreateView }
*
*/
public CreateView createCreateView() {
return new CreateView();
}
/**
* Create an instance of {@link DropTable }
*
*/
public DropTable createDropTable() {
return new DropTable();
}
/**
* Create an instance of {@link AddColumn }
*
*/
public AddColumn createAddColumn() {
return new AddColumn();
}
/**
* Create an instance of {@link RenameView }
*
*/
public RenameView createRenameView() {
return new RenameView();
}
/**
* Create an instance of {@link AddForeignKey }
*
*/
public AddForeignKey createAddForeignKey() {
return new AddForeignKey();
}
/**
* Create an instance of {@link ChangeSet }
*
*/
public ChangeSet createChangeSet() {
return new ChangeSet();
}
/**
* Create an instance of {@link Application }
*
*/
public Application createApplication() {
return new Application();
}
/**
* Create an instance of {@link Migration }
*
@@ -221,12 +181,4 @@ public class ObjectFactory {
return new Migration();
}
/**
* Create an instance of {@link Applications }
*
*/
public Applications createApplications() {
return new Applications();
}
}
@@ -15,6 +15,19 @@ public class MigrationXmlReader {
private static final MigrationXmlReader INSTANCE = new MigrationXmlReader();
/**
* Read and return a Migration from an xml document at the given resource path.
*/
public static Migration readMaybe(String resourcePath) {
InputStream is = MigrationXmlReader.class.getResourceAsStream(resourcePath);
if (is == null) {
return null;
}
return INSTANCE.read(is);
}
/**
* Read and return a Migration from an xml document at the given resource path.
*/
@@ -2,7 +2,6 @@ package com.avaje.ebean.dbmigration.model;
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.DdlNamingConvention;
import com.avaje.ebean.dbmigration.migration.ChangeSet;
import com.avaje.ebean.dbmigration.migration.Migration;
import com.avaje.ebean.dbmigration.migrationreader.MigrationXmlWriter;
@@ -22,17 +21,22 @@ public class CurrentModel {
private final SpiEbeanServer server;
private DdlNamingConvention namingConvention;
private ModelContainer model;
private ChangeSet changeSet;
private DdlWrite write;
/**
* Construct with a given EbeanServer instance.
*/
public CurrentModel(SpiEbeanServer server) {
this.server = server;
this.namingConvention = new DdlNamingConvention();
}
/**
* Return the current model by reading all the bean descriptors and properties.
*/
public ModelContainer read() {
if (model == null) {
model = new ModelContainer();
@@ -48,6 +52,9 @@ public class CurrentModel {
this.changeSet = changeSet;
}
/**
* Return as a ChangeSet.
*/
public ChangeSet getChangeSet() {
read();
if (changeSet == null) {
@@ -56,6 +63,9 @@ public class CurrentModel {
return changeSet;
}
/**
* Write as migration xml to the given file.
*/
public void writeMigration(File file) {
ChangeSet changeSet = getChangeSet();
@@ -66,6 +76,9 @@ public class CurrentModel {
writer.write(migration, file);
}
/**
* Return the 'Create' DDL.
*/
public String getCreateDdl() throws IOException {
createDdl();
@@ -78,6 +91,9 @@ public class CurrentModel {
return ddl.toString();
}
/**
* Return the 'Drop' DDL.
*/
public String getDropDdl() throws IOException {
createDdl();
@@ -89,16 +105,9 @@ public class CurrentModel {
return ddl.toString();
}
public DdlWrite generateDdl(ChangeSet changeSet) throws IOException {
DdlWrite write = new DdlWrite();
DdlHandler handler = handler();
handler.generate(write, changeSet);
return write;
}
/**
* Create all the DDL based on the changeSet.
*/
private void createDdl() throws IOException {
if (write == null) {
@@ -111,8 +120,10 @@ public class CurrentModel {
}
}
/**
* Return the platform specific DdlHandler (to generate DDL).
*/
private DdlHandler handler() {
return server.getDatabasePlatform().createDdlHandler();
}
@@ -1,5 +1,6 @@
package com.avaje.ebean.dbmigration.model;
import com.avaje.ebean.dbmigration.migration.AlterColumn;
import com.avaje.ebean.dbmigration.migration.Column;
/**
@@ -12,6 +13,7 @@ public class MColumn {
private String checkConstraint;
private String defaultValue;
private String references;
private boolean historyExclude;
private boolean notnull;
private boolean primaryKey;
private boolean identity;
@@ -34,6 +36,7 @@ public class MColumn {
this.primaryKey = Boolean.TRUE.equals(column.isPrimaryKey());
this.identity = Boolean.TRUE.equals(column.isIdentity());
this.unique = Boolean.TRUE.equals(column.isUnique());
this.historyExclude = Boolean.TRUE.equals(column.isHistoryExclude());
}
public MColumn(String name, String type) {
@@ -103,6 +106,14 @@ public class MColumn {
this.notnull = notnull;
}
public boolean isHistoryExclude() {
return historyExclude;
}
public void setHistoryExclude(boolean historyExclude) {
this.historyExclude = historyExclude;
}
public void setUnique(boolean unique) {
this.unique = unique;
}
@@ -136,6 +147,7 @@ public class MColumn {
if (uniqueOneToOne) c.setUniqueOneToOne(true);
if (primaryKey) c.setPrimaryKey(true);
if (identity) c.setIdentity(true);
if (historyExclude) c.setHistoryExclude(true);
c.setCheckConstraint(checkConstraint);
c.setReferences(references);
@@ -143,4 +155,64 @@ public class MColumn {
return c;
}
private boolean different(String val1, String val2) {
return (val1 == null) ? val2 != null : !val1.equals(val2);
}
AlterColumn alterColumn;
private AlterColumn getAlterColumn(String tableName) {
if (alterColumn == null) {
alterColumn = new AlterColumn();
alterColumn.setColumnName(name);
alterColumn.setTableName(tableName);
}
return alterColumn;
}
public void compare(ModelDiff modelDiff, MTable table, MColumn newColumn) {
String tableName = table.getName();
this.alterColumn = null;
if (different(type, newColumn.type)) {
getAlterColumn(tableName).setType(newColumn.type);
}
if (historyExclude != newColumn.historyExclude) {
getAlterColumn(tableName).setHistoryExclude(newColumn.historyExclude);
}
if (notnull != newColumn.notnull) {
getAlterColumn(tableName).setNotnull(newColumn.notnull);
}
if (different(defaultValue, newColumn.defaultValue)) {
AlterColumn alter = getAlterColumn(tableName);
alter.setOldDefaultValue(defaultValue);
alter.setNewDefaultValue(newColumn.defaultValue);
}
if (different(checkConstraint, newColumn.checkConstraint)) {
AlterColumn alter = getAlterColumn(tableName);
alter.setOldCheckConstraint(checkConstraint);
alter.setNewCheckConstraint(newColumn.checkConstraint);
}
if (different(references, newColumn.references)) {
AlterColumn alter = getAlterColumn(tableName);
alter.setOldReferences(references);
alter.setNewReferences(newColumn.references);
}
if (unique != newColumn.unique) {
AlterColumn alter = getAlterColumn(tableName);
alter.setUnique(newColumn.unique);
}
if (uniqueOneToOne != newColumn.uniqueOneToOne) {
AlterColumn alter = getAlterColumn(tableName);
alter.setUniqueOneToOne(newColumn.uniqueOneToOne);
}
if (alterColumn != null) {
modelDiff.addAlterColumn(alterColumn);
}
}
}
@@ -8,9 +8,12 @@ import com.avaje.ebean.dbmigration.migration.IdentityType;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Holds the logical model for a given Table and everything associated to it.
@@ -29,11 +32,6 @@ import java.util.Map;
*/
public class MTable {
/**
* Flag set to indicate
*/
private boolean matched;
private final String name;
private String comment;
@@ -60,6 +58,8 @@ public class MTable {
private List<MCompoundForeignKey> compoundKeys = new ArrayList<MCompoundForeignKey>();
private AddColumn addColumn;
/**
* Construct for migration.
*/
@@ -110,12 +110,37 @@ public class MTable {
return createTable;
}
public boolean isMatched() {
return matched;
}
public void compare(ModelDiff modelDiff, MTable newTable) {
// TODO: compare indexes?
// TODO: compare primary key
addColumn = null;
Set<String> mappedColumns = new LinkedHashSet<String>();
Collection<MColumn> newColumns = newTable.getColumns().values();
for (MColumn newColumn : newColumns) {
MColumn localColumn = columns.get(newColumn.getName());
if (localColumn == null) {
diffNewColumn(newColumn);
} else {
localColumn.compare(modelDiff, this, newColumn);
mappedColumns.add(newColumn.getName());
}
}
Collection<MColumn> existingColumns = columns.values();
for (MColumn existingColumn : existingColumns) {
if (!mappedColumns.contains(existingColumn.getName())) {
diffDropColumn(modelDiff, existingColumn);
}
}
if (addColumn != null) {
modelDiff.addAddColumn(addColumn);
}
public void setMatched(boolean matched) {
this.matched = matched;
}
/**
@@ -293,4 +318,24 @@ public class MTable {
addColumn(newCol);
return newCol;
}
private void diffNewColumn(MColumn newColumn) {
if (addColumn == null) {
addColumn = new AddColumn();
addColumn.setTableName(name);
}
addColumn.getColumn().add(newColumn.createColumn());
}
private void diffDropColumn(ModelDiff modelDiff, MColumn existingColumn) {
DropColumn dropColumn = new DropColumn();
dropColumn.setTableName(name);
dropColumn.setColumnName(existingColumn.getName());
modelDiff.addDropColumn(dropColumn);
}
}
@@ -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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Build the model from the series of migrations.
*/
public class MigrationModel {
private static final Logger logger = LoggerFactory.getLogger(MigrationModel.class);
private final ModelContainer model = new ModelContainer();
private final Set<String> readVersions = new LinkedHashSet<String>();
private final String resourcePath;
public MigrationModel(String resourcePath) {
this.resourcePath = normaliseResourcePath(resourcePath);
}
private String normaliseResourcePath(String resourcePath) {
if (resourcePath.endsWith("/")) {
// trim trailing slash
resourcePath = resourcePath.substring(0, resourcePath.length()-1);
}
if (resourcePath.startsWith("/")) {
// trim leading slash
resourcePath = resourcePath.substring(1);
}
return resourcePath;
}
/**
* Read all the migrations returning the model with all
* the migrations applied in version order.
*/
public ModelContainer read() {
readMigrations();
logger.info("read versions {}", readVersions);
return model;
}
/**
* Return the set of versions that were read.
*/
public Set<String> getReadVersions() {
return readVersions;
}
private void readMigrations() {
for (int majorVersion = 1; majorVersion < 100; majorVersion++) {
if (!readMinorVersions(majorVersion)){
// no major.0 version so stopping
return;
}
}
}
private boolean readMinorVersions(int majorVersion) {
for (int minorVersion = 0; minorVersion < 100; minorVersion++) {
if (!readMigration(majorVersion, minorVersion)) {
// continue reading next major if minorVersion 0 was read
return (minorVersion > 0);
}
}
return true;
}
private boolean readMigration(int majorVersion, int minorVersion) {
String version = majorVersion+"."+minorVersion;
String path = "/"+resourcePath+"/v"+version+".xml";
Migration migration = MigrationXmlReader.readMaybe(path);
if (migration == null) {
return false;
}
readVersions.add(version);
logger.trace("... read migration v{}", version);
model.apply(migration);
return true;
}
}
@@ -23,6 +23,9 @@ public class ModelContainer {
*/
private Map<String, MTable> tables = new LinkedHashMap<String, MTable>();
public ModelContainer() {
}
/**
* Return the map of all the tables.
@@ -73,7 +76,7 @@ public class ModelContainer {
protected void applyChange(CreateTable createTable) {
String tableName = createTable.getName();
if (tables.containsKey(tableName)) {
throw new IllegalStateException("Table [" + tableName + "] already exists?");
throw new IllegalStateException("Table [" + tableName + "] already exists in model?");
}
MTable table = new MTable(createTable);
tables.put(tableName, table);
@@ -85,7 +88,7 @@ public class ModelContainer {
protected void applyChange(AddColumn addColumn) {
MTable table = tables.get(addColumn.getTableName());
if (table == null) {
throw new IllegalStateException("Table [" + addColumn.getTableName() + "] does not exist?");
throw new IllegalStateException("Table [" + addColumn.getTableName() + "] does not exist in model?");
}
table.apply(addColumn);
}
@@ -96,7 +99,7 @@ public class ModelContainer {
protected void applyChange(DropColumn dropColumn) {
MTable table = tables.get(dropColumn.getTableName());
if (table == null) {
throw new IllegalStateException("Table [" + dropColumn.getTableName() + "] does not exist?");
throw new IllegalStateException("Table [" + dropColumn.getTableName() + "] does not exist in model?");
}
table.apply(dropColumn);
}
@@ -1,5 +1,9 @@
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.DropColumn;
import java.util.ArrayList;
import java.util.List;
@@ -12,17 +16,17 @@ public class ModelDiff {
/**
* The base model to which we compare the newer model.
*/
protected final ModelContainer baseModel;
private final ModelContainer baseModel;
/**
* List of 'create' type changes.
*/
protected final List<Object> createChanges = new ArrayList<Object>();
private final List<Object> createChanges = new ArrayList<Object>();
/**
* List of 'drop' type changes. Potential for putting into a separate changeSet.
* List of 'drop' type changes. Expected to be placed into a separate DDL script.
*/
protected final List<Object> dropChanges = new ArrayList<Object>();
private final List<Object> dropChanges = new ArrayList<Object>();
/**
* Construct with a base model.
@@ -77,7 +81,6 @@ public class ModelDiff {
protected void addNewTable(MTable newTable) {
createChanges.add(newTable.createTable());
// createChanges.add(newTable.createForeignKeys());
}
/**
@@ -85,14 +88,19 @@ public class ModelDiff {
*/
protected void compareTables(MTable currentTable, MTable newTable) {
//TODO: compareTables()
// changed columns
// find additional columns
// find removed columns
// changes to indexes?
// changes to primary key
// changes to foreign key
// changes to unique constraints?
currentTable.compare(this, newTable);
}
public void addAlterColumn(AlterColumn alterColumn) {
createChanges.add(alterColumn);
}
public void addDropColumn(DropColumn dropColumn) {
dropChanges.add(dropColumn);
}
public void addAddColumn(AddColumn addColumn) {
createChanges.add(addColumn);
}
}
@@ -9,6 +9,7 @@ import javax.sql.DataSource;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.*;
import com.avaje.ebean.dbmigration.DbOffline;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,11 +31,17 @@ public class DatabasePlatformFactory {
try {
String offlinePlatform = DbOffline.getPlatform();
if (offlinePlatform != null) {
logger.info("offline platform [{}]", offlinePlatform);
return byDatabaseName(offlinePlatform);
}
if (serverConfig.getDatabasePlatformName() != null) {
// choose based on dbName
return byDatabaseName(serverConfig.getDatabasePlatformName());
}
if (serverConfig.getDataSourceConfig().isOffline()) {
String m = "You must specify a DatabasePlatformName when you are offline";
throw new PersistenceException(m);
@@ -11,6 +11,7 @@ import com.avaje.ebean.config.PropertyMap;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.UnderscoreNamingConvention;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebean.dbmigration.DbOffline;
import com.avaje.ebeaninternal.api.SpiBackgroundExecutor;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.cache.DefaultServerCacheFactory;
@@ -113,9 +114,6 @@ public class DefaultContainer implements SpiContainer {
serverConfig.getDatabasePlatform().setDbEncrypt(serverConfig.getDbEncrypt());
}
DatabasePlatform dbPlatform = serverConfig.getDatabasePlatform();
// inform the NamingConvention of the associated DatabasePlaform
serverConfig.getNamingConvention().setDatabasePlatform(serverConfig.getDatabasePlatform());
@@ -169,6 +167,7 @@ public class DefaultContainer implements SpiContainer {
// start any services after registering with clusterManager
server.start();
DbOffline.reset();
return server;
}
}
@@ -284,6 +283,11 @@ public class DefaultContainer implements SpiContainer {
private DataSource getDataSourceFromConfig(ServerConfig config) {
if (DbOffline.isSet()) {
logger.trace("... DbOffline using platform [{}]", DbOffline.getPlatform());
return null;
}
DataSource ds;
if (config.getDataSourceJndiName() != null) {
@@ -324,6 +328,10 @@ public class DefaultContainer implements SpiContainer {
*/
private boolean checkDataSource(ServerConfig serverConfig) {
if (DbOffline.isSet()) {
return false;
}
if (serverConfig.getDataSource() == null) {
if (serverConfig.getDataSourceConfig().isOffline()) {
// this is ok - offline DDL generation etc
@@ -185,7 +185,6 @@ public final class ConvertInetAddresses {
boolean isIpv6 = false;
// handle IPv6 forms of IPv4 addresses
// TODO: use Ascii.toUpperCase() when available
if (ipString.toUpperCase(Locale.US).startsWith("::FFFF:")) {
ipString = ipString.substring(7);
} else if (ipString.startsWith("::")) {
+77 -69
View File
@@ -8,20 +8,20 @@
<!-- =========================================================== -->
<!-- Root level type : applications -->
<xsd:element name="applications">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="application" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!--<xsd:element name="applications">-->
<!--<xsd:complexType>-->
<!--<xsd:sequence>-->
<!--<xsd:element ref="application" minOccurs="0" maxOccurs="unbounded"/>-->
<!--</xsd:sequence>-->
<!--</xsd:complexType>-->
<!--</xsd:element>-->
<xsd:element name="application">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="resourcePath" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!--<xsd:element name="application">-->
<!--<xsd:complexType>-->
<!--<xsd:attribute name="name" type="xsd:string" use="required"/>-->
<!--<xsd:attribute name="resourcePath" type="xsd:string" use="required"/>-->
<!--</xsd:complexType>-->
<!--</xsd:element>-->
<!-- =========================================================== -->
@@ -201,6 +201,24 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="alterColumn">
<xsd:complexType>
<xsd:attribute name="columnName" type="xsd:string" use="required"/>
<xsd:attribute name="tableName" type="xsd:string" use="required"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="notnull" type="xsd:boolean"/>
<xsd:attribute name="historyExclude" type="xsd:boolean"/>
<xsd:attribute name="unique" type="xsd:boolean"/>
<xsd:attribute name="uniqueOneToOne" type="xsd:boolean"/>
<xsd:attribute name="oldDefaultValue" type="xsd:string"/>
<xsd:attribute name="newDefaultValue" type="xsd:string"/>
<xsd:attribute name="oldCheckConstraint" type="xsd:string"/>
<xsd:attribute name="newCheckConstraint" type="xsd:string"/>
<xsd:attribute name="oldReferences" type="xsd:string"/>
<xsd:attribute name="newReferences" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="renameColumn">
<xsd:complexType>
<xsd:attribute name="oldName" type="xsd:string" use="required"/>
@@ -212,49 +230,49 @@
<!-- VIEW -->
<xsd:element name="createView">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="replaceIfExists" type="xsd:boolean"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<!--<xsd:element name="createView">-->
<!--<xsd:complexType>-->
<!--<xsd:simpleContent>-->
<!--<xsd:extension base="xsd:string">-->
<!--<xsd:attribute name="name" type="xsd:string" use="required"/>-->
<!--<xsd:attribute name="replaceIfExists" type="xsd:boolean"/>-->
<!--</xsd:extension>-->
<!--</xsd:simpleContent>-->
<!--</xsd:complexType>-->
<!--</xsd:element>-->
<xsd:element name="dropView">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!--<xsd:element name="dropView">-->
<!--<xsd:complexType>-->
<!--<xsd:attribute name="name" type="xsd:string" use="required"/>-->
<!--</xsd:complexType>-->
<!--</xsd:element>-->
<xsd:element name="renameView">
<xsd:complexType>
<xsd:attribute name="oldName" type="xsd:string" use="required"/>
<xsd:attribute name="newName" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!--<xsd:element name="renameView">-->
<!--<xsd:complexType>-->
<!--<xsd:attribute name="oldName" type="xsd:string" use="required"/>-->
<!--<xsd:attribute name="newName" type="xsd:string" use="required"/>-->
<!--</xsd:complexType>-->
<!--</xsd:element>-->
<!-- FOREIGN KEY -->
<xsd:element name="addForeignKey">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="columns" type="xsd:string" use="required"/>
<xsd:attribute name="references" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<!--<xsd:element name="addForeignKey">-->
<!--<xsd:complexType>-->
<!--<xsd:simpleContent>-->
<!--<xsd:extension base="xsd:string">-->
<!--<xsd:attribute name="name" type="xsd:string" use="required"/>-->
<!--<xsd:attribute name="columns" type="xsd:string" use="required"/>-->
<!--<xsd:attribute name="references" type="xsd:string" use="required"/>-->
<!--</xsd:extension>-->
<!--</xsd:simpleContent>-->
<!--</xsd:complexType>-->
<!--</xsd:element>-->
<xsd:element name="dropForeignKey">
<xsd:complexType mixed="true">
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!--<xsd:element name="dropForeignKey">-->
<!--<xsd:complexType mixed="true">-->
<!--<xsd:attribute name="name" type="xsd:string" use="required"/>-->
<!--</xsd:complexType>-->
<!--</xsd:element>-->
<!-- ============================================ -->
@@ -263,13 +281,13 @@
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="type" type="xsd:string" use="required"/>
<xsd:attribute name="defaultValue" type="xsd:string"/>
<!--<xsd:attributeGroup ref="columnAttributes"/>-->
<xsd:attribute name="notnull" type="xsd:boolean"/>
<xsd:attribute name="checkConstraint" type="xsd:string"/>
<xsd:attribute name="historyExclude" type="xsd:boolean"/>
<xsd:attribute name="unique" type="xsd:boolean"/>
<xsd:attribute name="uniqueOneToOne" type="xsd:boolean"/>
<xsd:attribute name="primaryKey" type="xsd:boolean"/>
<xsd:attribute name="identity" type="xsd:boolean"/> <!-- aka autoincrement/identity -->
<xsd:attribute name="identity" type="xsd:boolean"/>
<xsd:attribute name="references" type="xsd:string"/>
<xsd:attribute name="comment" type="xsd:string"/>
</xsd:complexType>
@@ -285,7 +303,6 @@
<xsd:group name="changeSetChildren">
<xsd:choice>
<xsd:element ref="configuration" maxOccurs="1"/>
<xsd:element ref="sql" maxOccurs="unbounded"/>
<xsd:element ref="createTable" maxOccurs="unbounded"/>
@@ -294,16 +311,17 @@
<xsd:element ref="createHistoryTable" maxOccurs="unbounded"/>
<xsd:element ref="createView" maxOccurs="unbounded"/>
<xsd:element ref="dropView" maxOccurs="unbounded"/>
<xsd:element ref="renameView" maxOccurs="unbounded"/>
<xsd:element ref="addColumn" maxOccurs="unbounded"/>
<xsd:element ref="dropColumn" maxOccurs="unbounded"/>
<xsd:element ref="alterColumn" maxOccurs="unbounded"/>
<xsd:element ref="renameColumn" maxOccurs="unbounded"/>
<xsd:element ref="addForeignKey" maxOccurs="unbounded"/>
<xsd:element ref="dropForeignKey" maxOccurs="unbounded"/>
<!--<xsd:element ref="createView" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropView" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="renameView" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="addForeignKey" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropForeignKey" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="createIndex" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropIndex" maxOccurs="unbounded"/>-->
@@ -312,23 +330,13 @@
<!--<xsd:element ref="alterSequence" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropSequence" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="addNotNullConstraint" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropNotNullConstraint" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="addPrimaryKey" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropPrimaryKey" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="addUniqueConstraint" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropUniqueConstraint" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="addDefaultValue" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="dropDefaultValue" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="sql" maxOccurs="unbounded"/>-->
<!--<xsd:element ref="createProcedure" maxOccurs="unbounded"/>-->
</xsd:choice>
</xsd:group>
</xsd:schema>
@@ -0,0 +1,23 @@
package com.avaje.ebean.config;
import org.junit.Test;
import static org.assertj.core.api.Assertions.*;
public class DbMigrationConfigTest {
@Test
public void testLoad() {
ServerConfig config = new ServerConfig();
config.setName("h2other");
config.loadFromProperties();
DbMigrationConfig migrationConfig = config.getMigrationConfig();
assertThat(migrationConfig.getAppName()).isEqualTo("myapp");
assertThat(migrationConfig.getResourcePath()).isEqualTo("dbmigration/myapp");
}
}
@@ -0,0 +1,32 @@
package com.avaje.ebean.dbmigration;
import com.avaje.ebean.BaseTestCase;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.assertj.core.api.Assertions.*;
public class DbMigrationTest extends BaseTestCase {
private static final Logger logger = LoggerFactory.getLogger(DbMigrationTest.class);
//@Ignore
@Test
public void writeCurrent() {
logger.info("start");
DbOffline.asH2();
DbMigration migration = new DbMigration();
DbOffline.reset();
migration.writeCurrent();
assertThat(DbOffline.isSet()).isFalse();
logger.info("end");
}
}
@@ -12,7 +12,7 @@ public class MigrationXmlWriterTest {
Logger logger = LoggerFactory.getLogger(MigrationXmlWriterTest.class);
@Test
public void testWrite() throws Exception {
public void testReadWrite() throws Exception {
Migration migration = MigrationXmlReader.read("/container/test-create-table.xml");
@@ -0,0 +1,273 @@
package com.avaje.ebean.dbmigration.model;
import com.avaje.ebean.dbmigration.migration.AlterColumn;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import static org.assertj.core.api.Assertions.*;
public class MColumnTest {
MTable table = new MTable("tab");
MColumn basic() {
return new MColumn("col", "integer");
}
ModelDiff diff() {
return new ModelDiff();
}
@Test
public void noDiff() throws Exception {
ModelDiff diff = diff();
basic().compare(diff, table, basic());
assertThat(diff.getCreateChanges()).isEmpty();
assertThat(diff.getDropChanges()).isEmpty();
}
@Test
public void diffType() throws Exception {
ModelDiff diff = diff();
basic().compare(diff, table, new MColumn("col", "integer(8)"));
assertChanges(diff);
AlterColumn alterColumn = getAlterColumn(diff);
assertThat(alterColumn.getType()).isEqualTo("integer(8)");
}
@Test
public void diffNotNull() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setNotnull(true);
basic().compare(diff, table, newCol);
assertChanges(diff);
AlterColumn alterColumn = getAlterColumn(diff);
assertThat(alterColumn.isNotnull()).isEqualTo(true);
assertThat(alterColumn.getType()).isNull();
assertThat(alterColumn.isUnique()).isNull();
assertThat(alterColumn.isUniqueOneToOne()).isNull();
assertThat(alterColumn.getNewDefaultValue()).isNull();
}
@Test
public void diffCheckAdd() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setCheckConstraint("abc");
basic().compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewCheckConstraint()).isEqualTo("abc");
assertThat(getAlterColumn(diff).getOldCheckConstraint()).isNull();
}
@Test
public void diffCheckRemove() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
MColumn oldCol = basic();
oldCol.setCheckConstraint("abc");
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewCheckConstraint()).isNull();
assertThat(getAlterColumn(diff).getOldCheckConstraint()).isEqualTo("abc");
}
@Test
public void diffCheckChange() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setCheckConstraint("abc");
MColumn oldCol = basic();
oldCol.setCheckConstraint("d");
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewCheckConstraint()).isEqualTo("abc");
assertThat(getAlterColumn(diff).getOldCheckConstraint()).isEqualTo("d");
}
@Test
public void diffDefaultValueAdd() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setDefaultValue("abc");
basic().compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewDefaultValue()).isEqualTo("abc");
assertThat(getAlterColumn(diff).getOldDefaultValue()).isNull();
}
@Test
public void diffDefaultValueRemove() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
MColumn oldCol = basic();
oldCol.setDefaultValue("abc");
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewDefaultValue()).isNull();
assertThat(getAlterColumn(diff).getOldDefaultValue()).isEqualTo("abc");
}
@Test
public void diffDefaultValueChange() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setDefaultValue("abc");
MColumn oldCol = basic();
oldCol.setDefaultValue("d");
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewDefaultValue()).isEqualTo("abc");
assertThat(getAlterColumn(diff).getOldDefaultValue()).isEqualTo("d");
}
@Test
public void diffReferencesAdd() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setReferences("abc");
basic().compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewReferences()).isEqualTo("abc");
assertThat(getAlterColumn(diff).getOldReferences()).isNull();
}
@Test
public void diffReferencesRemove() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
MColumn oldCol = basic();
oldCol.setReferences("abc");
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewReferences()).isNull();
assertThat(getAlterColumn(diff).getOldReferences()).isEqualTo("abc");
}
@Test
public void diffReferencesChange() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setReferences("abc");
MColumn oldCol = basic();
oldCol.setReferences("d");
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).getNewReferences()).isEqualTo("abc");
assertThat(getAlterColumn(diff).getOldReferences()).isEqualTo("d");
}
@Test
public void diffUniqueAdd() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setUnique(true);
basic().compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).isUnique()).isEqualTo(true);
}
@Test
public void diffUniqueRemove() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
MColumn oldCol = basic();
oldCol.setUnique(true);
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).isUnique()).isEqualTo(false);
}
@Test
public void diffUniqueOneToOneAdd() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setUniqueOneToOne(true);
basic().compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).isUniqueOneToOne()).isEqualTo(true);
}
@Test
public void diffUniqueOneToOneRemove() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
MColumn oldCol = basic();
oldCol.setUniqueOneToOne(true);
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).isUniqueOneToOne()).isEqualTo(false);
}
@Test
public void diffHistoryExcludeAdd() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
newCol.setHistoryExclude(true);
basic().compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).isHistoryExclude()).isEqualTo(true);
}
@Test
public void diffHistoryExcludeRemove() throws Exception {
ModelDiff diff = diff();
MColumn newCol = basic();
MColumn oldCol = basic();
oldCol.setHistoryExclude(true);
oldCol.compare(diff, table, newCol);
assertChanges(diff);
assertThat(getAlterColumn(diff).isHistoryExclude()).isEqualTo(false);
}
@NotNull
private AlterColumn getAlterColumn(ModelDiff diff) {
return (AlterColumn) diff.getCreateChanges().get(0);
}
private void assertChanges(ModelDiff diff) {
assertThat(diff.getDropChanges()).isEmpty();
assertThat(diff.getCreateChanges()).hasSize(1);
}
}
@@ -0,0 +1,110 @@
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.DropColumn;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.*;
public class MTableTest {
MTable base() {
MTable table = new MTable("tab");
table.addColumn(new MColumn("id","bigint"));
table.addColumn(new MColumn("name","varchar(20)"));
table.addColumn(new MColumn("status","varchar(3)"));
return table;
}
MTable newTable() {
MTable table = new MTable("tab");
table.addColumn(new MColumn("id","bigint"));
table.addColumn(new MColumn("name","varchar(20)"));
table.addColumn(new MColumn("comment","varchar(1000)"));
return table;
}
MTable newTableAdd2Columns() {
MTable table = new MTable("tab");
table.addColumn(new MColumn("id","bigint"));
table.addColumn(new MColumn("name","varchar(20)"));
table.addColumn(new MColumn("status","varchar(3)"));
table.addColumn(new MColumn("comment","varchar(1000)"));
table.addColumn(new MColumn("note","varchar(2000)"));
return table;
}
MTable newTableModifiedColumn() {
MColumn modCol = new MColumn("name", "varchar(30)");// modified type
modCol.setNotnull(true);
MTable table = new MTable("tab");
table.addColumn(modCol);
table.addColumn(new MColumn("id","bigint"));
table.addColumn(new MColumn("status","varchar(3)"));
return table;
}
@Test
public void testCompare_addColumnDropColumn() throws Exception {
ModelDiff diff = new ModelDiff();
diff.compareTables(base(), newTable());
List<Object> createChanges = diff.getCreateChanges();
assertThat(createChanges).hasSize(1);
AddColumn addColumn = (AddColumn)createChanges.get(0);
assertThat(addColumn.getColumn()).extracting("name").contains("comment");
assertThat(addColumn.getColumn()).extracting("type").contains("varchar(1000)");
List<Object> dropChanges = diff.getDropChanges();
assertThat(dropChanges).hasSize(1);
DropColumn dropColumn = (DropColumn)dropChanges.get(0);
assertThat(dropColumn.getColumnName()).isEqualTo("status");
assertThat(dropColumn.getTableName()).isEqualTo("tab");
}
@Test
public void testCompare_addTwoColumnsToSameTable() throws Exception {
ModelDiff diff = new ModelDiff();
diff.compareTables(base(), newTableAdd2Columns());
List<Object> createChanges = diff.getCreateChanges();
assertThat(createChanges).hasSize(1);
AddColumn addColumn = (AddColumn)createChanges.get(0);
assertThat(addColumn.getColumn()).extracting("name").contains("comment","note");
assertThat(addColumn.getColumn()).extracting("type").contains("varchar(1000)","varchar(2000)");
assertThat(diff.getDropChanges()).hasSize(0);
}
@Test
public void testCompare_modifyColumn() throws Exception {
ModelDiff diff = new ModelDiff();
diff.compareTables(base(), newTableModifiedColumn());
List<Object> createChanges = diff.getCreateChanges();
assertThat(createChanges).hasSize(1);
AlterColumn alterColumn = (AlterColumn)createChanges.get(0);
assertThat(alterColumn.getColumnName()).isEqualTo("name");
assertThat(alterColumn.getType()).isEqualTo("varchar(30)");
assertThat(alterColumn.isNotnull()).isEqualTo(true);
assertThat(alterColumn.isUnique()).isNull();
assertThat(alterColumn.getNewCheckConstraint()).isNull();
assertThat(alterColumn.getNewReferences()).isNull();
assertThat(diff.getDropChanges()).hasSize(0);
}
}
@@ -0,0 +1,39 @@
package com.avaje.ebean.dbmigration.model;
import org.junit.Test;
import static org.assertj.core.api.Assertions.*;
public class MigrationModelTest {
@Test
public void testRead() throws Exception {
MigrationModel migrationModel = new MigrationModel("dbmigration/app1");
ModelContainer model = migrationModel.read();
assertThat(migrationModel.getReadVersions()).contains("1.0","1.1","2.0");
assertThat(model.getTable("v10_table")).isNotNull();
}
@Test
public void testRead_leadingSlash() throws Exception {
MigrationModel migrationModel = new MigrationModel("/dbmigration/app1");
ModelContainer model = migrationModel.read();
assertThat(migrationModel.getReadVersions()).contains("1.0","1.1","2.0");
assertThat(model.getTable("v10_table")).isNotNull();
}
@Test
public void testRead_trailingSlash() throws Exception {
MigrationModel migrationModel = new MigrationModel("/dbmigration/app1/");
ModelContainer model = migrationModel.read();
assertThat(migrationModel.getReadVersions()).contains("1.0","1.1","2.0");
assertThat(model.getTable("v10_table")).isNotNull();
}
}
@@ -32,7 +32,7 @@ public class ModelContainerApplyTest {
model.apply(migration);
MTable foo = model.getTable("foo");
assertThat(foo.getRemarks()).isEqualTo("comment");
assertThat(foo.getComment()).isEqualTo("comment");
assertThat(foo.getTablespace()).isEqualTo("fooSpace");
assertThat(foo.getIndexTablespace()).isEqualTo("fooIndexSpace");
assertThat(foo.getWithHistory()).isEqualTo(true);
@@ -0,0 +1,43 @@
package com.avaje.ebeaninternal.server.type;
import com.avaje.ebean.config.JsonConfig;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
import org.junit.Test;
import java.sql.Timestamp;
import static org.junit.Assert.*;
public class ScalarTypeJodaLocalDateTimeTest {
ScalarTypeJodaLocalDateTime type = new ScalarTypeJodaLocalDateTime(JsonConfig.DateTime.ISO8601);
@Test
public void testConvertFromTimestamp() throws Exception {
long now = System.currentTimeMillis();
Timestamp nowTs = new Timestamp(now);
LocalDateTime ldt1 = type.convertFromTimestamp(nowTs);
LocalDateTime ldt2 = localConvertFromTimestamp(nowTs);
assertEquals(ldt1, ldt2);
Timestamp ts1 = type.convertToTimestamp(ldt1);
Timestamp ts2 = localConvertToTimestamp(ldt2);
assertEquals(ts1, ts2);
}
LocalDateTime localConvertFromTimestamp(Timestamp ts) {
return new LocalDateTime(ts.getTime(), DateTimeZone.getDefault());
}
Timestamp localConvertToTimestamp(LocalDateTime t) {
return new Timestamp(t.toDateTime(DateTimeZone.getDefault()).getMillis());
}
}
@@ -0,0 +1,32 @@
package com.avaje.ebeaninternal.server.type;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
import org.junit.Test;
import java.sql.Timestamp;
import static org.junit.Assert.assertEquals;
public class ScalarTypeJodaLocalTimeTest {
@Test
public void test() {
long now = System.currentTimeMillis();
//DateTimeZone timeZone = DateTimeZone.getDefault();
//ISOChronology instance = ISOChronology.getInstance();
LocalDateTime ldt1 = new LocalDateTime(now, DateTimeZone.getDefault());
LocalDateTime ldt2 = new LocalDateTime(now);
assertEquals(ldt1, ldt2);
Timestamp ts1 = new Timestamp(ldt1.toDateTime(DateTimeZone.getDefault()).getMillis());
Timestamp ts2 = new Timestamp(ldt2.toDateTime().getMillis());
assertEquals(ts1, ts2);
}
}
+2 -13
View File
@@ -13,7 +13,7 @@
</rollback>
</sql>
<createTable name="dbmigration">
<createTable name="v10_table">
<column name="application" type="varchar(30)" notnull="true"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
@@ -21,17 +21,6 @@
<column name="locked_at" type="timestamp"/>
</createTable>
<createTable name="dbmigration_changeset">
<column name="id" type="integer" primaryKey="true"/>
<column name="application" type="varchar(30)" notnull="true" references="dbmigration.application"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
<column name="run_at" type="timestamp" notnull="true"/>
<column name="run_by" type="varchar(30)" notnull="true"/>
<column name="run_ddl" type="clob"/>
<column name="run_log" type="clob"/>
</createTable>
<createTable name="hello_world" withHistory="true">
<column name="id" type="integer" primaryKey="true"/>
<column name="name" type="varchar(20)" notnull="true"/>
@@ -47,7 +36,7 @@
<createHistoryTable baseTable="hello_world"/>
<addForeignKey name="fk_hello_world_x" columns="x" references="asdsad.asd"/>
<!--<addForeignKey name="fk_hello_world_x" columns="x" references="asdsad.asd"/>-->
</changeSet>
+1 -29
View File
@@ -13,7 +13,7 @@
</rollback>
</sql>
<createTable name="dbmigration">
<createTable name="v11_table">
<column name="application" type="varchar(30)" notnull="true"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
@@ -21,34 +21,6 @@
<column name="locked_at" type="timestamp"/>
</createTable>
<createTable name="dbmigration_changeset">
<column name="id" type="integer" primaryKey="true"/>
<column name="application" type="varchar(30)" notnull="true" references="dbmigration.application"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
<column name="run_at" type="timestamp" notnull="true"/>
<column name="run_by" type="varchar(30)" notnull="true"/>
<column name="run_ddl" type="clob"/>
<column name="run_log" type="clob"/>
</createTable>
<createTable name="hello_world" withHistory="true">
<column name="id" type="integer" primaryKey="true"/>
<column name="name" type="varchar(20)" notnull="true"/>
<column name="type" type="varchar(20)" notnull="true"/>
<column name="description" type="varchar(20)" notnull="true"/>
<uniqueConstraint columnNames="name,type"/>
</createTable>
<addColumn tableName="hello_world">
<column name="fooe" type="varchar(20)"/>
</addColumn>
<createHistoryTable baseTable="hello_world"/>
<addForeignKey name="fk_hello_world_x" columns="x" references="asdsad.asd"/>
</changeSet>
<changeSet type="drop" generated="true">
@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ebean-orm.github.io/xml/ns/dbmigration http://ebean-orm.github.io/xml/ns/dbmigration-1.0.xsd">
<changeSet type="apply">
<sql>
<apply>
create table foo;
</apply>
<rollback>
drop table if exists foo;
</rollback>
</sql>
<createTable name="dbmigration_lock">
<column name="application" type="varchar(30)" notnull="true"/>
<column name="locked_by" type="varchar(30)"/>
<column name="locked_at" type="timestamp"/>
</createTable>
<createTable name="dbmigration_run">
<column name="id" type="integer" primaryKey="true"/>
<column name="application" type="varchar(30)" notnull="true" references="dbmigration.application"/>
<column name="version" type="varchar(3)" notnull="true"/>
<column name="run_at" type="timestamp" notnull="true"/>
<column name="run_by" type="varchar(30)" notnull="true"/>
<column name="run_status" type="varchar(30)" notnull="true"/>
<column name="run_ddl" type="clob"/>
<column name="run_log" type="clob"/>
</createTable>
<createTable name="hello_world" withHistory="true">
<column name="id" type="integer" primaryKey="true"/>
<column name="name" type="varchar(20)" notnull="true"/>
<column name="description" type="varchar(20)" notnull="true"/>
</createTable>
<addColumn tableName="hello_world">
<column name="fooe" type="varchar(20)"/>
</addColumn>
<dropColumn columnName="fooe" tableName="hello_world"/>
<createHistoryTable baseTable="hello_world"/>
</changeSet>
<changeSet type="drop" generated="true">
<!-- no drops to do -->
</changeSet>
</migration>
@@ -13,39 +13,6 @@
</rollback>
</sql>
<createTable name="dbmigration">
<column name="application" type="varchar(30)" notnull="true"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
<column name="locked_by" type="varchar(30)"/>
<column name="locked_at" type="timestamp"/>
</createTable>
<createTable name="dbmigration_changeset">
<column name="id" type="integer" primaryKey="true"/>
<column name="application" type="varchar(30)" notnull="true" references="dbmigration.application"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
<column name="run_at" type="timestamp" notnull="true"/>
<column name="run_by" type="varchar(30)" notnull="true"/>
<column name="run_ddl" type="clob"/>
<column name="run_log" type="clob"/>
</createTable>
<createTable name="hello_world" withHistory="true">
<column name="id" type="integer" primaryKey="true"/>
<column name="name" type="varchar(20)" notnull="true"/>
<column name="description" type="varchar(20)" notnull="true"/>
</createTable>
<addColumn tableName="hello_world">
<column name="fooe" type="varchar(20)"/>
</addColumn>
<dropColumn columnName="fooe" tableName="hello_world"/>
<createHistoryTable baseTable="hello_world"/>
</changeSet>
<changeSet type="drop" generated="true">
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ebean-orm.github.io/xml/ns/dbmigration http://ebean-orm.github.io/xml/ns/dbmigration-1.0.xsd">
<changeSet type="apply">
<sql>
<apply>
create table foo;
</apply>
<rollback>
drop table if exists foo;
</rollback>
</sql>
<createTable name="dbmigration">
<column name="application" type="varchar(30)" notnull="true"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
<column name="locked_by" type="varchar(30)"/>
<column name="locked_at" type="timestamp"/>
</createTable>
<createTable name="dbmigration_changeset">
<column name="id" type="integer" primaryKey="true"/>
<column name="application" type="varchar(30)" notnull="true" references="dbmigration.application"/>
<column name="change_log" type="integer" notnull="true"/>
<column name="change_set" type="integer" notnull="true"/>
<column name="run_at" type="timestamp" notnull="true"/>
<column name="run_by" type="varchar(30)" notnull="true"/>
<column name="run_ddl" type="clob"/>
<column name="run_log" type="clob"/>
</createTable>
<createTable name="hello_world" withHistory="true">
<column name="id" type="integer" primaryKey="true"/>
<column name="name" type="varchar(20)" notnull="true"/>
<column name="description" type="varchar(20)" notnull="true"/>
</createTable>
<addColumn tableName="hello_world">
<column name="fooe" type="varchar(20)"/>
</addColumn>
<dropColumn columnName="fooe" tableName="hello_world"/>
<createHistoryTable baseTable="hello_world"/>
</changeSet>
<changeSet type="drop" generated="true">
<!-- no drops to do -->
</changeSet>
</migration>
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<applications xmlns="http://ebean-orm.github.io/xml/ns/dbmigration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ebean-orm.github.io/xml/ns/dbmigration http://ebean-orm.github.io/xml/ns/dbmigration-1.0.xsd">
<application name="myapp" resourcePath="dbmigration/app1"/>
</applications>
+4 -1
View File
@@ -23,7 +23,7 @@ ebean.autofetch.traceUsageCollection=false
ebean.ddl.generate=true
ebean.ddl.run=true
datasource.default=ms
datasource.default=h2
ebean.persistBatch=NONE
ebean.persistBatchOnCascade=ALL
@@ -46,6 +46,9 @@ ebean.cacheWarmingDelay=-1
##ebean.transaction.rollbackOnChecked=false
ebean.migration.appName=myapp
ebean.migration.resourcePath=dbmigration/myapp
## -------------------------------------------------------------
## DataSources (If using default Ebean DataSourceFactory)
+1 -1
View File
@@ -33,7 +33,7 @@
<logger name="org.avaje.ebean.TXN" level="TRACE"/>
<logger name="org.avaje.ebean.SUM" level="TRACE"/>
<logger name="com.avaje.ebeaninternal.server.ddl" level="TRACE"/>
<logger name="com.avaje.ebeaninternal.server.core" level="DEBUG"/>
<logger name="org.avaje.ebean.cache.QUERY" level="TRACE"/>
<logger name="org.avaje.ebean.cache.BEAN" level="TRACE"/>