mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
WIP: Db migration alterColumn ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
+1311
File diff suppressed because it is too large
Load Diff
+1311
File diff suppressed because it is too large
Load Diff
+1311
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>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <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="type" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="oldDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="oldCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="oldReferences" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newReferences" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </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;
|
||||
* <attribute name="defaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <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("::")) {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+43
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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)
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user