Feature/ddl migration (#1111)

* REFACTOR: use functions from ddl-help

* NEW: Default values are written to DDL

* fix testcase for sqlserver as default constraints will get names in future

* Reading DbMigration

* ADD: DbmIgrationGenerateTest

* Tables must be created first

* Sanity checks and some getters

* DdlMigration gets applied now

* ADD: Testcase and reference migration scripts

* no effective code changes: add comments
This commit is contained in:
Roland Praml
2017-09-08 21:47:33 +12:00
committed by Rob Bygrave
parent 73b3d1d977
commit dd8fff0277
90 changed files with 2767 additions and 70 deletions
@@ -0,0 +1,23 @@
package io.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to specify a default value for DDL-generation & Migration.
* This annotation is <b>EXPERMIENTAL</b> and may change.
*
* TODO: Move this annotation to eben-annotation package
*
* @author Roland Praml, FOCONIS AG
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DbDefault {
/**
* The defaultValue for the column.
*/
String value();
}
@@ -0,0 +1,65 @@
package io.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import io.ebean.Platform;
/**
* Annotation to specify details for DDL &amp; Migration-generation. (e.g. defaults/renames/...)
* This annotation is <b>EXPERMIENTAL</b> and may change.
*
* @author Roland Praml, FOCONIS AG
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Repeatable(DbMigration.List.class)
public @interface DbMigration {
/**
* DdlScripts that will be executed before the 'alter' command.
*
* You may write a custom update routine here.
* If you do not specify an SQL here, and this will alter the table
* to a non-null column, ebean will autogenerate a statement from
* default value like this:
* <pre>
* UPDATE table SET column = 'foo' WHERE column IS NULL
* </pre>
*/
String[] preAlter() default {};
/**
* DdlScript that will be executed after the 'alter' command
*/
String[] postAlter() default {};
/**
* DdlScript that will be executed before the 'add' command
*/
String[] preAdd() default {};
/**
* DdlScript that will be executed after the 'add' command.
* You may write certain update scripts here.
*/
String[] postAdd() default {};
// TODO: Do we need preDrop / postDrop?
Platform[] platforms() default {};
/**
* Repeatable support for {@link Formula}.
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@interface List {
DbMigration[] value() default {};
}
}
@@ -287,6 +287,9 @@ public class DatabasePlatform {
* Create and return a DDL handler for generating DDL scripts.
*/
public DdlHandler createDdlHandler(ServerConfig serverConfig) {
if (platformDdl == null) {
throw new IllegalStateException("Platform " + getName() + " has no DDL Handler");
}
return platformDdl.createDdlHandler(serverConfig);
}
@@ -1,8 +1,13 @@
package io.ebean.config.dbplatform;
import java.sql.Types;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.xml.bind.DatatypeConverter;
import io.ebean.annotation.DbDefault;
/**
* DB Column default values mapping to database platform specific literals.
*/
@@ -22,6 +27,13 @@ public class DbDefaultValue {
* The key for the NOW / current timestamp.
*/
public static final String NOW = "now";
/**
* The 'null' literal.
*/
public static final String NULL = "null";
protected Map<String, String> map = new LinkedHashMap<>();
@@ -63,8 +75,128 @@ public class DbDefaultValue {
if (dbDefaultLiteral == null) {
return null;
}
if (dbDefaultLiteral.startsWith("$RAW:")) {
return dbDefaultLiteral.substring(5);
}
String val = map.get(dbDefaultLiteral);
return val != null ? val : dbDefaultLiteral;
}
/**
* This method checks & convert the {@link DbDefault#value()} to a valid SQL literal.
*
* This is mainly to quote string literals and verify integer/dates for correctness.
* <p>
* Note: There are some special cases:
* </p>
* <ul>
* <li>Normal Quoting: <code>@DbDefault("User's default")</code> on a String propery
* returns: <code>default 'User''s default'</code><br/>
* (the same on an integer property will throw a NumberFormatException)</li>
* <li>Special case null: <code>@DbDefault("null")</code> will return this: <code>default null</code><br/>
* If you need really the String "null", you have to specify <code>@DbDefault("'null'")</code>
* which gives you the <code>default 'null'</code> statement.</li>
* <li>Any statement, that begins and ends with single quote will not be checked or get quoted again.</li>
* <li>A statement that begins with "$RAW:", e.g <code>@DbDefault("$RAW:N'SANDNES'")</code> will lead to
* a <code>default N'SANDNES'</code> in DDL. Note that this is platform specific!</li>
* </ul>
*/
public static String toSqlLiteral(String defaultValue, Class<?> propertyType, int sqlType) {
if (propertyType == null
|| defaultValue == null
|| NULL.equals(defaultValue)
|| (defaultValue.startsWith("'") && defaultValue.endsWith("'"))
|| (defaultValue.startsWith("$RAW:"))) {
return defaultValue;
}
if (Boolean.class.isAssignableFrom(propertyType) || Boolean.TYPE.isAssignableFrom(propertyType)) {
return toBooleanLiteral(defaultValue);
}
if (Number.class.isAssignableFrom(propertyType)
|| Byte.TYPE.equals(propertyType)
|| Short.TYPE.equals(propertyType)
|| Integer.TYPE.equals(propertyType)
|| Long.TYPE.equals(propertyType)
|| Float.TYPE.equals(propertyType)
|| Double.TYPE.equals(propertyType)
|| (propertyType.isEnum() && sqlType == Types.INTEGER)) {
Double.valueOf(defaultValue); // verify if it is a number
return defaultValue;
}
// check if it is a date/time - in all other cases return quoted defaultValue
switch (sqlType) {
// date
case Types.DATE:
return toDateLiteral(defaultValue);
// time
case Types.TIME:
case Types.TIME_WITH_TIMEZONE:
return toTimeLiteral(defaultValue);
// timestamp
case Types.TIMESTAMP:
case Types.TIMESTAMP_WITH_TIMEZONE:
return toDateTimeLiteral(defaultValue);
default:
return toTextLiteral(defaultValue); // do not check other datatypes
}
}
/**
* Checks if specified value is either 'true' or 'false'. The literal is translated later.
*/
private static String toBooleanLiteral(String value) {
if (DbDefaultValue.FALSE.equals(value) || DbDefaultValue.TRUE.equals(value)) {
return value;
}
throw new IllegalArgumentException("'" + value + "' is not a valid value for boolean");
}
/**
* This adds single qoutes around the <code>value</code> and doubles single quotes.
* "User's home" will return "'User''s home'"
*/
private static String toTextLiteral(String value) {
StringBuilder sb = new StringBuilder(value.length()+10);
sb.append('\'');
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
if (ch == '\'') {
sb.append("''");
} else {
sb.append(ch);
}
}
sb.append('\'');
return sb.toString();
}
private static String toDateLiteral(String value) {
if (NOW.equals(value)) {
return value; // this will get translated later
}
DatatypeConverter.parseDate(value); // verify
return toTextLiteral(value);
}
private static String toTimeLiteral(String value) {
if (NOW.equals(value)) {
return value; // this will get translated later
}
DatatypeConverter.parseTime(value); // verify
return toTextLiteral(value);
}
private static String toDateTimeLiteral(String value) {
if (NOW.equals(value)) {
return value; // this will get translated later
}
DatatypeConverter.parseDateTime(value); // verify
return toTextLiteral(value);
}
}
@@ -36,6 +36,11 @@ public class BaseDdlHandler implements DdlHandler {
for (Object change : changeSetChildren) {
if (change instanceof CreateTable) {
generate(writer, (CreateTable) change);
}
}
for (Object change : changeSetChildren) {
if (change instanceof CreateTable) {
// ignore
} else if (change instanceof DropTable) {
generate(writer, (DropTable) change);
} else if (change instanceof AddTableComment) {
@@ -54,6 +59,8 @@ public class BaseDdlHandler implements DdlHandler {
generate(writer, (AddHistoryTable) change);
} else if (change instanceof DropHistoryTable) {
generate(writer, (DropHistoryTable) change);
} else {
throw new IllegalArgumentException("Unsupported change: " + change);
}
}
}
@@ -15,6 +15,7 @@ import io.ebean.dbmigration.migration.AlterColumn;
import io.ebean.dbmigration.migration.Column;
import io.ebean.dbmigration.migration.CreateIndex;
import io.ebean.dbmigration.migration.CreateTable;
import io.ebean.dbmigration.migration.DdlScript;
import io.ebean.dbmigration.migration.DropColumn;
import io.ebean.dbmigration.migration.DropHistoryTable;
import io.ebean.dbmigration.migration.DropIndex;
@@ -27,6 +28,8 @@ import io.ebean.util.StringHelper;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -70,6 +73,119 @@ public class BaseTableDdl implements TableDdl {
*/
protected Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<>();
private boolean strict;
/**
* Helper class that is used to execute the migration ddl before and after the migration action.
*/
private class DdlMigrationHelp {
private List<String> before;
private List<String> after;
private String tableName;
private String columnName;
private String defaultValue;
/**
* Constructor for DdlMigrationHelp when adding a NEW column.
*/
DdlMigrationHelp(String tableName, Column column) throws IOException {
this.tableName = tableName;
this.columnName = column.getName();
this.defaultValue = platformDdl.convertDefaultValue(column.getDefaultValue());
boolean alterNotNull = Boolean.TRUE.equals(column.isNotnull());
if (column.getBefore().isEmpty() && alterNotNull && defaultValue == null) {
handleStrictError("non-null column has no default value: " + tableName + "." + columnName);
}
before = getScriptsForPlatform(column.getBefore(), platformDdl.getPlatform().getName());
after = getScriptsForPlatform(column.getAfter(), platformDdl.getPlatform().getName());
}
/**
* Constructor for DdlMigrationHelp when altering a column.
*/
DdlMigrationHelp(AlterColumn alter) throws IOException {
this.tableName = alter.getTableName();
this.columnName = alter.getColumnName();
String tmp = alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue();
this.defaultValue = platformDdl.convertDefaultValue(tmp);
boolean alterNotNull = Boolean.TRUE.equals(alter.isNotnull());
// here we add the platform's default update script
if (alter.getBefore().isEmpty() && alterNotNull) {
if (defaultValue == null) {
handleStrictError("non-null column has no default value: " + tableName + "." + columnName);
}
before = Arrays.asList(platformDdl.getUpdateNullWithDefault());
} else {
before = getScriptsForPlatform(alter.getBefore(), platformDdl.getPlatform().getName());
}
after = getScriptsForPlatform(alter.getAfter(), platformDdl.getPlatform().getName());
}
public void writeBefore(DdlBuffer buffer) throws IOException {
if (!before.isEmpty()) {
buffer.end();
}
for (String ddlScript : before) {
buffer.append(translate(ddlScript, tableName, columnName, this.defaultValue));
buffer.endOfStatement();
}
}
public void writeAfter(DdlBuffer buffer) throws IOException {
// here we run postmigration scripts
for (String ddlScript : after) {
buffer.append(translate(ddlScript, tableName, columnName, defaultValue));
buffer.endOfStatement();
}
if (!after.isEmpty()) {
buffer.end();
}
}
private List<String> getScriptsForPlatform(List<DdlScript> scripts, String searchPlatform) {
List<String> ret = Collections.emptyList();
for (DdlScript script : scripts) {
if (script.getPlatforms() == null || script.getPlatforms().isEmpty()) {
ret = script.getDdl();
} else for (String platform : StringHelper.splitNames(script.getPlatforms())) {
if (platform.equals(searchPlatform)) {
return script.getDdl();
}
}
}
return ret;
}
/**
* Replaces Table name (${table}), Column name (${column}) and default value (${default}) in DDL.
*/
private String translate(String ddl, String tableName, String columnName, String defaultValue) {
String ret = StringHelper.replaceString(ddl, "${table}", tableName);
ret = StringHelper.replaceString(ret, "${column}", columnName);
return StringHelper.replaceString(ret, "${default}", defaultValue);
}
private void handleStrictError(String message) {
if (strict) {
throw new IllegalArgumentException(message);
} else {
System.err.println("Error in DDL: " + message);
}
}
public String getDefaultValue() {
return defaultValue;
}
}
/**
* Construct with a naming convention and platform specific DDL.
*/
@@ -79,6 +195,7 @@ public class BaseTableDdl implements TableDdl {
this.historyTableSuffix = serverConfig.getHistoryTableSuffix();
this.platformDdl = platformDdl;
this.platformDdl.configure(serverConfig);
this.strict = true; // TODO RPr serverConfig.getMigrationConfig().isStrict();
}
/**
@@ -649,7 +766,9 @@ public class BaseTableDdl implements TableDdl {
*/
@Override
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
DdlMigrationHelp ddlHelp = new DdlMigrationHelp(alterColumn);
ddlHelp.writeBefore(writer.apply());
if (isTrue(alterColumn.isHistoryExclude())) {
regenerateHistoryTriggers(alterColumn.getTableName(), HistoryTableUpdate.Change.EXCLUDE, alterColumn.getColumnName());
} else if (isFalse(alterColumn.isHistoryExclude())) {
@@ -702,6 +821,7 @@ public class BaseTableDdl implements TableDdl {
// add constraint last (after potential type change)
addCheckConstraint(writer, alterColumn);
}
ddlHelp.writeAfter(writer.apply());
}
private void alterColumnComment(DdlWrite writer, AlterColumn alterColumn) throws IOException {
@@ -856,11 +976,11 @@ public class BaseTableDdl implements TableDdl {
}
protected void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable) throws IOException {
String ddl = platformDdl.alterTableAddColumn(tableName, column, onHistoryTable);
if (hasValue(ddl)) {
buffer.append(ddl);
buffer.endOfStatement();
}
DdlMigrationHelp help = new DdlMigrationHelp(tableName, column);
help.writeBefore(buffer);
platformDdl.alterTableAddColumn(buffer, tableName, column, onHistoryTable, help.getDefaultValue());
help.writeAfter(buffer);
}
protected boolean isFalse(Boolean value) {
@@ -59,7 +59,7 @@ public class MySqlDdl extends PlatformDdl {
@Override
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
String suffix = isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + defaultValue;
String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + defaultValue;
// use alter
return "alter table " + tableName + " alter " + columnName + " " + suffix;
@@ -67,7 +67,9 @@ public class MySqlDdl extends PlatformDdl {
@Override
public String alterColumnBaseAttributes(AlterColumn alter) {
if (DdlHelp.isDropDefault(alter.getDefaultValue())) {
return null;
}
String tableName = alter.getTableName();
String columnName = alter.getColumnName();
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
@@ -87,6 +87,8 @@ public class PlatformDdl {
protected String columnSetNotnull = "set not null";
protected String columnSetNull = "set null";
protected String updateNullWithDefault = "update ${table} set ${column} = ${default} where ${column} is null";
/**
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
@@ -205,7 +207,7 @@ public class PlatformDdl {
/**
* Convert the DB column default literal to platform specific.
*/
private String convertDefaultValue(String dbDefault) {
public String convertDefaultValue(String dbDefault) {
return dbDefaultValue.convert(dbDefault);
}
@@ -379,25 +381,38 @@ public class PlatformDdl {
return buffer.toString();
}
public String alterTableAddColumn(String tableName, Column column, boolean onHistoryTable) throws IOException {
public void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, String defaultValue) throws IOException {
String convertedType = convert(column.getType(), false);
StringBuilder buffer = new StringBuilder(90);
buffer.append("alter table ").append(tableName)
.append(' ').append(addColumn).append(' ').append(column.getName())
.append(' ').append(convertedType);
.append(" ").append(addColumn).append(" ").append(column.getName())
.append(" ").append(convertedType);
if (!onHistoryTable) {
if (isTrue(column.isNotnull())) {
buffer.append(" not null");
}
if (!StringHelper.isNull(column.getCheckConstraint())) {
buffer.append(" constraint ").append(column.getCheckConstraintName());
buffer.append(" ").append(column.getCheckConstraint());
if (defaultValue != null) {
if (typeContainsDefault(convertedType)) {
System.err.println("Cannot set default value for '" + tableName + "." + column.getName() + "'");
} else {
buffer.append(" default ");
buffer.append(defaultValue);
}
}
buffer.endOfStatement();
// check constraints cannot be added in one statement for h2
if (!StringHelper.isNull(column.getCheckConstraint())) {
String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint());
buffer.append(ddl).endOfStatement();
}
} else {
buffer.endOfStatement();
}
return buffer.toString();
}
/**
@@ -440,19 +455,11 @@ public class PlatformDdl {
return "alter table " + tableName + " " + addConstraint + " " + checkConstraintName + " " + checkConstraint;
}
/**
* Return true if the default value is the special DROP DEFAULT value.
*/
public boolean isDropDefault(String defaultValue) {
return "DROP DEFAULT".equals(defaultValue);
}
/**
* Alter column setting the default value.
*/
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
String suffix = isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + defaultValue;
String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + defaultValue;
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix;
}
@@ -505,6 +512,13 @@ public class PlatformDdl {
return naming.lowerColumnName(name);
}
public DatabasePlatform getPlatform() {
return platform;
}
public String getUpdateNullWithDefault() {
return updateNullWithDefault;
}
/**
* Null safe Boolean true test.
@@ -103,16 +103,19 @@ public class SqlServerDdl extends PlatformDdl {
@Override
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
if (isDropDefault(defaultValue)) {
return "-- alter table " + tableName + " drop constraint <unknown> -- find the appropriate constraint for default value on column " + columnName;
if (DdlHelp.isDropDefault(defaultValue)) {
return "alter table " + tableName + " drop constraint df_" + tableName + "_" + columnName;
} else {
return "alter table " + tableName + " add default " + defaultValue + " for " + columnName;
return "alter table " + tableName + " add constraint df_" + tableName + "_" + columnName
+ " default " + defaultValue + " for " + columnName;
}
}
@Override
public String alterColumnBaseAttributes(AlterColumn alter) {
if (DdlHelp.isDropDefault(alter.getDefaultValue())) {
return null;
}
String tableName = alter.getTableName();
String columnName = alter.getColumnName();
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
@@ -1,8 +1,12 @@
package io.ebean.dbmigration.migration;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@@ -44,10 +48,17 @@ import javax.xml.bind.annotation.XmlType;
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlType(name = "", propOrder = {
"before", "after"
})
@XmlRootElement(name = "alterColumn")
public class AlterColumn {
@XmlElement(required = false)
protected List<DdlScript> before;
@XmlElement(required = false)
protected List<DdlScript> after;
@XmlAttribute(name = "columnName", required = true)
protected String columnName;
@XmlAttribute(name = "tableName", required = true)
@@ -533,4 +544,17 @@ public class AlterColumn {
this.dropForeignKeyIndex = value;
}
public List<DdlScript> getBefore() {
if (before == null) {
before = new ArrayList<>();
}
return before;
}
public List<DdlScript> getAfter() {
if (after == null) {
after = new ArrayList<>();
}
return after;
}
}
@@ -1,8 +1,12 @@
package io.ebean.dbmigration.migration;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
@@ -39,13 +43,16 @@ import javax.xml.bind.annotation.XmlValue;
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"content"
"before", "after"
})
@XmlRootElement(name = "column")
public class Column {
@XmlValue
protected String content;
@XmlElement(required = false)
protected List<DdlScript> before;
@XmlElement(required = false)
protected List<DdlScript> after;
@XmlAttribute(name = "name", required = true)
protected String name;
@XmlAttribute(name = "type", required = true)
@@ -76,27 +83,22 @@ public class Column {
protected String foreignKeyIndex;
@XmlAttribute(name = "comment")
protected String comment;
/**
* Gets the value of the content property.
*
* @return possible object is
* {@link String }
*/
public String getContent() {
return content;
public List<DdlScript> getBefore() {
if (before == null) {
before = new ArrayList<>();
}
return before;
}
/**
* Sets the value of the content property.
*
* @param value allowed object is
* {@link String }
*/
public void setContent(String value) {
this.content = value;
public List<DdlScript> getAfter() {
if (after == null) {
after = new ArrayList<>();
}
return after;
}
/**
* Gets the value of the name property.
*
@@ -0,0 +1,73 @@
package io.ebean.dbmigration.migration;
import java.util.ArrayList;
import java.util.List;
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;
import javax.xml.bind.annotation.XmlValue;
/**
* <p>Java class for anonymous complex type.
* <p>
* <p>The following schema fragment specifies the expected content contained within this class.
* <p>
* <pre>
* TODO @Rob: Can this generated automatically?
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"ddl"
})
@XmlRootElement(name = "ddl-script")
public class DdlScript {
@XmlValue
protected List<String> ddl;
@XmlAttribute(name = "platforms")
protected String platforms;
/**
* Gets the value of the value property.
*
* @return possible object is
* {@link String }
*/
public List<String> getDdl() {
if (ddl == null) {
ddl = new ArrayList<>();
}
return ddl;
}
public void setDdl(List<String> ddl) {
this.ddl = ddl;
}
/**
* Gets the value of the platforms property.
*
* @return possible object is
* {@link String }
*/
public String getPlatforms() {
return platforms;
}
/**
* Sets the value of the platforms property.
*
* @param value allowed object is
* {@link String }
*/
public void setPlatforms(String value) {
this.platforms = value;
}
}
@@ -1,8 +1,14 @@
package io.ebean.dbmigration.model;
import java.util.List;
import javax.sound.midi.MidiDevice.Info;
import io.ebean.dbmigration.ddlgeneration.platform.DdlHelp;
import io.ebean.dbmigration.migration.AlterColumn;
import io.ebean.dbmigration.migration.Column;
import io.ebean.dbmigration.migration.DdlScript;
import io.ebeaninternal.server.deploy.DbMigrationInfo;
/**
* A column in the logical model.
@@ -38,6 +44,8 @@ public class MColumn {
private AlterColumn alterColumn;
private boolean draftOnly;
private List<DbMigrationInfo> dbMigrationInfos;
public MColumn(Column column) {
this.name = column.getName();
@@ -78,6 +86,7 @@ public class MColumn {
copy.checkConstraint = checkConstraint;
copy.checkConstraintName = checkConstraintName;
copy.defaultValue = defaultValue;
copy.dbMigrationInfos = dbMigrationInfos;
copy.references = references;
copy.comment = comment;
copy.foreignKeyName = foreignKeyName;
@@ -257,6 +266,24 @@ public class MColumn {
c.setComment(comment);
c.setUnique(unique);
c.setUniqueOneToOne(uniqueOneToOne);
if (dbMigrationInfos != null) {
for (DbMigrationInfo info : dbMigrationInfos) {
if (!info.getPreAdd().isEmpty()) {
DdlScript script = new DdlScript();
script.setDdl(info.getPreAdd());
script.setPlatforms(info.joinPlatforms());
c.getBefore().add(script);
}
if (!info.getPostAdd().isEmpty()) {
DdlScript script = new DdlScript();
script.setDdl(info.getPostAdd());
script.setPlatforms(info.joinPlatforms());
c.getAfter().add(script);
}
}
}
return c;
}
@@ -281,6 +308,24 @@ public class MColumn {
if (tableWithHistory) {
alterColumn.setWithHistory(Boolean.TRUE);
}
if (dbMigrationInfos != null) {
for (DbMigrationInfo info : dbMigrationInfos) {
if (!info.getPreAlter().isEmpty()) {
DdlScript script = new DdlScript();
script.setDdl(info.getPreAlter());
script.setPlatforms(info.joinPlatforms());
alterColumn.getBefore().add(script);
}
if (!info.getPostAlter().isEmpty()) {
DdlScript script = new DdlScript();
script.setDdl(info.getPostAlter());
script.setPlatforms(info.joinPlatforms());
alterColumn.getAfter().add(script);
}
}
}
}
return alterColumn;
}
@@ -291,6 +336,8 @@ public class MColumn {
*/
public void compare(ModelDiff modelDiff, MTable table, MColumn newColumn) {
this.dbMigrationInfos = newColumn.dbMigrationInfos;
boolean tableWithHistory = table.isWithHistory();
String tableName = table.getName();
@@ -383,6 +430,10 @@ public class MColumn {
}
}
public void setDbMigrationInfos(List<DbMigrationInfo> dbMigrationInfos) {
this.dbMigrationInfos = dbMigrationInfos;
}
/**
* Apply changes based on the AlterColumn request.
*/
@@ -177,7 +177,8 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
String refColumn = importedProperty.getDbColumn();
MColumn col = table.addColumn(dbCol, columnDefn, !p.isNullable());
col.setDbMigrationInfos(p.getDbMigrationInfos());
col.setDefaultValue(p.getDbColumnDefault());
if (columns.length == 1) {
// single references column (put it on the column)
String refTable = importedProperty.getBeanDescriptor().getBaseTable();
@@ -232,6 +233,7 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
}
} else {
col.setDefaultValue(p.getDbColumnDefault());
col.setDbMigrationInfos(p.getDbMigrationInfos());
if (!p.isNullable() || p.isDDLNotNull()) {
col.setNotnull(true);
}
@@ -2,9 +2,11 @@ package io.ebeaninternal.server.deploy;
import com.fasterxml.jackson.core.JsonToken;
import io.ebean.ValuePair;
import io.ebean.annotation.DbDefault;
import io.ebean.bean.EntityBean;
import io.ebean.bean.PersistenceContext;
import io.ebean.config.EncryptKey;
import io.ebean.config.dbplatform.DbDefaultValue;
import io.ebean.config.dbplatform.DbEncryptFunction;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.plugin.Property;
@@ -232,6 +234,7 @@ public class BeanProperty implements ElPropertyValue, Property {
* DB Column default value for DDL definition (FALSE, NOW etc).
*/
final String dbColumnDefault;
final List<DbMigrationInfo> dbMigrationInfos;
/**
* Database DDL column comment.
@@ -303,7 +306,8 @@ public class BeanProperty implements ElPropertyValue, Property {
this.dbLength = deploy.getDbLength();
this.dbScale = deploy.getDbScale();
this.dbColumnDefn = InternString.intern(deploy.getDbColumnDefn());
this.dbColumnDefault = deploy.getDbColumnDefault();
this.dbColumnDefault = DbDefaultValue.toSqlLiteral(deploy.getDbColumnDefault(), deploy.getPropertyType(), deploy.getDbType());
this.dbMigrationInfos = deploy.getDbMigrationInfos();
this.inherited = false;// deploy.isInherited();
this.owningType = deploy.getOwningType();
@@ -414,6 +418,7 @@ public class BeanProperty implements ElPropertyValue, Property {
this.dbScale = source.getDbScale();
this.dbColumnDefn = InternString.intern(source.getDbColumnDefn());
this.dbColumnDefault = source.dbColumnDefault;
this.dbMigrationInfos = source.dbMigrationInfos;
this.inherited = source.isInherited();
this.owningType = source.owningType;
@@ -1033,6 +1038,13 @@ public class BeanProperty implements ElPropertyValue, Property {
return dbColumnDefn != null ? null : dbColumnDefault;
}
/**
* Return the DDL-Migration Infos
*/
public List<DbMigrationInfo> getDbMigrationInfos() {
return dbMigrationInfos;
}
/**
* Return the bean Field associated with this property.
*/
@@ -0,0 +1,71 @@
package io.ebeaninternal.server.deploy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import io.ebean.Platform;
/**
* Class to hold the DDL-migration information that is needed to do correct alters.
*
* @author Roland Praml, FOCONIS AG
*/
public class DbMigrationInfo {
private final List<String> preAdd;
private final List<String> postAdd;
private final List<String> preAlter;
private final List<String> postAlter;
private final List<Platform> platforms;
public DbMigrationInfo(String[] preAdd, String[] postAdd, String[] preAlter, String[] postAlter, Platform[] platforms) {
this.preAdd = toList(preAdd);
this.postAdd = toList(postAdd);
this.preAlter = toList(preAlter);
this.postAlter = toList(postAlter);
this.platforms = toList(platforms);
}
private <T> List<T> toList(T[] scripts) {
if (scripts.length == 0) {
return Collections.emptyList();
} else {
return Collections.unmodifiableList(Arrays.asList(scripts));
}
}
public List<String> getPreAdd() {
return preAdd;
}
public List<String> getPostAdd() {
return postAdd;
}
public List<String> getPreAlter() {
return preAlter;
}
public List<String> getPostAlter() {
return postAlter;
}
public List<Platform> getPlatforms() {
return platforms;
}
public String joinPlatforms() {
if (platforms.isEmpty()) {
return null;
} else {
StringBuilder sb = new StringBuilder();
for (Platform p : platforms) {
if (sb.length() > 0) {
sb.append(',');
}
sb.append(p.name().toLowerCase());
}
return sb.toString();
}
}
}
@@ -17,6 +17,7 @@ import io.ebean.config.dbplatform.DbEncryptFunction;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.DeployDocPropertyOptions;
import io.ebeaninternal.server.deploy.DbMigrationInfo;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.deploy.parse.AnnotationBase;
import io.ebeaninternal.server.el.ElPropertyValue;
@@ -34,7 +35,9 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
@@ -221,6 +224,8 @@ public class DeployBeanProperty {
private String dbColumnDefault;
private List<DbMigrationInfo> dbMigrationInfos;
public DeployBeanProperty(DeployBeanDescriptor<?> desc, Class<?> propertyType, ScalarType<?> scalarType, ScalarTypeConverter<?, ?> typeConverter) {
this.desc = desc;
this.propertyType = propertyType;
@@ -949,7 +954,9 @@ public class DeployBeanProperty {
public void checkPrimitiveBoolean() {
if (boolean.class.equals(propertyType) && !softDelete) {
this.nullable = false;
this.dbColumnDefault = DbDefaultValue.FALSE;
if (dbColumnDefault == null) {
this.dbColumnDefault = DbDefaultValue.FALSE;
}
} else if (!id && !versionColumn && PRIMITIVE_NUMBER_TYPES.contains(propertyType)) {
this.nullable = false;
@@ -1003,6 +1010,10 @@ public class DeployBeanProperty {
return dbColumnDefault;
}
public void setDbColumnDefault(String dbColumnDefault) {
this.dbColumnDefault = dbColumnDefault;
}
public void setTenantId() {
this.tenantId = true;
this.nullable = false;
@@ -1013,4 +1024,15 @@ public class DeployBeanProperty {
public boolean isTenantId() {
return tenantId;
}
public void addDbMigrationInfo(DbMigrationInfo info) {
if (dbMigrationInfos == null) {
dbMigrationInfos = new ArrayList<>();
}
dbMigrationInfos.add(info);
}
public List<DbMigrationInfo> getDbMigrationInfos() {
return dbMigrationInfos;
}
}
@@ -7,6 +7,7 @@ import io.ebean.config.dbplatform.DbEncrypt;
import io.ebean.config.dbplatform.DbEncryptFunction;
import io.ebean.config.dbplatform.IdType;
import io.ebean.config.dbplatform.PlatformIdGenerator;
import io.ebeaninternal.server.deploy.DbMigrationInfo;
import io.ebeaninternal.server.deploy.IndexDefinition;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
@@ -131,6 +132,7 @@ public class AnnotationFields extends AnnotationParser {
}
initWhoProperties(prop);
readDbMigration(prop);
}
private void initWhoProperties(DeployBeanProperty prop) {
@@ -287,14 +289,20 @@ public class AnnotationFields extends AnnotationParser {
if (get(prop, HistoryExclude.class) != null) {
prop.setExcludedFromHistory();
}
Length length = get(prop, Length.class);
if (length != null) {
prop.setDbLength(length.value());
}
io.ebean.annotation.NotNull nonNull = get(prop, io.ebean.annotation.NotNull.class);
if (nonNull != null) {
prop.setNullable(false);
}
readDbMigration(prop);
if (validationAnnotations) {
NotNull notNull = get(prop, NotNull.class);
if (notNull != null && isEbeanValidationGroups(notNull.groups())) {
@@ -346,6 +354,17 @@ public class AnnotationFields extends AnnotationParser {
}
}
private void readDbMigration(DeployBeanProperty prop) {
DbDefault dbDefault = get(prop, DbDefault.class);
if (dbDefault != null) {
prop.setDbColumnDefault(dbDefault.value());
}
Set<DbMigration> dbMigration = getAll(prop, DbMigration.class);
dbMigration.forEach(ann -> prop.addDbMigrationInfo(
new DbMigrationInfo(ann.preAdd(), ann.postAdd(), ann.preAlter(), ann.postAlter(), ann.platforms())));
}
private void addIndex(DeployBeanProperty prop, Index index) {
String[] columnNames;
if (index.columnNames().length == 0) {
@@ -0,0 +1,109 @@
package io.ebean.dbmigration;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Platform;
import io.ebean.config.ServerConfig;
import org.junit.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
/**
* This is the Migrationscript generator. It generates 3 migrationscript for the models
* @author Roland Praml, FOCONIS AG
*
*/
public class DbMigrationGenerateTest {
private static final Logger logger = LoggerFactory.getLogger(DbMigrationGenerateTest.class);
@Test
public void invokeTest() throws IOException {
main(null);
}
public static void main(String[] args) throws IOException {
logger.info("start");
DbMigration migration = new DbMigration();
// We use src/test/resources as output directory (so we see in GIT if files will change)
migration.setPathToResources("src/test/resources");
// migration.addPlatform(Platform.GENERIC, "generic"); there is no ddl handler for generic
// migration.addPlatform(Platform.SQLANYWHERE, "sqlanywhere"); and sqlanywhere
migration.addPlatform(Platform.DB2, "db2");
migration.addPlatform(Platform.H2, "h2");
migration.addPlatform(Platform.HSQLDB, "hsqldb");
migration.addPlatform(Platform.MYSQL, "mysql");
migration.addPlatform(Platform.POSTGRES, "postgres");
migration.addPlatform(Platform.ORACLE, "oracle");
migration.addPlatform(Platform.SQLITE, "sqlite");
migration.addPlatform(Platform.SQLSERVER, "sqlserver");
ServerConfig config = new ServerConfig();
config.setName("migrationtest");
config.loadFromProperties();
config.setRegister(false);
config.setDefaultServer(false);
config.setPackages(Arrays.asList("misc.migration.v1_0"));
EbeanServer server = EbeanServerFactory.create(config);
migration.setServer(server);
// First, we clean up the output-directory
assertThat(migration.getMigrationDirectory().getAbsolutePath()).contains("migrationtest");
Files.walk(migration.getMigrationDirectory().toPath())
.filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete);
// then we generate migration scripts for v1_0
assertThat(migration.generateMigration()).isEqualTo("1.0__initial");
// and we check repeatative calls
assertThat(migration.generateMigration()).isNull();
// and now for v1_1
config.setPackages(Arrays.asList("misc.migration.v1_1"));
server = EbeanServerFactory.create(config);
migration.setServer(server);
assertThat(migration.generateMigration()).isEqualTo("1.1");
assertThat(migration.generateMigration()).isNull(); // subsequent call
System.setProperty("ddl.migration.pendingDropsFor", "1.1");
assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1");
System.clearProperty("ddl.migration.pendingDropsFor");
assertThat(migration.generateMigration()).isNull(); // subsequent call
// and now for v1_2 with
config.setPackages(Arrays.asList("misc.migration.v1_2"));
server = EbeanServerFactory.create(config);
migration.setServer(server);
assertThat(migration.generateMigration()).isEqualTo("1.3");
assertThat(migration.generateMigration()).isNull(); // subsequent call
System.setProperty("ddl.migration.pendingDropsFor", "1.3");
assertThat(migration.generateMigration()).isEqualTo("1.4__dropsFor_1.3");
System.clearProperty("ddl.migration.pendingDropsFor");
assertThat(migration.generateMigration()).isNull(); // subsequent call
logger.info("end");
}
}
@@ -1,31 +1,142 @@
package io.ebean.dbmigration;
import io.ebean.BaseTestCase;
import io.ebean.SqlQuery;
import io.ebean.SqlRow;
import io.ebean.SqlUpdate;
import io.ebean.Transaction;
import io.ebean.dbmigration.ddl.DdlRunner;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.List;
import javax.persistence.PersistenceException;
public class DbMigrationTest extends BaseTestCase {
private static final Logger logger = LoggerFactory.getLogger(DbMigrationTest.class);
//@Ignore
private int runScript(boolean expectErrors, String scriptName) throws IOException {
try (InputStream stream = getClass().getResourceAsStream("/dbmigration/migrationtest/" + server().getPluginApi().getDatabasePlatform().getName()+"/" + scriptName);
java.util.Scanner s = new java.util.Scanner(stream)) {
s.useDelimiter("\\A");
if (s.hasNext()) {
return runScript(expectErrors, s.next(), scriptName);
}
}
return 0;
}
private int runScript(boolean expectErrors, String content, String scriptName) {
DdlRunner runner = new DdlRunner(expectErrors, scriptName);
Transaction transaction = server().createTransaction();
Connection connection = transaction.getConnection();
try {
if (expectErrors) {
connection.setAutoCommit(true);
}
int count = runner.runAll(content, connection);
if (expectErrors) {
connection.setAutoCommit(false);
}
transaction.commit();
return count;
} catch (SQLException e) {
throw new PersistenceException("Failed to run script", e);
} finally {
transaction.end();
}
}
@Test
public void writeCurrent() {
public void testRunMigration() throws IOException {
// first clean up previously created objects
runScript(true, "drop table migtest_e_ref;\n","test");
runScript(true, "drop table migtest_e_basic;\n"
+ "drop table migtest_e_history;\n"
+ "drop table migtest_e_ref;\n"
+ "drop table migtest_e_ref cascade;\n"
+ "drop table migtest_e_user;\n"
+ "drop table migtest_e_history;\n"
+ "drop table migtest_e_history cascade;\n" // pg
+ "drop table migtest_e_history_history cascade;\n" // pg
+ "drop sequence migtest_e_basic_seq;\n"
+ "drop sequence migtest_e_history_seq;\n"
+ "drop sequence migtest_e_ref_seq;\n"
+ "drop sequence migtest_e_user;\n"
+ "drop sequence migtest_e_history;\n"
, "cleanup");
runScript(false, "1.0__initial.sql");
SqlUpdate update = server().createSqlUpdate("insert into migtest_e_basic (id, old_boolean, user_id) values (1, :false, 1), (2, :true, 1)");
update.setParameter("false", false);
update.setParameter("true", true);
assertThat(server().execute(update)).isEqualTo(2);
logger.info("start");
DbOffline.asH2();
DbMigration migration = new DbMigration();
DbOffline.reset();
// Run migration
runScript(false, "1.1.sql");
SqlQuery select = server().createSqlQuery("select * from migtest_e_basic order by id");
List<SqlRow> result = select.findList();
assertThat(result).hasSize(2);
SqlRow row = result.get(0);
assertThat(row.keySet()).contains("old_boolean", "old_boolean2");
assertThat(row.getInteger("id")).isEqualTo(1);
assertThat(row.getBoolean("old_boolean")).isFalse();
assertThat(row.getBoolean("new_boolean_field")).isFalse(); // test if update old_boolean -> new_boolean_field works well
assertThat(row.getString("new_string_field")).isEqualTo("foo'bar");
assertThat(row.getBoolean("new_boolean_field2")).isTrue();
assertThat(row.getTimestamp("some_date")).isEqualTo(new Timestamp(100, 0, 1, 0, 0, 0, 0)); // = 2000-01-01T00:00:00
row = result.get(1);
assertThat(row.getInteger("id")).isEqualTo(2);
assertThat(row.getBoolean("old_boolean")).isTrue();
assertThat(row.getBoolean("new_boolean_field")).isTrue(); // test if update old_boolean -> new_boolean_field works well
assertThat(row.getString("new_string_field")).isEqualTo("foo'bar");
assertThat(row.getBoolean("new_boolean_field2")).isTrue();
assertThat(row.getTimestamp("some_date")).isEqualTo(new Timestamp(100, 0, 1, 0, 0, 0, 0)); // = 2000-01-01T00:00:00
//migration.writeCurrent();
// Run migration & drops
runScript(false, "1.2__dropsFor_1.1.sql");
assertThat(DbOffline.isSet()).isFalse();
logger.info("end");
select = server().createSqlQuery("select * from migtest_e_basic order by id");
result = select.findList();
assertThat(result).hasSize(2);
row = result.get(0);
assertThat(row.keySet()).doesNotContain("old_boolean", "old_boolean2");
runScript(false, "1.3.sql");
runScript(false, "1.4__dropsFor_1.3.sql");
// now DB structure shoud be the same as v1_0
select = server().createSqlQuery("select * from migtest_e_basic order by id");
result = select.findList();
assertThat(result).hasSize(2);
row = result.get(0);
assertThat(row.keySet()).contains("old_boolean", "old_boolean2");
}
}
@@ -48,7 +48,8 @@ public class BaseDdlHandlerTest extends BaseTestCase {
DdlWrite write = new DdlWrite();
h2Handler().generate(write, Helper.getAlterTableAddColumnWithCheckConstraint());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column status integer constraint ck_ordering_status check ( status in (0,1));\n\n");
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column status integer;\n"
+ "alter table foo add constraint ck_ordering_status check ( status in (0,1));\n\n");
}
/**
@@ -157,7 +157,7 @@ public class PlatformDdl_AlterColumnTest {
assertEquals("alter table mytab alter acol set default 'hi'", sql);
sql = sqlServerDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
assertEquals("alter table mytab add default 'hi' for acol", sql);
assertEquals("alter table mytab add constraint df_mytab_acol default 'hi' for acol", sql);
}
@Test
@@ -176,7 +176,7 @@ public class PlatformDdl_AlterColumnTest {
assertEquals("alter table mytab alter acol drop default", sql);
sql = sqlServerDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
assertTrue(sql, sql.startsWith("-- alter"));
assertEquals("alter table mytab drop constraint df_mytab_acol", sql);
}
}
@@ -0,0 +1,116 @@
package misc.migration.v1_0;
import io.ebean.annotation.EnumValue;
import io.ebean.annotation.Index;
import io.ebean.annotation.NotNull;
import misc.migration.v1_1.EUser;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.sql.Timestamp;
@Entity
@Table(name = "migtest_e_basic")
public class EBasic {
public enum Status {
@EnumValue("N")
NEW,
@EnumValue("A")
ACTIVE,
@EnumValue("I")
INACTIVE,
}
@Id
Integer id;
Status status;
String name;
String description;
Timestamp someDate;
boolean old_boolean;
Boolean old_boolean2;
@ManyToOne
ERef eref;
// test add & remove indices
@Index
String indextest1;
@Index(unique = true)
String indextest2;
String indextest3;
String indextest4;
@Index(unique = false)
String indextest5;
@Index(unique = true)
String indextest6;
@NotNull
int user_id;
public EBasic() {
}
public EBasic(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Timestamp getSomeDate() {
return someDate;
}
public void setSomeDate(Timestamp someDate) {
this.someDate = someDate;
}
}
@@ -0,0 +1,17 @@
package misc.migration.v1_0;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "migtest_e_history")
public class EHistory {
@Id
Integer id;
String testString;
}
@@ -0,0 +1,19 @@
package misc.migration.v1_0;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "migtest_e_ref")
public class ERef {
@Id
Integer id;
@OneToMany
List<EBasic> basics;
}
@@ -0,0 +1,162 @@
package misc.migration.v1_1;
import io.ebean.Platform;
import io.ebean.annotation.DbDefault;
import io.ebean.annotation.DbMigration;
import io.ebean.annotation.EnumValue;
import io.ebean.annotation.Index;
import io.ebean.annotation.NotNull;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.sql.Timestamp;
@Entity
@Table(name = "migtest_e_basic")
public class EBasic {
public enum Status {
@EnumValue("N")
NEW,
@EnumValue("A")
ACTIVE,
@EnumValue("I")
INACTIVE,
@EnumValue("?")
DONT_KNOW,
}
public enum Progress {
@EnumValue("0")
START,
@EnumValue("1")
RUN,
@EnumValue("2")
END
}
@Id
Integer id;
@NotNull
@DbDefault("A")
Status status;
@Index(unique = true)
String name;
@DbMigration(preAlter = "-- rename all collisions")
@Column(unique = true)
String description;
@NotNull
@DbDefault("2000-01-01T00:00:00")
Timestamp someDate;
@NotNull
@DbDefault("foo'bar")
String newStringField;
@NotNull
@DbDefault("true")
@DbMigration(postAdd = "update ${table} set ${column} = old_boolean")
Boolean newBooleanField;
@NotNull
@DbDefault("true")
boolean newBooleanField2;
String indextest1;
String indextest2;
@Index
String indextest3;
@Index(unique = true)
String indextest4;
@Index(unique = true)
String indextest5;
@Index(unique = false)
String indextest6;
@NotNull
@DbDefault("0")
Progress progress;
@DbDefault("42")
int newInteger;
@NotNull
@ManyToOne
@DbMigration(preAlter= "insert into migtest_e_user (id) select distinct user_id from migtest_e_basic") // ensure all users exist
EUser user;
public EBasic() {
}
public EBasic(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Timestamp getSomeDate() {
return someDate;
}
public void setSomeDate(Timestamp someDate) {
this.someDate = someDate;
}
public String getNewStringField() {
return newStringField;
}
public void setNewStringField(String newStringField) {
this.newStringField = newStringField;
}
}
@@ -0,0 +1,26 @@
package misc.migration.v1_1;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import io.ebean.Platform;
import io.ebean.annotation.DbComment;
import io.ebean.annotation.DbMigration;
import io.ebean.annotation.History;
@Entity
@Table(name = "migtest_e_history")
@History
@DbComment("We have history now")
public class EHistory {
@Id
Integer id;
@DbComment("Column altered to long now")
@DbMigration(platforms = Platform.POSTGRES,
preAlter = "alter table ${table} alter column ${column} TYPE bigint USING (${column}::integer)")
Long testString;
}
@@ -0,0 +1,13 @@
package misc.migration.v1_1;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "migtest_e_user")
public class EUser {
@Id
Integer id;
}
@@ -0,0 +1,118 @@
package misc.migration.v1_2;
import io.ebean.annotation.DbDefault;
import io.ebean.annotation.EnumValue;
import io.ebean.annotation.Index;
import io.ebean.annotation.NotNull;
import misc.migration.v1_1.EUser;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.sql.Timestamp;
@Entity
@Table(name = "migtest_e_basic")
public class EBasic {
public enum Status {
@EnumValue("N")
NEW,
@EnumValue("A")
ACTIVE,
@EnumValue("I")
INACTIVE,
}
@Id
Integer id;
Status status;
String name;
String description;
Timestamp someDate;
boolean old_boolean;
Boolean old_boolean2;
@ManyToOne
ERef eref;
// test add & remove indices
@Index
String indextest1;
@Index(unique = true)
String indextest2;
String indextest3;
String indextest4;
@Index(unique = false)
String indextest5;
@Index(unique = true)
String indextest6;
@NotNull
@DbDefault("23")
int user_id;
public EBasic() {
}
public EBasic(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Timestamp getSomeDate() {
return someDate;
}
public void setSomeDate(Timestamp someDate) {
this.someDate = someDate;
}
}
@@ -0,0 +1,17 @@
package misc.migration.v1_2;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "migtest_e_history")
public class EHistory {
@Id
Integer id;
Long testString; // keep it as long as history prevents altering
}
@@ -0,0 +1,19 @@
package misc.migration.v1_2;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "migtest_e_ref")
public class ERef {
@Id
Integer id;
@OneToMany
List<EBasic> basics;
}
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_basic (
id integer generated by default as identity not null,
status varchar(1),
name varchar(255),
description varchar(255),
some_date timestamp,
old_boolean boolean default false not null,
old_boolean2 boolean,
eref_id integer,
indextest1 varchar(255),
indextest2 varchar(255),
indextest3 varchar(255),
indextest4 varchar(255),
indextest5 varchar(255),
indextest6 varchar(255),
user_id integer not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint pk_migtest_e_basic primary key (id)
);
-- NOT SUPPORTED alter table migtest_e_basic add constraint uq_migtest_e_basic_indextest2 unique (indextest2);
-- NOT SUPPORTED alter table migtest_e_basic add constraint uq_migtest_e_basic_indextest6 unique (indextest6);
create table migtest_e_history (
id integer generated by default as identity not null,
test_string varchar(255),
constraint pk_migtest_e_history primary key (id)
);
create table migtest_e_ref (
id integer generated by default as identity not null,
constraint pk_migtest_e_ref primary key (id)
);
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_user (
id integer generated by default as identity not null,
constraint pk_migtest_e_user primary key (id)
);
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status set default 'A';
alter table migtest_e_basic alter column status set not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
-- NOT SUPPORTED alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic alter column some_date set default '2000-01-01T00:00:00';
alter table migtest_e_basic alter column some_date set not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id) on delete restrict on update restrict;
alter table migtest_e_basic alter column user_id set null;
alter table migtest_e_basic add column new_string_field varchar(255) not null default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field boolean not null default true;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 boolean not null default true;
alter table migtest_e_basic add column progress integer not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer integer not null default 42;
comment on column migtest_e_history.test_string is 'Column altered to long now';
alter table migtest_e_history alter column test_string bigint;
comment on table migtest_e_history is 'We have history now';
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index ix_migtest_e_basic_indextest1;
drop index ix_migtest_e_basic_indextest5;
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
drop table migtest_e_ref;
@@ -0,0 +1,30 @@
-- apply changes
create table migtest_e_ref (
id integer generated by default as identity not null,
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status drop default;
alter table migtest_e_basic alter column status set null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
alter table migtest_e_basic alter column some_date drop default;
alter table migtest_e_basic alter column some_date set null;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table migtest_e_basic drop constraint fk_migtest_e_basic_user_id;
alter table migtest_e_basic alter column user_id set default 23;
alter table migtest_e_basic alter column user_id set not null;
alter table migtest_e_basic add column old_boolean boolean not null default false;
alter table migtest_e_basic add column old_boolean2 boolean;
alter table migtest_e_basic add column eref_id integer;
comment on column migtest_e_history.test_string is 'DROP COMMENT';
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index ix_migtest_e_basic_indextest3;
drop index ix_migtest_e_basic_indextest6;
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,12 @@
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
drop table migtest_e_user;
@@ -0,0 +1,8 @@
create or replace view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_basic (
id integer auto_increment not null,
status varchar(1),
name varchar(255),
description varchar(255),
some_date timestamp,
old_boolean boolean default false not null,
old_boolean2 boolean,
eref_id integer,
indextest1 varchar(255),
indextest2 varchar(255),
indextest3 varchar(255),
indextest4 varchar(255),
indextest5 varchar(255),
indextest6 varchar(255),
user_id integer not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
constraint uq_migtest_e_basic_indextest6 unique (indextest6),
constraint pk_migtest_e_basic primary key (id)
);
create table migtest_e_history (
id integer auto_increment not null,
test_string varchar(255),
constraint pk_migtest_e_history primary key (id)
);
create table migtest_e_ref (
id integer auto_increment not null,
constraint pk_migtest_e_ref primary key (id)
);
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,50 @@
-- apply changes
create table migtest_e_user (
id integer auto_increment not null,
constraint pk_migtest_e_user primary key (id)
);
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status set default 'A';
alter table migtest_e_basic alter column status set not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic alter column some_date set default '2000-01-01T00:00:00';
alter table migtest_e_basic alter column some_date set not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id) on delete restrict on update restrict;
alter table migtest_e_basic alter column user_id set null;
alter table migtest_e_basic add column new_string_field varchar(255) not null default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field boolean not null default true;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 boolean not null default true;
alter table migtest_e_basic add column progress integer not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer integer not null default 42;
comment on column migtest_e_history.test_string is 'Column altered to long now';
alter table migtest_e_history alter column test_string bigint;
comment on table migtest_e_history is 'We have history now';
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index if exists ix_migtest_e_basic_indextest1;
drop index if exists ix_migtest_e_basic_indextest5;
alter table migtest_e_history add column sys_period_start datetime(6) default now(6);
alter table migtest_e_history add column sys_period_end datetime(6);
create table migtest_e_history_history(
id integer,
test_string bigint,
sys_period_start datetime(6),
sys_period_end datetime(6)
);
create view migtest_e_history_with_history as select * from migtest_e_history union all select * from migtest_e_history_history;
create trigger migtest_e_history_history_upd before update,delete on migtest_e_history for each row call "io.ebean.config.dbplatform.h2.H2HistoryTrigger";
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
drop table if exists migtest_e_ref;
@@ -0,0 +1,30 @@
-- apply changes
create table migtest_e_ref (
id integer auto_increment not null,
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status drop default;
alter table migtest_e_basic alter column status set null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
alter table migtest_e_basic alter column some_date drop default;
alter table migtest_e_basic alter column some_date set null;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table migtest_e_basic drop constraint if exists fk_migtest_e_basic_user_id;
alter table migtest_e_basic alter column user_id set default 23;
alter table migtest_e_basic alter column user_id set not null;
alter table migtest_e_basic add column old_boolean boolean not null default false;
alter table migtest_e_basic add column old_boolean2 boolean;
alter table migtest_e_basic add column eref_id integer;
comment on column migtest_e_history.test_string is 'DROP COMMENT';
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index if exists ix_migtest_e_basic_indextest3;
drop index if exists ix_migtest_e_basic_indextest6;
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,20 @@
-- drop dependencies
drop trigger migtest_e_history_history_upd;
drop view migtest_e_history_with_history;
alter table migtest_e_history drop column sys_period_start;
alter table migtest_e_history drop column sys_period_end;
drop table migtest_e_history_history;
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
drop table if exists migtest_e_user;
@@ -0,0 +1,3 @@
-- h2 and postgres script
@@ -0,0 +1,8 @@
create or replace view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_basic (
id integer generated by default as identity (start with 1) not null,
status varchar(1),
name varchar(255),
description varchar(255),
some_date timestamp,
old_boolean boolean default false not null,
old_boolean2 boolean,
eref_id integer,
indextest1 varchar(255),
indextest2 varchar(255),
indextest3 varchar(255),
indextest4 varchar(255),
indextest5 varchar(255),
indextest6 varchar(255),
user_id integer not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
constraint uq_migtest_e_basic_indextest6 unique (indextest6),
constraint pk_migtest_e_basic primary key (id)
);
create table migtest_e_history (
id integer generated by default as identity (start with 1) not null,
test_string varchar(255),
constraint pk_migtest_e_history primary key (id)
);
create table migtest_e_ref (
id integer generated by default as identity (start with 1) not null,
constraint pk_migtest_e_ref primary key (id)
);
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_user (
id integer generated by default as identity (start with 1) not null,
constraint pk_migtest_e_user primary key (id)
);
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status set default 'A';
alter table migtest_e_basic alter column status set not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic alter column some_date set default '2000-01-01T00:00:00';
alter table migtest_e_basic alter column some_date set not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id) on delete restrict on update restrict;
alter table migtest_e_basic alter column user_id set null;
alter table migtest_e_basic add column new_string_field varchar(255) not null default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field boolean not null default true;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 boolean not null default true;
alter table migtest_e_basic add column progress integer not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer integer not null default 42;
comment on column migtest_e_history.test_string is 'Column altered to long now';
alter table migtest_e_history alter column test_string bigint;
comment on table migtest_e_history is 'We have history now';
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index if exists ix_migtest_e_basic_indextest1;
drop index if exists ix_migtest_e_basic_indextest5;
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
drop table if exists migtest_e_ref;
@@ -0,0 +1,30 @@
-- apply changes
create table migtest_e_ref (
id integer generated by default as identity (start with 1) not null,
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status drop default;
alter table migtest_e_basic alter column status set null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
alter table migtest_e_basic alter column some_date drop default;
alter table migtest_e_basic alter column some_date set null;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table migtest_e_basic drop constraint if exists fk_migtest_e_basic_user_id;
alter table migtest_e_basic alter column user_id set default 23;
alter table migtest_e_basic alter column user_id set not null;
alter table migtest_e_basic add column old_boolean boolean not null default false;
alter table migtest_e_basic add column old_boolean2 boolean;
alter table migtest_e_basic add column eref_id integer;
comment on column migtest_e_history.test_string is 'DROP COMMENT';
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index if exists ix_migtest_e_basic_indextest3;
drop index if exists ix_migtest_e_basic_indextest6;
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,12 @@
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
drop table if exists migtest_e_user;
@@ -0,0 +1,8 @@
drop view order_agg_vw if exists ;
create view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE xml>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<createTable name="migtest_e_basic" pkName="pk_migtest_e_basic">
<column name="id" type="integer" primaryKey="true"/>
<column name="status" type="varchar(1)" checkConstraint="check ( status in ('N','A','I'))" checkConstraintName="ck_migtest_e_basic_status"/>
<column name="name" type="varchar"/>
<column name="description" type="varchar"/>
<column name="some_date" type="timestamp"/>
<column name="old_boolean" type="boolean" defaultValue="false" notnull="true"/>
<column name="old_boolean2" type="boolean"/>
<column name="eref_id" type="integer" references="migtest_e_ref.id" foreignKeyName="fk_migtest_e_basic_eref_id" foreignKeyIndex="ix_migtest_e_basic_eref_id"/>
<column name="indextest1" type="varchar"/>
<column name="indextest2" type="varchar"/>
<column name="indextest3" type="varchar"/>
<column name="indextest4" type="varchar"/>
<column name="indextest5" type="varchar"/>
<column name="indextest6" type="varchar"/>
<column name="user_id" type="integer" notnull="true"/>
<uniqueConstraint name="uq_migtest_e_basic_indextest2" columnNames="indextest2"/>
<uniqueConstraint name="uq_migtest_e_basic_indextest6" columnNames="indextest6"/>
</createTable>
<createTable name="migtest_e_history" pkName="pk_migtest_e_history">
<column name="id" type="integer" primaryKey="true"/>
<column name="test_string" type="varchar"/>
</createTable>
<createTable name="migtest_e_ref" pkName="pk_migtest_e_ref">
<column name="id" type="integer" primaryKey="true"/>
</createTable>
<createIndex indexName="ix_migtest_e_basic_indextest1" tableName="migtest_e_basic" columns="indextest1"/>
<createIndex indexName="ix_migtest_e_basic_indextest5" tableName="migtest_e_basic" columns="indextest5"/>
</changeSet>
</migration>
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE xml>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<alterColumn columnName="status" tableName="migtest_e_basic" currentType="varchar(1)" defaultValue="'A'" notnull="true" currentNotnull="false" checkConstraint="check ( status in ('N','A','I','?'))" checkConstraintName="ck_migtest_e_basic_status"/>
<alterColumn columnName="description" tableName="migtest_e_basic" unique="uq_migtest_e_basic_description">
<before>-- rename all collisions</before>
</alterColumn>
<alterColumn columnName="some_date" tableName="migtest_e_basic" currentType="timestamp" defaultValue="'2000-01-01T00:00:00'" notnull="true" currentNotnull="false"/>
<alterColumn columnName="user_id" tableName="migtest_e_basic" currentType="integer" notnull="false" currentNotnull="true" references="migtest_e_user.id" foreignKeyName="fk_migtest_e_basic_user_id" foreignKeyIndex="ix_migtest_e_basic_user_id">
<before>insert into migtest_e_user (id) select distinct user_id from migtest_e_basic</before>
</alterColumn>
<addColumn tableName="migtest_e_basic">
<column name="new_string_field" type="varchar" defaultValue="'foo''bar'" notnull="true"/>
<column name="new_boolean_field" type="boolean" defaultValue="true" notnull="true">
<after>update ${table} set ${column} = old_boolean</after>
</column>
<column name="new_boolean_field2" type="boolean" defaultValue="true" notnull="true"/>
<column name="progress" type="integer" defaultValue="0" notnull="true" checkConstraint="check ( progress in (0,1,2))" checkConstraintName="ck_migtest_e_basic_progress"/>
<column name="new_integer" type="integer" defaultValue="42" notnull="true"/>
</addColumn>
<addHistoryTable baseTable="migtest_e_history"/>
<alterColumn columnName="test_string" tableName="migtest_e_history" type="bigint" currentType="varchar" currentNotnull="false" comment="Column altered to long now">
<before platforms="postgres">alter table ${table} alter column ${column} TYPE bigint USING (${column}::integer)</before>
</alterColumn>
<addTableComment name="migtest_e_history" comment="We have history now"/>
<createTable name="migtest_e_user" pkName="pk_migtest_e_user">
<column name="id" type="integer" primaryKey="true"/>
</createTable>
<createIndex indexName="ix_migtest_e_basic_indextest3" tableName="migtest_e_basic" columns="indextest3"/>
<createIndex indexName="ix_migtest_e_basic_indextest6" tableName="migtest_e_basic" columns="indextest6"/>
<dropIndex indexName="ix_migtest_e_basic_indextest1" tableName="migtest_e_basic"/>
<dropIndex indexName="ix_migtest_e_basic_indextest5" tableName="migtest_e_basic"/>
</changeSet>
<changeSet type="pendingDrops">
<dropColumn columnName="old_boolean" tableName="migtest_e_basic"/>
<dropColumn columnName="old_boolean2" tableName="migtest_e_basic"/>
<dropColumn columnName="eref_id" tableName="migtest_e_basic"/>
<dropTable name="migtest_e_ref"/>
</changeSet>
</migration>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE xml>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply" dropsFor="1.1">
<dropColumn columnName="old_boolean" tableName="migtest_e_basic"/>
<dropColumn columnName="old_boolean2" tableName="migtest_e_basic"/>
<dropColumn columnName="eref_id" tableName="migtest_e_basic"/>
<dropTable name="migtest_e_ref"/>
</changeSet>
</migration>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE xml>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<alterColumn columnName="status" tableName="migtest_e_basic" currentType="varchar(1)" defaultValue="DROP DEFAULT" notnull="false" currentNotnull="true" checkConstraint="check ( status in ('N','A','I'))" checkConstraintName="ck_migtest_e_basic_status"/>
<alterColumn columnName="description" tableName="migtest_e_basic" dropUnique="uq_migtest_e_basic_description"/>
<alterColumn columnName="some_date" tableName="migtest_e_basic" currentType="timestamp" defaultValue="DROP DEFAULT" notnull="false" currentNotnull="true"/>
<alterColumn columnName="user_id" tableName="migtest_e_basic" currentType="integer" defaultValue="23" notnull="true" currentNotnull="false" dropForeignKey="fk_migtest_e_basic_user_id" dropForeignKeyIndex="ix_migtest_e_basic_user_id"/>
<addColumn tableName="migtest_e_basic">
<column name="old_boolean" type="boolean" defaultValue="false" notnull="true"/>
<column name="old_boolean2" type="boolean"/>
<column name="eref_id" type="integer" references="migtest_e_ref.id" foreignKeyName="fk_migtest_e_basic_eref_id" foreignKeyIndex="ix_migtest_e_basic_eref_id"/>
</addColumn>
<alterColumn columnName="test_string" tableName="migtest_e_history" withHistory="true" comment="DROP COMMENT"/>
<addTableComment name="migtest_e_history"/>
<createTable name="migtest_e_ref" pkName="pk_migtest_e_ref">
<column name="id" type="integer" primaryKey="true"/>
</createTable>
<createIndex indexName="ix_migtest_e_basic_indextest1" tableName="migtest_e_basic" columns="indextest1"/>
<createIndex indexName="ix_migtest_e_basic_indextest5" tableName="migtest_e_basic" columns="indextest5"/>
<dropIndex indexName="ix_migtest_e_basic_indextest3" tableName="migtest_e_basic"/>
<dropIndex indexName="ix_migtest_e_basic_indextest6" tableName="migtest_e_basic"/>
</changeSet>
<changeSet type="pendingDrops">
<dropColumn columnName="new_string_field" tableName="migtest_e_basic"/>
<dropColumn columnName="new_boolean_field" tableName="migtest_e_basic"/>
<dropColumn columnName="new_boolean_field2" tableName="migtest_e_basic"/>
<dropColumn columnName="progress" tableName="migtest_e_basic"/>
<dropColumn columnName="new_integer" tableName="migtest_e_basic"/>
<dropHistoryTable baseTable="migtest_e_history"/>
<dropTable name="migtest_e_user"/>
</changeSet>
</migration>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE xml>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply" dropsFor="1.3">
<dropColumn columnName="new_string_field" tableName="migtest_e_basic"/>
<dropColumn columnName="new_boolean_field" tableName="migtest_e_basic"/>
<dropColumn columnName="new_boolean_field2" tableName="migtest_e_basic"/>
<dropColumn columnName="progress" tableName="migtest_e_basic"/>
<dropColumn columnName="new_integer" tableName="migtest_e_basic"/>
<dropHistoryTable baseTable="migtest_e_history"/>
<dropTable name="migtest_e_user"/>
</changeSet>
</migration>
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_basic (
id integer auto_increment not null,
status varchar(1),
name varchar(255),
description varchar(255),
some_date datetime(6),
old_boolean tinyint(1) default 0 not null,
old_boolean2 tinyint(1) default 0,
eref_id integer,
indextest1 varchar(255),
indextest2 varchar(255),
indextest3 varchar(255),
indextest4 varchar(255),
indextest5 varchar(255),
indextest6 varchar(255),
user_id integer not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
constraint uq_migtest_e_basic_indextest6 unique (indextest6),
constraint pk_migtest_e_basic primary key (id)
);
create table migtest_e_history (
id integer auto_increment not null,
test_string varchar(255),
constraint pk_migtest_e_history primary key (id)
);
create table migtest_e_ref (
id integer auto_increment not null,
constraint pk_migtest_e_ref primary key (id)
);
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,57 @@
-- apply changes
create table migtest_e_user (
id integer auto_increment not null,
constraint pk_migtest_e_user primary key (id)
);
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic alter status set default 'A';
alter table migtest_e_basic modify status varchar(1) not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic alter some_date set default '2000-01-01T00:00:00';
alter table migtest_e_basic modify some_date datetime(6) not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id) on delete restrict on update restrict;
alter table migtest_e_basic modify user_id integer;
alter table migtest_e_basic add column new_string_field varchar(255) not null default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field tinyint(1) default 0 not null;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 tinyint(1) default 0 not null;
alter table migtest_e_basic add column progress integer not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer integer not null default 42;
comment on column migtest_e_history.test_string is 'Column altered to long now';
alter table migtest_e_history modify test_string bigint;
alter table migtest_e_history comment = 'We have history now';
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index ix_migtest_e_basic_indextest1 on migtest_e_basic;
drop index ix_migtest_e_basic_indextest5 on migtest_e_basic;
alter table migtest_e_history add column sys_period_start datetime(6) default now(6);
alter table migtest_e_history add column sys_period_end datetime(6);
create table migtest_e_history_history(
id integer,
test_string bigint,
sys_period_start datetime(6),
sys_period_end datetime(6)
);
create view migtest_e_history_with_history as select * from migtest_e_history union all select * from migtest_e_history_history;
delimiter $$
create trigger migtest_e_history_history_upd before update on migtest_e_history for each row begin
insert into migtest_e_history_history (sys_period_start,sys_period_end,id, test_string) values (OLD.sys_period_start, now(6),OLD.id, OLD.test_string);
set NEW.sys_period_start = now(6);
end$$
delimiter $$
create trigger migtest_e_history_history_del before delete on migtest_e_history for each row begin
insert into migtest_e_history_history (sys_period_start,sys_period_end,id, test_string) values (OLD.sys_period_start, now(6),OLD.id, OLD.test_string);
end$$
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
drop table if exists migtest_e_ref;
@@ -0,0 +1,27 @@
-- apply changes
create table migtest_e_ref (
id integer auto_increment not null,
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_basic alter status drop default;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop index uq_migtest_e_basic_description;
alter table migtest_e_basic alter some_date drop default;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table migtest_e_basic drop foreign key fk_migtest_e_basic_user_id;
alter table migtest_e_basic alter user_id set default 23;
alter table migtest_e_basic modify user_id integer not null;
alter table migtest_e_basic add column old_boolean tinyint(1) default 0 not null;
alter table migtest_e_basic add column old_boolean2 tinyint(1) default 0;
alter table migtest_e_basic add column eref_id integer;
comment on column migtest_e_history.test_string is 'DROP COMMENT';
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index ix_migtest_e_basic_indextest3 on migtest_e_basic;
drop index ix_migtest_e_basic_indextest6 on migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,21 @@
-- drop dependencies
drop trigger migtest_e_history_history_upd;
drop trigger migtest_e_history_history_del;
drop view migtest_e_history_with_history;
alter table migtest_e_history drop column sys_period_start;
alter table migtest_e_history drop column sys_period_end;
drop table migtest_e_history_history;
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
drop table if exists migtest_e_user;
@@ -0,0 +1,8 @@
create or replace view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
@@ -0,0 +1,42 @@
-- apply changes
create table migtest_e_basic (
id number(10) not null,
status varchar2(1),
name varchar2(255),
description varchar2(255),
some_date timestamp,
old_boolean number(1) default 0 not null,
old_boolean2 number(1) default 0,
eref_id number(10),
indextest1 varchar2(255),
indextest2 varchar2(255),
indextest3 varchar2(255),
indextest4 varchar2(255),
indextest5 varchar2(255),
indextest6 varchar2(255),
user_id number(10) not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
constraint uq_migtest_e_basic_indextest6 unique (indextest6),
constraint pk_migtest_e_basic primary key (id)
);
create sequence migtest_e_basic_seq;
create table migtest_e_history (
id number(10) not null,
test_string varchar2(255),
constraint pk_migtest_e_history primary key (id)
);
create sequence migtest_e_history_seq;
create table migtest_e_ref (
id number(10) not null,
constraint pk_migtest_e_ref primary key (id)
);
create sequence migtest_e_ref_seq;
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id);
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,40 @@
-- apply changes
create table migtest_e_user (
id number(10) not null,
constraint pk_migtest_e_user primary key (id)
);
create sequence migtest_e_user_seq;
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic modify status default 'A';
alter table migtest_e_basic modify status not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic modify some_date default '2000-01-01T00:00:00';
alter table migtest_e_basic modify some_date not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id);
alter table migtest_e_basic modify user_id null;
alter table migtest_e_basic add column new_string_field varchar2(255) not null default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field number(1) default 0 not null;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 number(1) default 0 not null;
alter table migtest_e_basic add column progress number(10) not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer number(10) not null default 42;
comment on column migtest_e_history.test_string is 'Column altered to long now';
alter table migtest_e_history modify test_string number(19);
comment on table migtest_e_history is 'We have history now';
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index ix_migtest_e_basic_indextest1;
drop index ix_migtest_e_basic_indextest5;
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
drop table migtest_e_ref cascade constraints purge;
@@ -0,0 +1,31 @@
-- apply changes
create table migtest_e_ref (
id number(10) not null,
constraint pk_migtest_e_ref primary key (id)
);
create sequence migtest_e_ref_seq;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic modify status drop default;
alter table migtest_e_basic modify status null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
alter table migtest_e_basic modify some_date drop default;
alter table migtest_e_basic modify some_date null;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table migtest_e_basic drop constraint fk_migtest_e_basic_user_id;
alter table migtest_e_basic modify user_id default 23;
alter table migtest_e_basic modify user_id not null;
alter table migtest_e_basic add column old_boolean number(1) default 0 not null;
alter table migtest_e_basic add column old_boolean2 number(1) default 0;
alter table migtest_e_basic add column eref_id number(10);
comment on column migtest_e_history.test_string is 'DROP COMMENT';
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index ix_migtest_e_basic_indextest3;
drop index ix_migtest_e_basic_indextest6;
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id);
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,12 @@
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
drop table migtest_e_user cascade constraints purge;
@@ -0,0 +1,3 @@
-- oracle only script
@@ -0,0 +1,8 @@
create or replace view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_basic (
id serial not null,
status varchar(1),
name varchar(255),
description varchar(255),
some_date timestamptz,
old_boolean boolean default false not null,
old_boolean2 boolean,
eref_id integer,
indextest1 varchar(255),
indextest2 varchar(255),
indextest3 varchar(255),
indextest4 varchar(255),
indextest5 varchar(255),
indextest6 varchar(255),
user_id integer not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
constraint uq_migtest_e_basic_indextest6 unique (indextest6),
constraint pk_migtest_e_basic primary key (id)
);
create table migtest_e_history (
id serial not null,
test_string varchar(255),
constraint pk_migtest_e_history primary key (id)
);
create table migtest_e_ref (
id serial not null,
constraint pk_migtest_e_ref primary key (id)
);
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,62 @@
-- apply changes
create table migtest_e_user (
id serial not null,
constraint pk_migtest_e_user primary key (id)
);
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status set default 'A';
alter table migtest_e_basic alter column status set not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic alter column some_date set default '2000-01-01T00:00:00';
alter table migtest_e_basic alter column some_date set not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id) on delete restrict on update restrict;
alter table migtest_e_basic alter column user_id drop not null;
alter table migtest_e_basic add column new_string_field varchar(255) not null default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field boolean not null default true;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 boolean not null default true;
alter table migtest_e_basic add column progress integer not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer integer not null default 42;
alter table migtest_e_history alter column test_string TYPE bigint USING (test_string::integer);
comment on column migtest_e_history.test_string is 'Column altered to long now';
alter table migtest_e_history alter column test_string type bigint;
comment on table migtest_e_history is 'We have history now';
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index if exists ix_migtest_e_basic_indextest1;
drop index if exists ix_migtest_e_basic_indextest5;
alter table migtest_e_history add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
create table migtest_e_history_history(like migtest_e_history);
create view migtest_e_history_with_history as select * from migtest_e_history union all select * from migtest_e_history_history;
create or replace function migtest_e_history_history_version() returns trigger as $$
begin
if (TG_OP = 'UPDATE') then
insert into migtest_e_history_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
NEW.sys_period = tstzrange(current_timestamp,null);
return new;
elsif (TG_OP = 'DELETE') then
insert into migtest_e_history_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
return old;
end if;
end;
$$ LANGUAGE plpgsql;
create trigger migtest_e_history_history_upd
before update or delete on migtest_e_history
for each row execute procedure migtest_e_history_history_version();
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
drop table if exists migtest_e_ref cascade;
@@ -0,0 +1,30 @@
-- apply changes
create table migtest_e_ref (
id serial not null,
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status drop default;
alter table migtest_e_basic alter column status drop not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
alter table migtest_e_basic alter column some_date drop default;
alter table migtest_e_basic alter column some_date drop not null;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table if exists migtest_e_basic drop constraint if exists fk_migtest_e_basic_user_id;
alter table migtest_e_basic alter column user_id set default 23;
alter table migtest_e_basic alter column user_id set not null;
alter table migtest_e_basic add column old_boolean boolean not null default false;
alter table migtest_e_basic add column old_boolean2 boolean;
alter table migtest_e_basic add column eref_id integer;
comment on column migtest_e_history.test_string is 'DROP COMMENT';
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index if exists ix_migtest_e_basic_indextest3;
drop index if exists ix_migtest_e_basic_indextest6;
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,21 @@
-- drop dependencies
drop trigger if exists migtest_e_history_history_upd on migtest_e_history cascade;
drop function if exists migtest_e_history_history_version();
drop view migtest_e_history_with_history;
alter table migtest_e_history drop column sys_period;
drop table migtest_e_history_history;
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
drop table if exists migtest_e_user cascade;
@@ -0,0 +1,3 @@
-- h2 and postgres script
@@ -0,0 +1,8 @@
create or replace view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
@@ -0,0 +1,4 @@
-- postgres specific indexes
create index ix_ebasic_jmjb_gin2 on ebasic_json_map_json_b using gin(content jsonb_path_ops);
@@ -0,0 +1,37 @@
-- apply changes
create table migtest_e_basic (
id integer not null,
status varchar(1),
name varchar(255),
description varchar(255),
some_date timestamp,
old_boolean int default 0 not null,
old_boolean2 int default 0,
eref_id integer,
indextest1 varchar(255),
indextest2 varchar(255),
indextest3 varchar(255),
indextest4 varchar(255),
indextest5 varchar(255),
indextest6 varchar(255),
user_id integer not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
constraint uq_migtest_e_basic_indextest6 unique (indextest6),
constraint pk_migtest_e_basic primary key (id),
foreign key (eref_id) references migtest_e_ref (id) on delete restrict on update restrict
);
create table migtest_e_history (
id integer not null,
test_string varchar(255),
constraint pk_migtest_e_history primary key (id)
);
create table migtest_e_ref (
id integer not null,
constraint pk_migtest_e_ref primary key (id)
);
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
@@ -0,0 +1,36 @@
-- apply changes
create table migtest_e_user (
id integer not null,
constraint pk_migtest_e_user primary key (id)
);
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status set default 'A';
alter table migtest_e_basic alter column status set not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic alter column some_date set default '2000-01-01T00:00:00';
alter table migtest_e_basic alter column some_date set not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic alter column user_id set null;
alter table migtest_e_basic add column new_string_field varchar(255) not null default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field int default 0 not null;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 int default 0 not null;
alter table migtest_e_basic add column progress integer not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer integer not null default 42;
alter table migtest_e_history alter column test_string integer;
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index if exists ix_migtest_e_basic_indextest1;
drop index if exists ix_migtest_e_basic_indextest5;
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
drop table if exists migtest_e_ref;
@@ -0,0 +1,28 @@
-- apply changes
create table migtest_e_ref (
id integer not null,
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic alter column status drop default;
alter table migtest_e_basic alter column status set null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
alter table migtest_e_basic alter column some_date drop default;
alter table migtest_e_basic alter column some_date set null;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table migtest_e_basic drop constraint if exists fk_migtest_e_basic_user_id;
alter table migtest_e_basic alter column user_id set default 23;
alter table migtest_e_basic alter column user_id set not null;
alter table migtest_e_basic add column old_boolean int default 0 not null;
alter table migtest_e_basic add column old_boolean2 int default 0;
alter table migtest_e_basic add column eref_id integer;
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index if exists ix_migtest_e_basic_indextest3;
drop index if exists ix_migtest_e_basic_indextest6;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,12 @@
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
drop table if exists migtest_e_user;
@@ -0,0 +1,9 @@
drop view if exists order_agg_vw;
create view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
@@ -0,0 +1,39 @@
-- apply changes
create table migtest_e_basic (
id integer identity(1,1) not null,
status varchar(1),
name varchar(255),
description varchar(255),
some_date datetime2,
old_boolean bit default 0 not null,
old_boolean2 bit default 0,
eref_id integer,
indextest1 varchar(255),
indextest2 varchar(255),
indextest3 varchar(255),
indextest4 varchar(255),
indextest5 varchar(255),
indextest6 varchar(255),
user_id integer not null,
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
constraint pk_migtest_e_basic primary key (id)
);
create unique nonclustered index uq_migtest_e_basic_indextest2 on migtest_e_basic(indextest2) where indextest2 is not null;
create unique nonclustered index uq_migtest_e_basic_indextest6 on migtest_e_basic(indextest6) where indextest6 is not null;
create table migtest_e_history (
id integer identity(1,1) not null,
test_string varchar(255),
constraint pk_migtest_e_history primary key (id)
);
create table migtest_e_ref (
id integer identity(1,1) not null,
constraint pk_migtest_e_ref primary key (id)
);
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id);
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,42 @@
-- apply changes
create table migtest_e_user (
id integer identity(1,1) not null,
constraint pk_migtest_e_user primary key (id)
);
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic add constraint df_migtest_e_basic_status default 'A' for status;
alter table migtest_e_basic alter column status varchar(1) not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
-- rename all collisions;
create unique nonclustered index uq_migtest_e_basic_description on migtest_e_basic(description) where description is not null;
update migtest_e_basic set some_date = '2000-01-01T00:00:00' where some_date is null;
alter table migtest_e_basic add constraint df_migtest_e_basic_some_date default '2000-01-01T00:00:00' for some_date;
alter table migtest_e_basic alter column some_date datetime2 not null;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id);
alter table migtest_e_basic alter column user_id integer;
alter table migtest_e_basic add new_string_field varchar(255) not null default 'foo''bar';
alter table migtest_e_basic add new_boolean_field bit default 0 not null;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add new_boolean_field2 bit default 0 not null;
alter table migtest_e_basic add progress integer not null default 0;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add new_integer integer not null default 42;
alter table migtest_e_history alter column test_string numeric(19);
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
IF EXISTS (SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('migtest_e_basic','U') AND name = 'ix_migtest_e_basic_indextest1') drop index ix_migtest_e_basic_indextest1 ON migtest_e_basic;
IF EXISTS (SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('migtest_e_basic','U') AND name = 'ix_migtest_e_basic_indextest5') drop index ix_migtest_e_basic_indextest5 ON migtest_e_basic;
alter table migtest_e_history
add sys_periodFrom datetime2 GENERATED ALWAYS AS ROW START NOT NULL DEFAULT SYSUTCDATETIME(),
sys_periodTo datetime2 GENERATED ALWAYS AS ROW END NOT NULL DEFAULT '9999-12-31T23:59:59.9999999',
period for system_time (sys_periodFrom, sys_periodTo);
alter table migtest_e_history set (system_versioning = on (history_table=dbo.migtest_e_history_history));
@@ -0,0 +1,8 @@
-- apply changes
alter table migtest_e_basic drop column old_boolean;
alter table migtest_e_basic drop column old_boolean2;
alter table migtest_e_basic drop column eref_id;
IF OBJECT_ID('migtest_e_ref', 'U') IS NOT NULL drop table migtest_e_ref;
@@ -0,0 +1,27 @@
-- apply changes
create table migtest_e_ref (
id integer identity(1,1) not null,
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
alter table migtest_e_basic drop constraint df_migtest_e_basic_status;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
alter table migtest_e_basic drop constraint df_migtest_e_basic_some_date;
update migtest_e_basic set user_id = 23 where user_id is null;
IF OBJECT_ID('fk_migtest_e_basic_user_id', 'F') IS NOT NULL alter table migtest_e_basic drop constraint fk_migtest_e_basic_user_id;
alter table migtest_e_basic add constraint df_migtest_e_basic_user_id default 23 for user_id;
alter table migtest_e_basic alter column user_id integer not null;
alter table migtest_e_basic add old_boolean bit default 0 not null;
alter table migtest_e_basic add old_boolean2 bit default 0;
alter table migtest_e_basic add eref_id integer;
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
IF EXISTS (SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('migtest_e_basic','U') AND name = 'ix_migtest_e_basic_indextest3') drop index ix_migtest_e_basic_indextest3 ON migtest_e_basic;
IF EXISTS (SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('migtest_e_basic','U') AND name = 'ix_migtest_e_basic_indextest6') drop index ix_migtest_e_basic_indextest6 ON migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id);
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
@@ -0,0 +1,15 @@
-- apply changes
alter table migtest_e_basic drop column new_string_field;
alter table migtest_e_basic drop column new_boolean_field;
alter table migtest_e_basic drop column new_boolean_field2;
alter table migtest_e_basic drop column progress;
alter table migtest_e_basic drop column new_integer;
IF OBJECT_ID('migtest_e_user', 'U') IS NOT NULL drop table migtest_e_user;
alter table migtest_e_history set (system_versioning = off);
alter table migtest_e_history drop column sys_periodFrom;
alter table migtest_e_history drop column sys_periodTo;
@@ -0,0 +1,10 @@
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'order_agg_vw')
DROP VIEW order_agg_vw;
create view order_agg_vw as
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
sum(d.ship_qty * d.unit_price) as ship_total
from o_order_detail d
group by d.order_id;
+1 -1
View File
@@ -1,4 +1,4 @@
entity-packages: org
entity-packages: org,misc
transactional-packages: org
querybean-packages: none
+13
View File
@@ -17,6 +17,7 @@ ebean.encryptKeyManager=org.tests.basic.encrypt.BasicEncyptKeyManager
ebean.ddl.generate=true
ebean.ddl.run=true
ebean.packages=org.tests
datasource.default=h2
#ebean.persistBatch=NONE
@@ -133,3 +134,15 @@ datasource.db2.username=db2admin
datasource.db2.password=veryverysecret#1234
datasource.db2.databaseUrl=jdbc:db2://127.0.0.1:50000/SAMPLE
datasource.db2.databaseDriver=com.ibm.db2.jcc.DB2Driver
# parameters for migration test
datasource.migrationtest.username=SA
datasource.migrationtest.password=SA
datasource.migrationtest.databaseUrl=jdbc:h2:mem:migration
datasource.migrationtest.databaseDriver=org.h2.Driver
ebean.migrationtest.applyPrefix=V
ebean.migrationtest.ddl.generate=false
ebean.migrationtest.ddl.run=false
ebean.migrationtest.migration.appName=migrationtest
ebean.migrationtest.migration.migrationPath=dbmigration/migrationtest
ebean.migrationtest.migration.strict=true