mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
DB migration initial
This commit is contained in:
@@ -7,6 +7,7 @@ import javax.sql.DataSource;
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.Query;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -145,6 +146,8 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected boolean disallowBatchOnCascade;
|
||||
|
||||
protected PlatformDdl platformDdl;
|
||||
|
||||
/**
|
||||
* Instantiates a new database platform.
|
||||
*/
|
||||
@@ -164,6 +167,10 @@ public class DatabasePlatform {
|
||||
return name;
|
||||
}
|
||||
|
||||
public PlatformDdl getPlatformDdl() {
|
||||
return platformDdl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the JDBC driver does not allow additional queries to execute
|
||||
* when a resultSet is being 'streamed' as is the case with findEach() etc.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.H2Ddl;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@@ -12,6 +13,7 @@ public class H2Platform extends DatabasePlatform {
|
||||
public H2Platform() {
|
||||
super();
|
||||
this.name = "h2";
|
||||
this.platformDdl = new H2Ddl(this.dbTypeMap);
|
||||
this.dbEncrypt = new H2DbEncrypt();
|
||||
// like ? escape'' not working in the latest version H2 so just using no
|
||||
// escape clause for now noting that backslash is an escape char for like in H2
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.H2Ddl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PostgresDdl;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Types;
|
||||
@@ -16,6 +18,8 @@ public class PostgresPlatform extends DatabasePlatform {
|
||||
public PostgresPlatform() {
|
||||
super();
|
||||
this.name = "postgres";
|
||||
this.platformDdl = new PostgresDdl(this.dbTypeMap);
|
||||
|
||||
// OnQueryOnly.CLOSE as a performance optimisation on Postgres
|
||||
this.onQueryOnly = OnQueryOnly.CLOSE;
|
||||
this.likeClause = "like ? escape''";
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.BaseColumnDdl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.BaseTableDdl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.DdlNamingConvention;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class BaseDdlHandler implements DdlHandler {
|
||||
|
||||
protected final ColumnDdl columnDdl;
|
||||
|
||||
protected final TableDdl tableDdl;
|
||||
|
||||
public BaseDdlHandler(DdlNamingConvention namingConvention, PlatformDdl platformDdl) {
|
||||
this.tableDdl = new BaseTableDdl(namingConvention, platformDdl);
|
||||
this.columnDdl = new BaseColumnDdl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, ChangeSet changeSet) throws IOException {
|
||||
|
||||
List<Object> changeSetChildren = changeSet.getChangeSetChildren();
|
||||
for (Object change : changeSetChildren) {
|
||||
if (change instanceof CreateTable) {
|
||||
generate(writer, (CreateTable) change);
|
||||
} else if (change instanceof AddColumn) {
|
||||
generate(writer, (AddColumn) change);
|
||||
} else if (change instanceof DropColumn) {
|
||||
generate(writer, (DropColumn) change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateTable createTable) throws IOException {
|
||||
tableDdl.generate(writer, createTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
columnDdl.generate(writer, addColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
columnDdl.generate(writer, dropColumn);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Write AddColumn or DropColumn.
|
||||
*/
|
||||
public interface ColumnDdl {
|
||||
|
||||
/**
|
||||
* Write a AddColumn change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a DropColumn change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration;
|
||||
|
||||
import com.avaje.ebean.dbmigration.model.MConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Buffer to append generated DDL to.
|
||||
*/
|
||||
public interface DdlBuffer {
|
||||
|
||||
/**
|
||||
* Return the configuration (default tablespaces etc).
|
||||
*/
|
||||
MConfiguration getConfiguration();
|
||||
|
||||
/**
|
||||
* Append DDL content to the buffer.
|
||||
*/
|
||||
DdlBuffer append(String content) throws IOException;
|
||||
|
||||
/**
|
||||
* Append DDL content to the buffer with space padding.
|
||||
*/
|
||||
DdlBuffer append(String type, int space) throws IOException;
|
||||
|
||||
/**
|
||||
* Append a value that is potentially null or empty and proceed it with a space if so.
|
||||
*/
|
||||
DdlBuffer appendWithSpace(String foreignKeyRestrict) throws IOException;
|
||||
|
||||
/**
|
||||
* Append new line character to the buffer.
|
||||
*/
|
||||
DdlBuffer newLine() throws IOException;
|
||||
|
||||
/**
|
||||
* Append the end of statement content.
|
||||
*/
|
||||
DdlBuffer endOfStatement() throws IOException;
|
||||
|
||||
/**
|
||||
* End of a change - add some whitespace.
|
||||
*/
|
||||
DdlBuffer end() throws IOException;
|
||||
|
||||
/**
|
||||
* Return the buffer content.
|
||||
*/
|
||||
String getBuffer();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*/
|
||||
public interface DdlHandler {
|
||||
|
||||
void generate(DdlWrite writer, ChangeSet changeSet) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, CreateTable createTable) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.BaseDdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.model.MConfiguration;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.ModelContainer;
|
||||
|
||||
/**
|
||||
* Write context holding the buffers for both apply and rollback DDL.
|
||||
*/
|
||||
public class DdlWrite {
|
||||
|
||||
private final ModelContainer currentModel;
|
||||
|
||||
private final DdlBuffer apply;
|
||||
|
||||
private final DdlBuffer applyForeignKeys;
|
||||
|
||||
private final DdlBuffer applyHistory;
|
||||
|
||||
private final DdlBuffer rollbackForeignKeys;
|
||||
|
||||
private final DdlBuffer rollbackLast;
|
||||
|
||||
/**
|
||||
* Create without any configuration or current model (no history support).
|
||||
*/
|
||||
public DdlWrite() {
|
||||
this(new MConfiguration(), new ModelContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create with a configuration.
|
||||
*/
|
||||
public DdlWrite(MConfiguration configuration, ModelContainer currentModel) {
|
||||
this.currentModel = currentModel;
|
||||
this.apply = new BaseDdlBuffer(configuration);
|
||||
this.applyForeignKeys = new BaseDdlBuffer(configuration);
|
||||
this.applyHistory = new BaseDdlBuffer(configuration);
|
||||
this.rollbackForeignKeys = new BaseDdlBuffer(configuration);
|
||||
this.rollbackLast = new BaseDdlBuffer(configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Table information from the current model.
|
||||
* <p>
|
||||
* This is typically required for the history support (used to determine the list of columns
|
||||
* included in the history when creating or recreating the associated trigger/stored procedure).
|
||||
* </p>
|
||||
*/
|
||||
public MTable getTable(String tableName) {
|
||||
return currentModel.getTable(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that APPLY DDL is written to.
|
||||
*/
|
||||
public DdlBuffer apply() {
|
||||
return apply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that APPLY DDL is written to for foreign keys and their associated indexes.
|
||||
* <p>
|
||||
* Statements added to this buffer are executed after all the normal apply statements and
|
||||
* typically 'add foreign key' is added to this buffer.
|
||||
*/
|
||||
public DdlBuffer applyForeignKeys() {
|
||||
return applyForeignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that apply history DDL is written to.
|
||||
*/
|
||||
public DdlBuffer applyHistory() {
|
||||
return applyHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that ROLLBACK DDL is written to for foreign keys and associated indexes.
|
||||
*/
|
||||
public DdlBuffer rollbackForeignKeys() {
|
||||
return rollbackForeignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that ROLLBACK DDL is written to (typically drop tables).
|
||||
* <p>
|
||||
* Statements added to this rollback buffer are executed after foreign key rollback
|
||||
* has been executed.
|
||||
*/
|
||||
public DdlBuffer rollback() {
|
||||
return rollbackLast;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Write table DDL.
|
||||
*/
|
||||
public interface TableDdl {
|
||||
|
||||
/**
|
||||
* Generate the create table DDL.
|
||||
*/
|
||||
void generate(DdlWrite writer, CreateTable createTable) throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.ColumnDdl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class BaseColumnDdl implements ColumnDdl {
|
||||
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
|
||||
String tableName = addColumn.getTableName();
|
||||
List<Column> columns = addColumn.getColumn();
|
||||
for (Column column : columns) {
|
||||
// apply
|
||||
alterTableAddColumn(writer.apply(), tableName, column);
|
||||
|
||||
// rollback
|
||||
alterTableDropColumn(writer.rollback(), tableName, column.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
|
||||
String tableName = dropColumn.getTableName();
|
||||
|
||||
alterTableDropColumn(writer.apply(), tableName, dropColumn.getColumnName());
|
||||
|
||||
// no good rollback option here, it is best if drop columns
|
||||
// are put into a separate changeSet that is run last
|
||||
}
|
||||
|
||||
protected void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
|
||||
buffer.append("alter table ").append(tableName)
|
||||
.append(" drop column ").append(columnName)
|
||||
.endOfStatement().end();
|
||||
}
|
||||
|
||||
protected void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column) throws IOException {
|
||||
|
||||
buffer.append("alter table ").append(tableName)
|
||||
.append(" add column ").append(column.getName())
|
||||
.append(" ").append(column.getType());
|
||||
|
||||
if (Boolean.TRUE.equals(column.isNotnull())) {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
if (hasValue(column.getCheckConstraint())) {
|
||||
buffer.append(" ").append(column.getCheckConstraint());
|
||||
}
|
||||
buffer.endOfStatement().end();
|
||||
}
|
||||
|
||||
|
||||
protected boolean hasValue(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.model.MConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* Base implementation of DdlBuffer using an underlying writer.
|
||||
*/
|
||||
public class BaseDdlBuffer implements DdlBuffer {
|
||||
|
||||
protected final Writer writer;
|
||||
|
||||
protected final MConfiguration configuration;
|
||||
|
||||
public BaseDdlBuffer(MConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.writer = new StringWriter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MConfiguration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer appendWithSpace(String foreignKeyRestrict) throws IOException {
|
||||
if (foreignKeyRestrict != null && !foreignKeyRestrict.isEmpty()) {
|
||||
writer.append(" ").append(foreignKeyRestrict);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer append(String content) throws IOException {
|
||||
writer.append(content);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer append(String content, int space) throws IOException {
|
||||
writer.append(content);
|
||||
appendSpace(space, content);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void appendSpace(int max, String content) throws IOException {
|
||||
int space = max - content.length();
|
||||
if (space > 0) {
|
||||
for (int i = 0; i < space; i++) {
|
||||
append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer endOfStatement() throws IOException {
|
||||
writer.append(";\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to demarcate the end of a series of statements.
|
||||
* This should be just whitespace or a sql comment.
|
||||
*/
|
||||
@Override
|
||||
public DdlBuffer end() throws IOException {
|
||||
writer.append("\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer newLine() throws IOException {
|
||||
writer.append("\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getBuffer() {
|
||||
return writer.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.TableDdl;
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base implementation for 'create table' and 'alter table' statements.
|
||||
*/
|
||||
public class BaseTableDdl implements TableDdl {
|
||||
|
||||
protected final DdlNamingConvention namingConvention;
|
||||
|
||||
protected final PlatformDdl platformDdl;
|
||||
|
||||
public BaseTableDdl(DdlNamingConvention namingConvention, PlatformDdl platformDdl) {
|
||||
this.namingConvention = namingConvention;
|
||||
this.platformDdl = platformDdl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the appropriate 'create table' and matching 'drop table' statements
|
||||
* and add them to the 'apply' and 'rollback' buffers.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateTable createTable) throws IOException {
|
||||
|
||||
String tableName = createTable.getName();
|
||||
List<Column> columns = createTable.getColumn();
|
||||
List<Column> pk = determinePrimaryKeyColumns(columns);
|
||||
|
||||
DdlBuffer apply = writer.apply();
|
||||
apply.append("create table ").append(tableName).append(" (");
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
apply.newLine();
|
||||
writeColumnDefinition(apply, columns.get(i));
|
||||
if (i < columns.size() - 1) {
|
||||
apply.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
writeCheckConstraints(apply, createTable);
|
||||
writeUniqueConstraints(apply, createTable);
|
||||
writeCompoundUniqueConstraints(apply, createTable);
|
||||
if (!pk.isEmpty()) {
|
||||
writePrimaryKeyConstraint(apply, tableName, pk);
|
||||
}
|
||||
|
||||
apply.newLine().append(")").endOfStatement();
|
||||
apply.end();
|
||||
|
||||
writeAddForeignKeys(writer, createTable);
|
||||
|
||||
// add drop table to the rollback buffer
|
||||
dropTable(writer.rollback(), tableName);
|
||||
|
||||
if (isTrue(createTable.isWithHistory())) {
|
||||
createWithHistory(writer, createTable.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createWithHistory(DdlWrite writer, String name) throws IOException {
|
||||
|
||||
MTable table = writer.getTable(name);
|
||||
platformDdl.createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
protected void writeAddForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
|
||||
List<Column> columns = createTable.getColumn();
|
||||
for (Column column : columns) {
|
||||
String references = column.getReferences();
|
||||
if (hasValue(references)) {
|
||||
writeForeignKey(write, createTable.getName(), column.getName(), references);
|
||||
}
|
||||
}
|
||||
//createTable.
|
||||
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, String tableName, String columnName, String references) throws IOException {
|
||||
|
||||
String fkName = determineForeignKeyConstraintName(tableName, columnName);
|
||||
|
||||
int pos = references.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
throw new IllegalStateException("Expecting period '.' character for table.column split but not found in [" + references + "]");
|
||||
}
|
||||
String refTableName = references.substring(0, pos);
|
||||
String refColumnName = references.substring(pos + 1);
|
||||
|
||||
String[] cols = {columnName};
|
||||
String[] refCols = {refColumnName};
|
||||
|
||||
writeForeignKey(write, fkName, tableName, cols, refTableName, refCols);
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, String fkName, String tableName, String[] columns, String refTable, String[] refColumns) throws IOException {
|
||||
|
||||
DdlBuffer fkeyBuffer = write.applyForeignKeys();
|
||||
fkeyBuffer
|
||||
.append("alter table ").append(tableName)
|
||||
.append(" add constraint ").append(fkName)
|
||||
.append(" foreign key (");
|
||||
appendColumns(columns, fkeyBuffer);
|
||||
fkeyBuffer
|
||||
.append(") references ")
|
||||
.append(refTable);
|
||||
appendColumns(refColumns, fkeyBuffer);
|
||||
fkeyBuffer.appendWithSpace(platformDdl.getForeignKeyRestrict())
|
||||
.endOfStatement();
|
||||
|
||||
String indexName = determineForeignKeyIndexName(tableName, columns);
|
||||
|
||||
fkeyBuffer.append("create index ").append(indexName).append(" on ").append(tableName);
|
||||
appendColumns(columns, fkeyBuffer);
|
||||
fkeyBuffer.endOfStatement();
|
||||
|
||||
fkeyBuffer.end();
|
||||
|
||||
write.rollbackForeignKeys()
|
||||
.append("drop index ").append(indexName)
|
||||
.endOfStatement();
|
||||
|
||||
write.rollbackForeignKeys()
|
||||
.append("alter table ").append(tableName).append(" drop constraint ").append(fkName)
|
||||
.endOfStatement();
|
||||
|
||||
write.rollbackForeignKeys().end();
|
||||
|
||||
}
|
||||
|
||||
private void appendColumns(String[] columns, DdlBuffer buffer) throws IOException {
|
||||
buffer.append(" (");
|
||||
for (int i = 0; i <columns.length ; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(columns[i]);
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add 'drop table' statement to the buffer.
|
||||
*/
|
||||
protected void dropTable(DdlBuffer buffer, String tableName) throws IOException {
|
||||
|
||||
buffer.append("drop table ").append(tableName).endOfStatement().end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write all the check constraints.
|
||||
*/
|
||||
protected void writeCheckConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
|
||||
List<Column> columns = createTable.getColumn();
|
||||
for (Column column : columns) {
|
||||
String checkConstraint = column.getCheckConstraint();
|
||||
if (hasValue(checkConstraint)) {
|
||||
writeCheckConstraint(apply, createTable.getName(), column, checkConstraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a check constraint.
|
||||
*/
|
||||
protected void writeCheckConstraint(DdlBuffer buffer, String tableName, Column column, String checkConstraint) throws IOException {
|
||||
|
||||
String ckName = determineCheckConstraintName(tableName, column.getName());
|
||||
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(ckName);
|
||||
buffer.append(" ").append(checkConstraint);
|
||||
}
|
||||
|
||||
protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) {
|
||||
//TODO: Write compound unique constraints
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unique constraints inline with the create table statement.
|
||||
*/
|
||||
protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
|
||||
List<Column> columns = createTable.getColumn();
|
||||
for (Column column : columns) {
|
||||
if (isTrue(column.isUnique())) {
|
||||
inlineUniqueConstraintSingle(apply, createTable.getName(), column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unique constraint inline with the create table statement.
|
||||
*/
|
||||
protected void inlineUniqueConstraintSingle(DdlBuffer buffer, String tableName, Column column) throws IOException {
|
||||
|
||||
String uqName = determineUniqueConstraintName(tableName, column.getName());
|
||||
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(uqName).append(" unique ");
|
||||
buffer.append("(");
|
||||
buffer.append(column.getName());
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the primary key constraint inline with the create table statement.
|
||||
*/
|
||||
protected void writePrimaryKeyConstraint(DdlBuffer buffer, String tableName, List<Column> pk) throws IOException {
|
||||
|
||||
String pkName = determinePrimaryKeyName(tableName, pk);
|
||||
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(pkName).append(" primary key ");
|
||||
buffer.append("(");
|
||||
for (int i = 0; i < pk.size(); i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(pk.get(i).getName());
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write alter table add primary key statement.
|
||||
*/
|
||||
public void alterTableAddPrimaryKey(DdlBuffer buffer, String tableName, List<Column> pk) throws IOException {
|
||||
|
||||
String pkName = determinePrimaryKeyName(tableName, pk);
|
||||
|
||||
buffer.append("alter table ").append(tableName);
|
||||
buffer.append(" add primary key ").append(pkName).append(" (");
|
||||
for (int i = 0; i < pk.size(); i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(pk.get(i).getName());
|
||||
}
|
||||
buffer.append(")").endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the column definition to the create table statement.
|
||||
*/
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, Column column) throws IOException {
|
||||
|
||||
String platformType = convertToPlatformType(column.getType(), isTrue(column.isIdentity()));
|
||||
|
||||
buffer.append(" ");
|
||||
buffer.append(column.getName(), 30);
|
||||
buffer.append(platformType);
|
||||
if (isTrue(column.isNotnull()) || isTrue(column.isPrimaryKey())) {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
|
||||
// add check constraints later as we really want to give them a nice name
|
||||
// so that the database can potentially provide a nice SQL error
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the expected logical type into a platform specific one.
|
||||
* <p>
|
||||
* For example clob -> text for postgres.
|
||||
* </p>
|
||||
*/
|
||||
protected String convertToPlatformType(String type, boolean identity) {
|
||||
return platformDdl.convert(type, identity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary key constraint name.
|
||||
*/
|
||||
protected String determinePrimaryKeyName(String tableName, List<Column> pkColumns) {
|
||||
|
||||
// collect the primary key column names
|
||||
List<String> pkColumnNames = new ArrayList<String>(pkColumns.size());
|
||||
for (int i = 0; i < pkColumns.size(); i++) {
|
||||
pkColumnNames.add(pkColumns.get(i).getName());
|
||||
}
|
||||
return namingConvention.primaryKeyName(tableName, pkColumnNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
protected String determineForeignKeyConstraintName(String tableName, String columnName) {
|
||||
|
||||
return namingConvention.foreignKeyConstraintName(tableName, columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
protected String determineForeignKeyIndexName(String tableName, String[] columns) {
|
||||
|
||||
return namingConvention.foreignKeyIndexName(tableName, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
protected String determineUniqueConstraintName(String tableName, String columnName) {
|
||||
|
||||
return namingConvention.uniqueConstraintName(tableName, columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the constraint name.
|
||||
*/
|
||||
protected String determineCheckConstraintName(String tableName, String columnName) {
|
||||
|
||||
return namingConvention.checkConstraintName(tableName, columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of columns that make the primary key.
|
||||
*/
|
||||
protected List<Column> determinePrimaryKeyColumns(List<Column> columns) {
|
||||
List<Column> pk = new ArrayList<Column>(3);
|
||||
for (Column column : columns) {
|
||||
if (isTrue(column.isPrimaryKey())) {
|
||||
pk.add(column);
|
||||
}
|
||||
}
|
||||
return pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if null or trimmed string is empty.
|
||||
*/
|
||||
protected boolean hasValue(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Null safe Boolean true test.
|
||||
*/
|
||||
protected boolean isTrue(Boolean value) {
|
||||
return Boolean.TRUE.equals(value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
/**
|
||||
* Used to normalise table and column names which means stripping out
|
||||
* quoted identifier characters and any catalog or schema prefix.
|
||||
*/
|
||||
public class DbNameNormalise {
|
||||
|
||||
protected boolean lowerCase = true;
|
||||
|
||||
protected String[] quotedIdentifiers = {"\"", "'", "[", "]", "`"};
|
||||
|
||||
/**
|
||||
* Normalise the table name by trimming catalog and schema and removing any
|
||||
* quoted identifier characters (",',[,] etc).
|
||||
*/
|
||||
public String normalise(String tableName) {
|
||||
|
||||
tableName = trimQuotes(tableName);
|
||||
int lastPeriod = tableName.lastIndexOf('.');
|
||||
if (lastPeriod > -1) {
|
||||
tableName = tableName.substring(lastPeriod + 1);
|
||||
}
|
||||
if (lowerCase) {
|
||||
tableName = tableName.toLowerCase();
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim off the platform quoted identifier quotes like [ ' and ".
|
||||
*/
|
||||
protected String trimQuotes(String tableName) {
|
||||
|
||||
// remove quoted identifier characters
|
||||
for (int i = 0; i < quotedIdentifiers.length; i++) {
|
||||
tableName = tableName.replace(quotedIdentifiers[i], "");
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebeaninternal.server.type.ScalarTypeBoolean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Naming convention used for constraint names.
|
||||
*/
|
||||
public class DdlNamingConvention {
|
||||
|
||||
protected String pkPrefix = "pk_";
|
||||
protected String pkSuffix = "";
|
||||
|
||||
protected String fkPrefix = "fk_";
|
||||
protected String fkMiddle = "_";
|
||||
protected String fkSuffix = "";
|
||||
|
||||
protected String fkIndexPrefix = "ix_";
|
||||
protected String fkIndexMiddle = "_";
|
||||
protected String fkIndexSuffix = "";
|
||||
|
||||
protected String uqPrefix = "uq_";
|
||||
protected String uqSuffix = "";
|
||||
|
||||
protected String ckPrefix = "ck_";
|
||||
protected String ckSuffix = "";
|
||||
|
||||
protected final DbNameNormalise normalise;
|
||||
|
||||
public DdlNamingConvention() {
|
||||
this.normalise = new DbNameNormalise();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary key constraint name.
|
||||
*/
|
||||
public String primaryKeyName(String tableName, List<String> pkColumns) {
|
||||
|
||||
return pkPrefix + normalise(tableName) + pkSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint name given a single column foreign key.
|
||||
*/
|
||||
public String foreignKeyConstraintName(String tableName, String columnName) {
|
||||
return fkPrefix + normalise(tableName) + fkMiddle + normalise(columnName) + fkSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index name associated with a foreign key constraint given a single column foreign key.
|
||||
*/
|
||||
public String foreignKeyIndexName(String tableName, String[] columns) {
|
||||
|
||||
String cols = columns.length == 1 ? normalise(columns[0]) : joinColumns(columns);
|
||||
return fkIndexPrefix + normalise(tableName) + fkIndexMiddle + cols + fkIndexSuffix;
|
||||
}
|
||||
|
||||
private String joinColumns(String[] columns) {
|
||||
|
||||
//TODO: Fix this to handle maximum constraint name limits
|
||||
StringBuilder sb = new StringBuilder(30);
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append("-");
|
||||
}
|
||||
sb.append(columns[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
public String uniqueConstraintName(String tableName, String columnName) {
|
||||
|
||||
return uqPrefix + normalise(tableName) + "_" + normalise(columnName) + uqSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the check constraint name.
|
||||
*/
|
||||
public String checkConstraintName(String tableName, String columnName) {
|
||||
|
||||
return ckPrefix + normalise(tableName) + "_" + normalise(columnName) + ckSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise the table name by trimming catalog and schema and removing any
|
||||
* quoted identifier characters (",',[,] etc).
|
||||
*/
|
||||
protected String normalise(String tableName) {
|
||||
|
||||
return normalise.normalise(tableName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
|
||||
/**
|
||||
* H2 platform specific DDL.
|
||||
*/
|
||||
public class H2Ddl extends PlatformDdl {
|
||||
|
||||
public H2Ddl(DbTypeMap platformTypes) {
|
||||
super(platformTypes, new H2HistoryDdl());
|
||||
this.foreignKeyRestrict = "on delete restrict on update restrict";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class H2HistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
// does nothing, not supported yet
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PlatformDdl {
|
||||
|
||||
protected final PlatformHistoryDdl historyDdl;
|
||||
|
||||
protected final PlatformTypeConverter typeConverter;
|
||||
|
||||
protected String foreignKeyRestrict = "";
|
||||
|
||||
public PlatformDdl(DbTypeMap platformTypes, PlatformHistoryDdl historyDdl) {
|
||||
this.typeConverter = new PlatformTypeConverter(platformTypes);
|
||||
this.historyDdl = historyDdl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify and return the column definition for autoincrement or identity definition.
|
||||
*/
|
||||
public String asIdentityColumn(String columnDefn) {
|
||||
return columnDefn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key on delete on update restrict clause.
|
||||
*/
|
||||
public String getForeignKeyRestrict() {
|
||||
return foreignKeyRestrict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the standard type to the platform specific type.
|
||||
*/
|
||||
public String convert(String type, boolean identity) {
|
||||
String platformType = typeConverter.convert(type);
|
||||
return identity ? asIdentityColumn(platformType) : platformType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add history support to this table using the platform specific mechanism.
|
||||
*/
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
historyDdl.createWithHistory(writer, table);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines the implementation for adding history support to a table.
|
||||
*/
|
||||
public interface PlatformHistoryDdl {
|
||||
|
||||
/**
|
||||
* Add history support to the table using platform specific mechanism.
|
||||
*/
|
||||
void createWithHistory(DdlWrite writer, MTable table) throws IOException;
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
|
||||
/**
|
||||
* Converts a logical column definition into platform specific one.
|
||||
*
|
||||
* This translates standard sql types into platform specific ones.
|
||||
*/
|
||||
public class PlatformTypeConverter {
|
||||
|
||||
protected final DbTypeMap platformTypes;
|
||||
|
||||
/**
|
||||
* Construct with the platform specific types.
|
||||
*/
|
||||
public PlatformTypeConverter(DbTypeMap platformTypes) {
|
||||
this.platformTypes = platformTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the standard type to the platform specific type.
|
||||
*/
|
||||
public String convert(String columnDefinition) {
|
||||
|
||||
int open = columnDefinition.indexOf('(');
|
||||
if (open > -1) {
|
||||
// no scale or precision
|
||||
return convertWithScale(columnDefinition, open);
|
||||
} else {
|
||||
return convertNoScale(columnDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a type that has scale and possibly precision.
|
||||
*/
|
||||
protected String convertWithScale(String columnDefinition, int open) {
|
||||
|
||||
int close = columnDefinition.lastIndexOf(')');
|
||||
if (close == -1) {
|
||||
// assume already platform specific, leave as is
|
||||
return columnDefinition;
|
||||
}
|
||||
|
||||
String type = columnDefinition.substring(0,open);
|
||||
try {
|
||||
DbType dbType = platformTypes.lookup(type);
|
||||
int comma = columnDefinition.indexOf(',',open);
|
||||
if (comma > -1) {
|
||||
// scale and precision - decimal(10,4)
|
||||
int scale = Integer.parseInt(columnDefinition.substring(open+1, comma));
|
||||
int precision = Integer.parseInt(columnDefinition.substring(comma+1, close));
|
||||
return dbType.renderType(scale,precision);
|
||||
|
||||
} else {
|
||||
// scale - varchar(10)
|
||||
int scale = Integer.parseInt(columnDefinition.substring(open+1, close));
|
||||
return dbType.renderType(scale,0);
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
// assume already platform specific, leave as is
|
||||
return columnDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a simple type with not scale or precision.
|
||||
*/
|
||||
protected String convertNoScale(String columnDefinition) {
|
||||
|
||||
try {
|
||||
DbType dbType = platformTypes.lookup(columnDefinition);
|
||||
return dbType.renderType(0,0);
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
// assume already platform specific, leave as is
|
||||
return columnDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
|
||||
/**
|
||||
* Postgres specific DDL.
|
||||
*/
|
||||
public class PostgresDdl extends PlatformDdl {
|
||||
|
||||
public PostgresDdl(DbTypeMap platformTypes) {
|
||||
super(platformTypes, new PostgresHistoryDdl());
|
||||
this.foreignKeyRestrict = "on delete restrict on update restrict";
|
||||
}
|
||||
|
||||
/**
|
||||
* Map bigint, integer and smallint into their equivalent serial types.
|
||||
*/
|
||||
public String asIdentityColumn(String columnDefn) {
|
||||
|
||||
if ("bigint".equalsIgnoreCase(columnDefn)) {
|
||||
return "bigserial";
|
||||
}
|
||||
if ("integer".equalsIgnoreCase(columnDefn)) {
|
||||
return "serial";
|
||||
}
|
||||
if ("smallint".equalsIgnoreCase(columnDefn)) {
|
||||
return "smallserial";
|
||||
}
|
||||
return columnDefn;
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.model.MColumn;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PostgresHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
DbNameNormalise normalise = new DbNameNormalise();
|
||||
|
||||
protected String historyTableName(String baseTableName) {
|
||||
return baseTableName + "_history";
|
||||
}
|
||||
|
||||
protected String procedureName(String baseTableName) {
|
||||
return baseTableName + "_history_version";
|
||||
}
|
||||
|
||||
protected String triggerName(String baseTableName) {
|
||||
return baseTableName + "_history_upd";
|
||||
}
|
||||
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
// naming convention
|
||||
|
||||
addHistoryTable(writer, table);
|
||||
addStoredFunction(writer, table);
|
||||
addTrigger(writer, table);
|
||||
}
|
||||
|
||||
public void addHistoryTable(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = this.normalise.normalise(table.getName());
|
||||
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
|
||||
buffer
|
||||
.append("alter table ").append(baseTableName)
|
||||
.append(" add column sys_period tstzrange not null")
|
||||
.endOfStatement().end();
|
||||
|
||||
buffer
|
||||
.append("create table ").append(baseTableName).append("_history")
|
||||
.append(" (like ").append(baseTableName).append(")")
|
||||
.endOfStatement().end();
|
||||
|
||||
buffer
|
||||
.append("create view ").append(baseTableName).append("_with_history")
|
||||
.append(" as select * from").append(baseTableName)
|
||||
.append(" union all select * from").append(baseTableName).append("_history")
|
||||
.endOfStatement().end();
|
||||
|
||||
}
|
||||
|
||||
public void addTrigger(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = this.normalise.normalise(table.getName());
|
||||
String procedureName = procedureName(baseTableName);
|
||||
String triggerName = triggerName(baseTableName);
|
||||
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
buffer
|
||||
.append("create trigger ").append(triggerName).newLine()
|
||||
.append(" before insert or update or delete on ").append(baseTableName).newLine()
|
||||
.append(" for each row execute procedure ").append(procedureName).append("();").newLine().newLine();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addStoredFunction(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = this.normalise.normalise(table.getName());
|
||||
String procedureName = procedureName(baseTableName);
|
||||
DdlBuffer buffer = writer.applyHistory();
|
||||
|
||||
buffer
|
||||
.append("create or replace function ").append(procedureName).append("() returns trigger as $$").newLine()
|
||||
.append("begin").newLine();
|
||||
buffer
|
||||
.append(" if (TG_OP = 'INSERT') then").newLine()
|
||||
.append(" NEW.sys_period = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" return new;").newLine().newLine();
|
||||
buffer
|
||||
.append(" elsif (TG_OP = 'UPDATE') then").newLine();
|
||||
appendInsertIntoHistory(buffer, table);
|
||||
buffer
|
||||
.append(" NEW.sys_period = tstzrange(CURRENT_TIMESTAMP,null);").newLine()
|
||||
.append(" return new;").newLine().newLine();
|
||||
buffer
|
||||
.append(" elsif (TG_OP = 'DELETE') then").newLine();
|
||||
appendInsertIntoHistory(buffer, table);
|
||||
buffer
|
||||
.append(" return old;").newLine().newLine();
|
||||
|
||||
buffer
|
||||
.append(" end if;").newLine()
|
||||
.append("end;").newLine()
|
||||
.append("$$ LANGUAGE plpgsql;").newLine();
|
||||
|
||||
buffer.end();
|
||||
}
|
||||
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, MTable table) throws IOException {
|
||||
|
||||
String historyTable = historyTableName(table.getName());
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (sys_period,");
|
||||
appendColumnNames(buffer, table, "");
|
||||
buffer.append(") values (tstzrange(lower(OLD.sys_period), CURRENT_TIMESTAMP), ");
|
||||
appendColumnNames(buffer, table, "OLD.");
|
||||
buffer.append(");").newLine();
|
||||
}
|
||||
|
||||
protected void appendColumnNames(DdlBuffer buffer, MTable table, String columnPrefix) throws IOException {
|
||||
|
||||
//id, line1, line2, city, country_code, version, when_created, when_updated
|
||||
Collection<MColumn> columns = table.getColumns().values();
|
||||
int i = 0;
|
||||
for (MColumn column : columns) {
|
||||
if (++i > 1) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
buffer.append(columnPrefix);
|
||||
buffer.append(column.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}column" maxOccurs="unbounded"/>
|
||||
* </sequence>
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"column"
|
||||
})
|
||||
@XmlRootElement(name = "addColumn")
|
||||
public class AddColumn {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected List<Column> column;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
|
||||
/**
|
||||
* Gets the value of the column property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the column property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getColumn().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Column }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<Column> getColumn() {
|
||||
if (column == null) {
|
||||
column = new ArrayList<Column>();
|
||||
}
|
||||
return this.column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <simpleContent>
|
||||
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columns" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="references" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </extension>
|
||||
* </simpleContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"value"
|
||||
})
|
||||
@XmlRootElement(name = "addForeignKey")
|
||||
public class AddForeignKey {
|
||||
|
||||
@XmlValue
|
||||
protected String value;
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "columns", required = true)
|
||||
protected String columns;
|
||||
@XmlAttribute(name = "references", required = true)
|
||||
protected String references;
|
||||
|
||||
/**
|
||||
* Gets the value of the value property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the value property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columns property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columns property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setColumns(String value) {
|
||||
this.columns = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the references property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the references property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setReferences(String value) {
|
||||
this.references = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="resourcePath" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "application")
|
||||
public class Application {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "resourcePath", required = true)
|
||||
protected String resourcePath;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the resourcePath property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getResourcePath() {
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the resourcePath property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setResourcePath(String value) {
|
||||
this.resourcePath = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}application" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"application"
|
||||
})
|
||||
@XmlRootElement(name = "applications")
|
||||
public class Applications {
|
||||
|
||||
protected List<Application> application;
|
||||
|
||||
/**
|
||||
* Gets the value of the application property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the application property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getApplication().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Application }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<Application> getApplication() {
|
||||
if (application == null) {
|
||||
application = new ArrayList<Application>();
|
||||
}
|
||||
return this.application;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
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>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <simpleContent>
|
||||
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
|
||||
* </extension>
|
||||
* </simpleContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"value"
|
||||
})
|
||||
@XmlRootElement(name = "apply")
|
||||
public class Apply {
|
||||
|
||||
@XmlValue
|
||||
protected String value;
|
||||
|
||||
/**
|
||||
* Gets the value of the value property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the value property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElements;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSchemaType;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <choice>
|
||||
* <group ref="{http://ebean-orm.github.io/xml/ns/dbmigration}changeSetChildren" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </choice>
|
||||
* </sequence>
|
||||
* <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="comment" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"changeSetChildren"
|
||||
})
|
||||
@XmlRootElement(name = "changeSet")
|
||||
public class ChangeSet {
|
||||
|
||||
@XmlElements({
|
||||
@XmlElement(name = "configuration", type = Configuration.class),
|
||||
@XmlElement(name = "sql", type = Sql.class),
|
||||
@XmlElement(name = "createTable", type = CreateTable.class),
|
||||
@XmlElement(name = "dropTable", type = DropTable.class),
|
||||
@XmlElement(name = "renameTable", type = RenameTable.class),
|
||||
@XmlElement(name = "addHistoryTable", type = CreateHistoryTable.class),
|
||||
@XmlElement(name = "createView", type = CreateView.class),
|
||||
@XmlElement(name = "dropView", type = DropView.class),
|
||||
@XmlElement(name = "renameView", type = RenameView.class),
|
||||
@XmlElement(name = "addColumn", type = AddColumn.class),
|
||||
@XmlElement(name = "dropColumn", type = DropColumn.class),
|
||||
@XmlElement(name = "renameColumn", type = RenameColumn.class),
|
||||
@XmlElement(name = "addForeignKey", type = AddForeignKey.class),
|
||||
@XmlElement(name = "dropForeignKey", type = DropForeignKey.class)
|
||||
})
|
||||
protected List<Object> changeSetChildren;
|
||||
@XmlAttribute(name = "id", required = true)
|
||||
@XmlSchemaType(name = "positiveInteger")
|
||||
protected BigInteger id;
|
||||
@XmlAttribute(name = "comment")
|
||||
protected String comment;
|
||||
|
||||
/**
|
||||
* Gets the value of the changeSetChildren property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the changeSetChildren property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getChangeSetChildren().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Configuration }
|
||||
* {@link Sql }
|
||||
* {@link CreateTable }
|
||||
* {@link DropTable }
|
||||
* {@link RenameTable }
|
||||
* {@link CreateHistoryTable }
|
||||
* {@link CreateView }
|
||||
* {@link DropView }
|
||||
* {@link RenameView }
|
||||
* {@link AddColumn }
|
||||
* {@link DropColumn }
|
||||
* {@link RenameColumn }
|
||||
* {@link AddForeignKey }
|
||||
* {@link DropForeignKey }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<Object> getChangeSetChildren() {
|
||||
if (changeSetChildren == null) {
|
||||
changeSetChildren = new ArrayList<Object>();
|
||||
}
|
||||
return this.changeSetChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the id property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link BigInteger }
|
||||
*
|
||||
*/
|
||||
public BigInteger getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the id property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link BigInteger }
|
||||
*
|
||||
*/
|
||||
public void setId(BigInteger value) {
|
||||
this.id = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the comment property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the comment property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setComment(String value) {
|
||||
this.comment = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attGroup ref="{http://ebean-orm.github.io/xml/ns/dbmigration}column"/>
|
||||
* <attGroup ref="{http://ebean-orm.github.io/xml/ns/dbmigration}columnAttributes"/>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"content"
|
||||
})
|
||||
@XmlRootElement(name = "column")
|
||||
public class Column {
|
||||
|
||||
@XmlValue
|
||||
protected String content;
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "type", required = true)
|
||||
protected String type;
|
||||
@XmlAttribute(name = "defaultValue")
|
||||
protected String defaultValue;
|
||||
@XmlAttribute(name = "remarks")
|
||||
protected String remarks;
|
||||
@XmlAttribute(name = "notnull")
|
||||
protected Boolean notnull;
|
||||
@XmlAttribute(name = "checkConstraint")
|
||||
protected String checkConstraint;
|
||||
@XmlAttribute(name = "unique")
|
||||
protected Boolean unique;
|
||||
@XmlAttribute(name = "primaryKey")
|
||||
protected Boolean primaryKey;
|
||||
@XmlAttribute(name = "identity")
|
||||
protected Boolean identity;
|
||||
@XmlAttribute(name = "references")
|
||||
protected String references;
|
||||
@XmlAttribute(name = "deleteCascade")
|
||||
protected Boolean deleteCascade;
|
||||
@XmlAttribute(name = "deferrable")
|
||||
protected Boolean deferrable;
|
||||
@XmlAttribute(name = "initiallyDeferred")
|
||||
protected Boolean initiallyDeferred;
|
||||
|
||||
/**
|
||||
* Gets the value of the content property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the content property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setContent(String value) {
|
||||
this.content = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the type property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the type property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setType(String value) {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the defaultValue property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the defaultValue property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setDefaultValue(String value) {
|
||||
this.defaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the remarks property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getRemarks() {
|
||||
return remarks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the remarks property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setRemarks(String value) {
|
||||
this.remarks = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the notnull property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isNotnull() {
|
||||
return notnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the notnull property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setNotnull(Boolean value) {
|
||||
this.notnull = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraint property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraint property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setCheckConstraint(String value) {
|
||||
this.checkConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the unique property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the unique property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setUnique(Boolean value) {
|
||||
this.unique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the primaryKey property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isPrimaryKey() {
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the primaryKey property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setPrimaryKey(Boolean value) {
|
||||
this.primaryKey = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identity property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the identity property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setIdentity(Boolean value) {
|
||||
this.identity = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the references property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the references property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setReferences(String value) {
|
||||
this.references = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the deleteCascade property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isDeleteCascade() {
|
||||
return deleteCascade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the deleteCascade property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setDeleteCascade(Boolean value) {
|
||||
this.deleteCascade = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the deferrable property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isDeferrable() {
|
||||
return deferrable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the deferrable property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setDeferrable(Boolean value) {
|
||||
this.deferrable = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the initiallyDeferred property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isInitiallyDeferred() {
|
||||
return initiallyDeferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the initiallyDeferred property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setInitiallyDeferred(Boolean value) {
|
||||
this.initiallyDeferred = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}defaultTablespace"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"defaultTablespace"
|
||||
})
|
||||
@XmlRootElement(name = "configuration")
|
||||
public class Configuration {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected DefaultTablespace defaultTablespace;
|
||||
|
||||
/**
|
||||
* Gets the value of the defaultTablespace property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link DefaultTablespace }
|
||||
*
|
||||
*/
|
||||
public DefaultTablespace getDefaultTablespace() {
|
||||
return defaultTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the defaultTablespace property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link DefaultTablespace }
|
||||
*
|
||||
*/
|
||||
public void setDefaultTablespace(DefaultTablespace value) {
|
||||
this.defaultTablespace = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="baseTable" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "createDropHistoryTable", namespace = "http://ebean-orm.github.io/xml/ns/dbmigration")
|
||||
public class CreateDropHistoryTable {
|
||||
|
||||
@XmlAttribute(name = "baseTable", required = true)
|
||||
protected String baseTable;
|
||||
|
||||
/**
|
||||
* Gets the value of the baseTable property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the baseTable property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setBaseTable(String value) {
|
||||
this.baseTable = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="baseTable" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "addHistoryTable")
|
||||
public class CreateHistoryTable {
|
||||
|
||||
@XmlAttribute(name = "baseTable", required = true)
|
||||
protected String baseTable;
|
||||
|
||||
/**
|
||||
* Gets the value of the baseTable property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the baseTable property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setBaseTable(String value) {
|
||||
this.baseTable = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}column" maxOccurs="unbounded"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}uniqueConstraint" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* <attGroup ref="{http://ebean-orm.github.io/xml/ns/dbmigration}tablespaceAttributes"/>
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"column",
|
||||
"uniqueConstraint"
|
||||
})
|
||||
@XmlRootElement(name = "createTable")
|
||||
public class CreateTable {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected List<Column> column;
|
||||
protected List<UniqueConstraint> uniqueConstraint;
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
@XmlAttribute(name = "tablespace")
|
||||
protected String tablespace;
|
||||
@XmlAttribute(name = "indexTablespace")
|
||||
protected String indexTablespace;
|
||||
@XmlAttribute(name = "remarks")
|
||||
protected String remarks;
|
||||
|
||||
/**
|
||||
* Gets the value of the column property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the column property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getColumn().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Column }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<Column> getColumn() {
|
||||
if (column == null) {
|
||||
column = new ArrayList<Column>();
|
||||
}
|
||||
return this.column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the uniqueConstraint property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the uniqueConstraint property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getUniqueConstraint().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link UniqueConstraint }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<UniqueConstraint> getUniqueConstraint() {
|
||||
if (uniqueConstraint == null) {
|
||||
uniqueConstraint = new ArrayList<UniqueConstraint>();
|
||||
}
|
||||
return this.uniqueConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the withHistory property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the withHistory property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setWithHistory(Boolean value) {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tablespace property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getTablespace() {
|
||||
return tablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tablespace property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setTablespace(String value) {
|
||||
this.tablespace = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the indexTablespace property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getIndexTablespace() {
|
||||
return indexTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexTablespace property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setIndexTablespace(String value) {
|
||||
this.indexTablespace = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the remarks property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getRemarks() {
|
||||
return remarks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the remarks property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setRemarks(String value) {
|
||||
this.remarks = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <simpleContent>
|
||||
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="replaceIfExists" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* </extension>
|
||||
* </simpleContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"value"
|
||||
})
|
||||
@XmlRootElement(name = "createView")
|
||||
public class CreateView {
|
||||
|
||||
@XmlValue
|
||||
protected String value;
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "replaceIfExists")
|
||||
protected Boolean replaceIfExists;
|
||||
|
||||
/**
|
||||
* Gets the value of the value property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the value property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the replaceIfExists property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isReplaceIfExists() {
|
||||
return replaceIfExists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the replaceIfExists property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setReplaceIfExists(Boolean value) {
|
||||
this.replaceIfExists = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="tables" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="indexes" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="history" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "defaultTablespace")
|
||||
public class DefaultTablespace {
|
||||
|
||||
@XmlAttribute(name = "tables")
|
||||
protected String tables;
|
||||
@XmlAttribute(name = "indexes")
|
||||
protected String indexes;
|
||||
@XmlAttribute(name = "history")
|
||||
protected String history;
|
||||
|
||||
/**
|
||||
* Gets the value of the tables property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getTables() {
|
||||
return tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tables property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setTables(String value) {
|
||||
this.tables = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the indexes property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getIndexes() {
|
||||
return indexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexes property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setIndexes(String value) {
|
||||
this.indexes = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the history property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getHistory() {
|
||||
return history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the history property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setHistory(String value) {
|
||||
this.history = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="columnName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropColumn")
|
||||
public class DropColumn {
|
||||
|
||||
@XmlAttribute(name = "columnName", required = true)
|
||||
protected String columnName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
|
||||
/**
|
||||
* Gets the value of the columnName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setColumnName(String value) {
|
||||
this.columnName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"content"
|
||||
})
|
||||
@XmlRootElement(name = "dropForeignKey")
|
||||
public class DropForeignKey {
|
||||
|
||||
@XmlValue
|
||||
protected String content;
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Gets the value of the content property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the content property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setContent(String value) {
|
||||
this.content = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="baseTable" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropHistoryTable")
|
||||
public class DropHistoryTable {
|
||||
|
||||
@XmlAttribute(name = "baseTable", required = true)
|
||||
protected String baseTable;
|
||||
|
||||
/**
|
||||
* Gets the value of the baseTable property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the baseTable property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setBaseTable(String value) {
|
||||
this.baseTable = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropTable")
|
||||
public class DropTable {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropView")
|
||||
public class DropView {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}changeSet" maxOccurs="unbounded"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"changeSet"
|
||||
})
|
||||
@XmlRootElement(name = "migration")
|
||||
public class Migration {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected List<ChangeSet> changeSet;
|
||||
|
||||
/**
|
||||
* Gets the value of the changeSet property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the changeSet property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getChangeSet().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link ChangeSet }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<ChangeSet> getChangeSet() {
|
||||
if (changeSet == null) {
|
||||
changeSet = new ArrayList<ChangeSet>();
|
||||
}
|
||||
return this.changeSet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRegistry;
|
||||
|
||||
|
||||
/**
|
||||
* This object contains factory methods for each
|
||||
* Java content interface and Java element interface
|
||||
* generated in the org.avaje.ebean.dbmigration.migration package.
|
||||
* <p>An ObjectFactory allows you to programatically
|
||||
* construct new instances of the Java representation
|
||||
* for XML content. The Java representation of XML
|
||||
* content can consist of schema derived interfaces
|
||||
* and classes representing the binding of schema
|
||||
* type definitions, element declarations and model
|
||||
* groups. Factory methods for each of these are
|
||||
* provided in this class.
|
||||
*
|
||||
*/
|
||||
@XmlRegistry
|
||||
public class ObjectFactory {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.avaje.ebean.dbmigration.migration
|
||||
*
|
||||
*/
|
||||
public ObjectFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Rollback }
|
||||
*
|
||||
*/
|
||||
public Rollback createRollback() {
|
||||
return new Rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AddColumn }
|
||||
*
|
||||
*/
|
||||
public AddColumn createAddColumn() {
|
||||
return new AddColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Column }
|
||||
*
|
||||
*/
|
||||
public Column createColumn() {
|
||||
return new Column();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link CreateTable }
|
||||
*
|
||||
*/
|
||||
public CreateTable createCreateTable() {
|
||||
return new CreateTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link UniqueConstraint }
|
||||
*
|
||||
*/
|
||||
public UniqueConstraint createUniqueConstraint() {
|
||||
return new UniqueConstraint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropForeignKey }
|
||||
*
|
||||
*/
|
||||
public DropForeignKey createDropForeignKey() {
|
||||
return new DropForeignKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Apply }
|
||||
*
|
||||
*/
|
||||
public Apply createApply() {
|
||||
return new Apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Configuration }
|
||||
*
|
||||
*/
|
||||
public Configuration createConfiguration() {
|
||||
return new Configuration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DefaultTablespace }
|
||||
*
|
||||
*/
|
||||
public DefaultTablespace createDefaultTablespace() {
|
||||
return new DefaultTablespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link RenameTable }
|
||||
*
|
||||
*/
|
||||
public RenameTable createRenameTable() {
|
||||
return new RenameTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropHistoryTable }
|
||||
*
|
||||
*/
|
||||
public DropHistoryTable createDropHistoryTable() {
|
||||
return new DropHistoryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link RenameView }
|
||||
*
|
||||
*/
|
||||
public RenameView createRenameView() {
|
||||
return new RenameView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AddForeignKey }
|
||||
*
|
||||
*/
|
||||
public AddForeignKey createAddForeignKey() {
|
||||
return new AddForeignKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropColumn }
|
||||
*
|
||||
*/
|
||||
public DropColumn createDropColumn() {
|
||||
return new DropColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropView }
|
||||
*
|
||||
*/
|
||||
public DropView createDropView() {
|
||||
return new DropView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ChangeSet }
|
||||
*
|
||||
*/
|
||||
public ChangeSet createChangeSet() {
|
||||
return new ChangeSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Sql }
|
||||
*
|
||||
*/
|
||||
public Sql createSql() {
|
||||
return new Sql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropTable }
|
||||
*
|
||||
*/
|
||||
public DropTable createDropTable() {
|
||||
return new DropTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link CreateHistoryTable }
|
||||
*
|
||||
*/
|
||||
public CreateHistoryTable createCreateHistoryTable() {
|
||||
return new CreateHistoryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link CreateView }
|
||||
*
|
||||
*/
|
||||
public CreateView createCreateView() {
|
||||
return new CreateView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link RenameColumn }
|
||||
*
|
||||
*/
|
||||
public RenameColumn createRenameColumn() {
|
||||
return new RenameColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Application }
|
||||
*
|
||||
*/
|
||||
public Application createApplication() {
|
||||
return new Application();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Migration }
|
||||
*
|
||||
*/
|
||||
public Migration createMigration() {
|
||||
return new Migration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Applications }
|
||||
*
|
||||
*/
|
||||
public Applications createApplications() {
|
||||
return new Applications();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="oldName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dataType" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "renameColumn")
|
||||
public class RenameColumn {
|
||||
|
||||
@XmlAttribute(name = "oldName", required = true)
|
||||
protected String oldName;
|
||||
@XmlAttribute(name = "newName", required = true)
|
||||
protected String newName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "dataType")
|
||||
protected String dataType;
|
||||
|
||||
/**
|
||||
* Gets the value of the oldName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setOldName(String value) {
|
||||
this.oldName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setNewName(String value) {
|
||||
this.newName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dataType property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dataType property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setDataType(String value) {
|
||||
this.dataType = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="oldName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "renameTable")
|
||||
public class RenameTable {
|
||||
|
||||
@XmlAttribute(name = "oldName", required = true)
|
||||
protected String oldName;
|
||||
@XmlAttribute(name = "newName", required = true)
|
||||
protected String newName;
|
||||
|
||||
/**
|
||||
* Gets the value of the oldName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setOldName(String value) {
|
||||
this.oldName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setNewName(String value) {
|
||||
this.newName = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="oldName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "renameView")
|
||||
public class RenameView {
|
||||
|
||||
@XmlAttribute(name = "oldName", required = true)
|
||||
protected String oldName;
|
||||
@XmlAttribute(name = "newName", required = true)
|
||||
protected String newName;
|
||||
|
||||
/**
|
||||
* Gets the value of the oldName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setOldName(String value) {
|
||||
this.oldName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setNewName(String value) {
|
||||
this.newName = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
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>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <simpleContent>
|
||||
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
|
||||
* </extension>
|
||||
* </simpleContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"value"
|
||||
})
|
||||
@XmlRootElement(name = "rollback")
|
||||
public class Rollback {
|
||||
|
||||
@XmlValue
|
||||
protected String value;
|
||||
|
||||
/**
|
||||
* Gets the value of the value property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the value property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}apply"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}rollback"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"apply",
|
||||
"rollback"
|
||||
})
|
||||
@XmlRootElement(name = "sql")
|
||||
public class Sql {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected Apply apply;
|
||||
@XmlElement(required = true)
|
||||
protected Rollback rollback;
|
||||
|
||||
/**
|
||||
* Gets the value of the apply property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Apply }
|
||||
*
|
||||
*/
|
||||
public Apply getApply() {
|
||||
return apply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the apply property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Apply }
|
||||
*
|
||||
*/
|
||||
public void setApply(Apply value) {
|
||||
this.apply = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the rollback property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Rollback }
|
||||
*
|
||||
*/
|
||||
public Rollback getRollback() {
|
||||
return rollback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the rollback property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Rollback }
|
||||
*
|
||||
*/
|
||||
public void setRollback(Rollback value) {
|
||||
this.rollback = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="columnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="constraintName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "uniqueConstraint")
|
||||
public class UniqueConstraint {
|
||||
|
||||
@XmlAttribute(name = "columnNames", required = true)
|
||||
protected String columnNames;
|
||||
@XmlAttribute(name = "constraintName")
|
||||
protected String constraintName;
|
||||
|
||||
/**
|
||||
* Gets the value of the columnNames property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnNames property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setColumnNames(String value) {
|
||||
this.columnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the constraintName property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getConstraintName() {
|
||||
return constraintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the constraintName property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setConstraintName(String value) {
|
||||
this.constraintName = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
@javax.xml.bind.annotation.XmlSchema(namespace = "http://ebean-orm.github.io/xml/ns/dbmigration", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
|
||||
package com.avaje.ebean.dbmigration.migration;
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.avaje.ebean.dbmigration.migrationreader;
|
||||
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Reads a migration xml document returning the Migration.
|
||||
*/
|
||||
public class MigrationXmlReader {
|
||||
|
||||
private static final MigrationXmlReader INSTANCE = new MigrationXmlReader();
|
||||
|
||||
/**
|
||||
* Read and return a Migration from an xml document at the given resource path.
|
||||
*/
|
||||
public static Migration read(String resourcePath) {
|
||||
|
||||
InputStream is = MigrationXmlReader.class.getResourceAsStream(resourcePath);
|
||||
if (is == null) {
|
||||
throw new IllegalArgumentException("No resource found for path [" + resourcePath + "]");
|
||||
}
|
||||
|
||||
return INSTANCE.read(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and return a Migration from an xml document.
|
||||
*/
|
||||
public Migration read(InputStream is) {
|
||||
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(Migration.class);
|
||||
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||
return (Migration) unmarshaller.unmarshal(is);
|
||||
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.avaje.ebean.dbmigration.migrationreader;
|
||||
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Simple writer for output of the Migration/ChangeSet as an XML document.
|
||||
*/
|
||||
public class MigrationXmlWriter {
|
||||
|
||||
/**
|
||||
* Write a Migration to a file as an xml document to the file.
|
||||
*/
|
||||
public void write(Migration migration, File file) {
|
||||
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(Migration.class);
|
||||
Marshaller marshaller = jaxbContext.createMarshaller();
|
||||
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||
marshaller.marshal(migration, file);
|
||||
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
import com.avaje.ebean.config.dbplatform.PostgresPlatform;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.DdlNamingConvention;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PostgresDdl;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
import com.avaje.ebean.dbmigration.migrationreader.MigrationXmlWriter;
|
||||
import com.avaje.ebean.dbmigration.model.build.ModelBuildBeanVisitor;
|
||||
import com.avaje.ebean.dbmigration.model.build.ModelBuildContext;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.VisitAllUsing;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Reads EbeanServer bean descriptors to build the current model.
|
||||
*/
|
||||
public class CurrentModel {
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
private DdlNamingConvention namingConvention;
|
||||
|
||||
private ModelContainer model;
|
||||
private ChangeSet changeSet;
|
||||
private DdlWrite write;
|
||||
|
||||
public CurrentModel(SpiEbeanServer server) {
|
||||
this.server = server;
|
||||
this.namingConvention = new DdlNamingConvention();
|
||||
}
|
||||
|
||||
public ModelContainer read() {
|
||||
if (model == null) {
|
||||
model = new ModelContainer();
|
||||
ModelBuildContext context = new ModelBuildContext(model);
|
||||
ModelBuildBeanVisitor visitor = new ModelBuildBeanVisitor(context);
|
||||
VisitAllUsing visit = new VisitAllUsing(visitor, server);
|
||||
visit.visitAllBeans();
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
public ChangeSet getChangeSet() {
|
||||
read();
|
||||
if (changeSet == null) {
|
||||
changeSet = asChangeSet();
|
||||
}
|
||||
return changeSet;
|
||||
}
|
||||
|
||||
public void writeMigration(File file) {
|
||||
|
||||
ChangeSet changeSet = getChangeSet();
|
||||
Migration migration = new Migration();
|
||||
migration.getChangeSet().add(changeSet);
|
||||
|
||||
MigrationXmlWriter writer = new MigrationXmlWriter();
|
||||
writer.write(migration, file);
|
||||
}
|
||||
|
||||
public String getCreateDdl() throws IOException {
|
||||
|
||||
createDdl();
|
||||
|
||||
StringBuilder ddl = new StringBuilder(2000);
|
||||
ddl.append(write.apply().getBuffer());
|
||||
ddl.append(write.applyForeignKeys().getBuffer());
|
||||
ddl.append(write.applyHistory().getBuffer());
|
||||
|
||||
return ddl.toString();
|
||||
}
|
||||
|
||||
public String getDropDdl() throws IOException {
|
||||
|
||||
createDdl();
|
||||
|
||||
StringBuilder ddl = new StringBuilder(2000);
|
||||
ddl.append(write.rollbackForeignKeys().getBuffer());
|
||||
ddl.append(write.rollback().getBuffer());
|
||||
|
||||
return ddl.toString();
|
||||
}
|
||||
|
||||
private void createDdl() throws IOException {
|
||||
|
||||
if (write == null) {
|
||||
ChangeSet createChangeSet = getChangeSet();
|
||||
|
||||
write = new DdlWrite();
|
||||
|
||||
BaseDdlHandler handler = handler();
|
||||
handler.generate(write, createChangeSet);
|
||||
}
|
||||
}
|
||||
|
||||
private BaseDdlHandler handler() {
|
||||
|
||||
DatabasePlatform databasePlatform = server.getDatabasePlatform();
|
||||
PlatformDdl platformDdl = databasePlatform.getPlatformDdl();
|
||||
|
||||
return new BaseDdlHandler(namingConvention, platformDdl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the model into a ChangeSet.
|
||||
*/
|
||||
private ChangeSet asChangeSet() {
|
||||
|
||||
// empty diff so changes will effectively all be create
|
||||
ModelDiff diff = new ModelDiff();
|
||||
diff.compareTo(model);
|
||||
|
||||
List<Object> createChanges = diff.getCreateChanges();
|
||||
|
||||
// put the changes into a ChangeSet
|
||||
ChangeSet createChangeSet = new ChangeSet();
|
||||
createChangeSet.getChangeSetChildren().addAll(createChanges);
|
||||
return createChangeSet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
|
||||
/**
|
||||
* A column in the logical model.
|
||||
*/
|
||||
public class MColumn {
|
||||
|
||||
private final String name;
|
||||
private final String type;
|
||||
private String checkConstraint;
|
||||
private String defaultValue;
|
||||
private String references;
|
||||
private boolean notnull;
|
||||
private boolean primaryKey;
|
||||
private boolean identity;
|
||||
private boolean unique;
|
||||
|
||||
public MColumn(Column column) {
|
||||
this.name = column.getName();
|
||||
this.type = column.getType();
|
||||
this.checkConstraint = column.getCheckConstraint();
|
||||
this.defaultValue = column.getDefaultValue();
|
||||
this.references = column.getReferences();
|
||||
this.notnull = Boolean.TRUE.equals(column.isNotnull());
|
||||
this.primaryKey = Boolean.TRUE.equals(column.isPrimaryKey());
|
||||
this.identity = Boolean.TRUE.equals(column.isIdentity());
|
||||
this.unique = Boolean.TRUE.equals(column.isUnique());
|
||||
}
|
||||
|
||||
public MColumn(String name, String type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public MColumn(String name, String type, boolean notnull) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.notnull = notnull;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isPrimaryKey() {
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
public void setPrimaryKey(boolean primaryKey) {
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
public boolean isIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public void setIdentity(boolean identity) {
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
public void setCheckConstraint(String checkConstraint) {
|
||||
this.checkConstraint = checkConstraint;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public String getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
public void setReferences(String references) {
|
||||
this.references = references;
|
||||
}
|
||||
|
||||
public boolean isNotnull() {
|
||||
return notnull;
|
||||
}
|
||||
|
||||
public void setNotnull(boolean notnull) {
|
||||
this.notnull = notnull;
|
||||
}
|
||||
|
||||
public void setUnique(boolean unique) {
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
public boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
public Column createColumn() {
|
||||
|
||||
Column c = new Column();
|
||||
c.setName(name);
|
||||
c.setType(type);
|
||||
c.setNotnull(notnull);
|
||||
c.setCheckConstraint(checkConstraint);
|
||||
c.setUnique(unique);
|
||||
c.setPrimaryKey(primaryKey);
|
||||
c.setIdentity(identity);
|
||||
c.setReferences(references);
|
||||
c.setDefaultValue(defaultValue);
|
||||
|
||||
//c.setDeleteCascade();
|
||||
//c.setDeferrable(deferrable);
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A unique constraint for multiple columns.
|
||||
* <p>
|
||||
* Note that unique constraint on a single column is instead
|
||||
* a boolean flag on the associated MColumn.
|
||||
* </p>
|
||||
*/
|
||||
public class MCompoundForeignKey {
|
||||
|
||||
private final String referenceTable;
|
||||
private final List<String> columns = new ArrayList<String>();
|
||||
private final List<String> referenceColumns = new ArrayList<String>();
|
||||
|
||||
public MCompoundForeignKey(String referenceTable) {
|
||||
this.referenceTable = referenceTable;
|
||||
}
|
||||
|
||||
public void addColumnPair(String dbCol, String refColumn) {
|
||||
columns.add(dbCol);
|
||||
referenceColumns.add(refColumn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
/**
|
||||
* A unique constraint for multiple columns.
|
||||
* <p>
|
||||
* Note that unique constraint on a single column is instead
|
||||
* a boolean flag on the associated MColumn.
|
||||
* </p>
|
||||
*/
|
||||
public class MCompoundUniqueConstraint {
|
||||
|
||||
/**
|
||||
* The columns combined to be unique.
|
||||
*/
|
||||
private final String[] columns;
|
||||
|
||||
public MCompoundUniqueConstraint(String[] columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
public String[] getColumns() {
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.Configuration;
|
||||
import com.avaje.ebean.dbmigration.migration.DefaultTablespace;
|
||||
|
||||
/**
|
||||
* Holds configuration such as the default tablespaces to use for tables,
|
||||
* indexes, history tables etc.
|
||||
*/
|
||||
public class MConfiguration {
|
||||
|
||||
/**
|
||||
* Default tablespace for tables.
|
||||
*/
|
||||
protected String tableTablespace;
|
||||
|
||||
/**
|
||||
* Default tablespace for indexes.
|
||||
*/
|
||||
protected String indexTablespace;
|
||||
|
||||
/**
|
||||
* Default tablespace for history tables.
|
||||
*/
|
||||
protected String historyTablespace;
|
||||
|
||||
/**
|
||||
* Apply the migration configuration.
|
||||
* <p>
|
||||
* It is expected that these are applied in the correct chronological order
|
||||
* from earliest to latest.
|
||||
* </p>
|
||||
*/
|
||||
public void apply(Configuration configuration) {
|
||||
|
||||
DefaultTablespace defaultTablespace = configuration.getDefaultTablespace();
|
||||
if (defaultTablespace != null) {
|
||||
String tables = defaultTablespace.getTables();
|
||||
if (isNotEmpty(tables)) {
|
||||
this.tableTablespace = tables;
|
||||
}
|
||||
String indexes = defaultTablespace.getIndexes();
|
||||
if (isNotEmpty(indexes)) {
|
||||
this.indexTablespace = indexes;
|
||||
}
|
||||
String history = defaultTablespace.getHistory();
|
||||
if (isNotEmpty(history)) {
|
||||
this.historyTablespace = history;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default tablespace to use for tables.
|
||||
*/
|
||||
public String getTableTablespace() {
|
||||
return tableTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default tablespace to use for indexes.
|
||||
*/
|
||||
public String getIndexTablespace() {
|
||||
return indexTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default tablespace to use for history tables.
|
||||
*/
|
||||
public String getHistoryTablespace() {
|
||||
return historyTablespace;
|
||||
}
|
||||
|
||||
protected boolean isNotEmpty(String tables) {
|
||||
return tables != null && !tables.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
/**
|
||||
* Index as part of the logical model.
|
||||
*/
|
||||
public class MIndex {
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.Column;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Holds the logical model for a given Table and everything associated to it.
|
||||
* <p>
|
||||
* This effectively represents a table, its columns and all associated
|
||||
* constraints, foreign keys and indexes.
|
||||
* </p>
|
||||
* <p>
|
||||
* Migrations can be applied to this such that it represents the state
|
||||
* of a given table after various migrations have been applied.
|
||||
* </p>
|
||||
* <p>
|
||||
* This table model can also be derived from the EbeanServer bean descriptor
|
||||
* and associated properties.
|
||||
* </p>
|
||||
*/
|
||||
public class MTable {
|
||||
|
||||
/**
|
||||
* Flag set to indicate
|
||||
*/
|
||||
private boolean matched;
|
||||
|
||||
private final String name;
|
||||
|
||||
private String remarks;
|
||||
|
||||
private String tablespace;
|
||||
|
||||
private String indexTablespace;
|
||||
|
||||
private Boolean withHistory;
|
||||
|
||||
private Map<String,MColumn> columns = new LinkedHashMap<String,MColumn>();
|
||||
|
||||
private List<MCompoundUniqueConstraint> compoundUniqueConstraints = new ArrayList<MCompoundUniqueConstraint>();
|
||||
|
||||
private List<MCompoundForeignKey> compoundKeys = new ArrayList<MCompoundForeignKey>();
|
||||
/**
|
||||
* Construct for migration.
|
||||
*/
|
||||
public MTable(CreateTable createTable) {
|
||||
this.name = createTable.getName();
|
||||
this.remarks = createTable.getRemarks();
|
||||
this.tablespace = createTable.getTablespace();
|
||||
this.indexTablespace = createTable.getIndexTablespace();
|
||||
this.withHistory = createTable.isWithHistory();
|
||||
List<Column> cols = createTable.getColumn();
|
||||
for (Column column : cols) {
|
||||
addColumn(column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct typically from EbeanServer meta data.
|
||||
*/
|
||||
public MTable(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public CreateTable createTable() {
|
||||
|
||||
CreateTable createTable = new CreateTable();
|
||||
createTable.setName(name);
|
||||
createTable.setRemarks(remarks);
|
||||
createTable.setTablespace(tablespace);
|
||||
createTable.setIndexTablespace(indexTablespace);
|
||||
createTable.setWithHistory(withHistory);
|
||||
|
||||
for (MColumn column : this.columns.values()) {
|
||||
createTable.getColumn().add(column.createColumn());
|
||||
}
|
||||
return createTable;
|
||||
}
|
||||
|
||||
public boolean isMatched() {
|
||||
return matched;
|
||||
}
|
||||
|
||||
public void setMatched(boolean matched) {
|
||||
this.matched = matched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply AddColumn migration.
|
||||
*/
|
||||
public void apply(AddColumn addColumn) {
|
||||
checkTableName(addColumn.getTableName());
|
||||
for (Column column : addColumn.getColumn()) {
|
||||
addColumn(column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply DropColumn migration.
|
||||
*/
|
||||
public void apply(DropColumn dropColumn) {
|
||||
checkTableName(dropColumn.getTableName());
|
||||
columns.remove(dropColumn.getColumnName());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getRemarks() {
|
||||
return remarks;
|
||||
}
|
||||
|
||||
public String getTablespace() {
|
||||
return tablespace;
|
||||
}
|
||||
|
||||
public String getIndexTablespace() {
|
||||
return indexTablespace;
|
||||
}
|
||||
|
||||
public Boolean getWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
public Map<String, MColumn> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public List<MCompoundUniqueConstraint> getCompoundUniqueConstraints() {
|
||||
return compoundUniqueConstraints;
|
||||
}
|
||||
|
||||
public List<MCompoundForeignKey> getCompoundKeys() {
|
||||
return compoundKeys;
|
||||
}
|
||||
|
||||
private void checkTableName(String tableName) {
|
||||
if (!name.equals(tableName)) {
|
||||
throw new IllegalArgumentException("addColumn tableName ["+tableName+"] does not match ["+name+"]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column via migration data.
|
||||
*/
|
||||
private void addColumn(Column column) {
|
||||
columns.put(column.getName(), new MColumn(column));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a model column (typically from EbeanServer meta data).
|
||||
*/
|
||||
public void addColumn(MColumn column) {
|
||||
columns.put(column.getName(), column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a compound unique constraint.
|
||||
*/
|
||||
public void addCompoundUniqueConstraint(String[] columns) {
|
||||
compoundUniqueConstraints.add(new MCompoundUniqueConstraint(columns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a compound unique constraint.
|
||||
*/
|
||||
public void addCompoundUniqueConstraint(List<MColumn> columns) {
|
||||
String[] cols = new String[columns.size()];
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
cols[i] = columns.get(i).getName();
|
||||
}
|
||||
addCompoundUniqueConstraint(cols);
|
||||
}
|
||||
|
||||
public void addForeignKey(MCompoundForeignKey compoundKey) {
|
||||
compoundKeys.add(compoundKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import com.avaje.ebean.dbmigration.migration.AddColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.ChangeSet;
|
||||
import com.avaje.ebean.dbmigration.migration.CreateTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropColumn;
|
||||
import com.avaje.ebean.dbmigration.migration.Migration;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Holds all the tables, views, indexes etc that represent the model.
|
||||
* <p>
|
||||
* Migration changeSets can be applied to the model.
|
||||
* </p>
|
||||
*/
|
||||
public class ModelContainer {
|
||||
|
||||
/**
|
||||
* All the tables in the model.
|
||||
*/
|
||||
private Map<String, MTable> tables = new LinkedHashMap<String, MTable>();
|
||||
|
||||
|
||||
/**
|
||||
* Return the map of all the tables.
|
||||
*/
|
||||
public Map<String, MTable> getTables() {
|
||||
return tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the table by name.
|
||||
*/
|
||||
public MTable getTable(String tableName) {
|
||||
return tables.get(tableName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply a migration with associated changeSets to the model.
|
||||
*/
|
||||
public void apply(Migration migration) {
|
||||
|
||||
List<ChangeSet> changeSets = migration.getChangeSet();
|
||||
for (ChangeSet changeSet : changeSets) {
|
||||
applyChangeSet(changeSet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a changeSet to the model.
|
||||
*/
|
||||
protected void applyChangeSet(ChangeSet changeSet) {
|
||||
|
||||
List<Object> changeSetChildren = changeSet.getChangeSetChildren();
|
||||
for (Object change : changeSetChildren) {
|
||||
if (change instanceof CreateTable) {
|
||||
applyChange((CreateTable) change);
|
||||
} else if (change instanceof AddColumn) {
|
||||
applyChange((AddColumn) change);
|
||||
} else if (change instanceof DropColumn) {
|
||||
applyChange((DropColumn) change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a CreateTable change to the model.
|
||||
*/
|
||||
protected void applyChange(CreateTable createTable) {
|
||||
String tableName = createTable.getName();
|
||||
if (tables.containsKey(tableName)) {
|
||||
throw new IllegalStateException("Table [" + tableName + "] already exists?");
|
||||
}
|
||||
MTable table = new MTable(createTable);
|
||||
tables.put(tableName, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a AddColumn change to the model.
|
||||
*/
|
||||
protected void applyChange(AddColumn addColumn) {
|
||||
MTable table = tables.get(addColumn.getTableName());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("Table [" + addColumn.getTableName() + "] does not exist?");
|
||||
}
|
||||
table.apply(addColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a DropColumn change to the model.
|
||||
*/
|
||||
protected void applyChange(DropColumn dropColumn) {
|
||||
MTable table = tables.get(dropColumn.getTableName());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("Table [" + dropColumn.getTableName() + "] does not exist?");
|
||||
}
|
||||
table.apply(dropColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a table (typically from reading EbeanServer meta data).
|
||||
*/
|
||||
public void addTable(MTable table) {
|
||||
tables.put(table.getName(), table);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.avaje.ebean.dbmigration.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Used to prepare a diff in terms of changes required to migrate from
|
||||
* the base model to the newer model.
|
||||
*/
|
||||
public class ModelDiff {
|
||||
|
||||
/**
|
||||
* The base model to which we compare the newer model.
|
||||
*/
|
||||
protected final ModelContainer baseModel;
|
||||
|
||||
/**
|
||||
* List of 'create' type changes.
|
||||
*/
|
||||
protected final List<Object> createChanges = new ArrayList<Object>();
|
||||
|
||||
/**
|
||||
* List of 'drop' type changes. Potential for putting into a separate changeSet.
|
||||
*/
|
||||
protected final List<Object> dropChanges = new ArrayList<Object>();
|
||||
|
||||
/**
|
||||
* Construct with a base model.
|
||||
*/
|
||||
public ModelDiff(ModelContainer baseModel) {
|
||||
this.baseModel = baseModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a base model.
|
||||
*/
|
||||
public ModelDiff() {
|
||||
this.baseModel = new ModelContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of 'create' changes.
|
||||
*/
|
||||
public List<Object> getCreateChanges() {
|
||||
return createChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of 'drop' changes.
|
||||
*/
|
||||
public List<Object> getDropChanges() {
|
||||
return dropChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a 'newer' model and collect the differences.
|
||||
*/
|
||||
public void compareTo(ModelContainer newModel) {
|
||||
|
||||
for (MTable newTable : newModel.getTables().values()) {
|
||||
|
||||
MTable currentTable = baseModel.getTable(newTable.getName());
|
||||
if (currentTable == null) {
|
||||
addNewTable(newTable);
|
||||
} else {
|
||||
compareTables(currentTable, newTable);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: other parts of the model? views, indexes etc
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add CreateTable to the 'creation' changes.
|
||||
*/
|
||||
protected void addNewTable(MTable newTable) {
|
||||
|
||||
createChanges.add(newTable.createTable());
|
||||
// createChanges.add(newTable.createForeignKeys());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare tables looking for add/drop/modify columns etc.
|
||||
*/
|
||||
protected void compareTables(MTable currentTable, MTable newTable) {
|
||||
|
||||
//TODO: compareTables()
|
||||
// changed columns
|
||||
// find additional columns
|
||||
// find removed columns
|
||||
// changes to indexes?
|
||||
// changes to primary key
|
||||
// changes to foreign key
|
||||
// changes to unique constraints?
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.avaje.ebean.dbmigration.model.build;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.CompoundUniqueContraint;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.ebean.dbmigration.model.MColumn;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.BeanPropertyVisitor;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.BeanVisitor;
|
||||
|
||||
/**
|
||||
* Used to build the Model objects MTable etc.
|
||||
*/
|
||||
public class ModelBuildBeanVisitor implements BeanVisitor {
|
||||
|
||||
private final ModelBuildContext ctx;
|
||||
|
||||
public ModelBuildBeanVisitor(ModelBuildContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the PropertyVisitor used to read all the property meta data
|
||||
* and in this case add MColumn objects to the model.
|
||||
* <p>
|
||||
* This creates an MTable and adds it to the model.
|
||||
* </p>
|
||||
*/
|
||||
public BeanPropertyVisitor visitBean(BeanDescriptor<?> descriptor) {
|
||||
|
||||
if (!descriptor.isInheritanceRoot()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MTable table = new MTable(descriptor.getBaseTable());
|
||||
|
||||
// add the table to the model
|
||||
ctx.addTable(table);
|
||||
|
||||
InheritInfo inheritInfo = descriptor.getInheritInfo();
|
||||
if (inheritInfo != null && inheritInfo.isRoot()) {
|
||||
// add the discriminator column
|
||||
String discColumn = inheritInfo.getDiscriminatorColumn();
|
||||
DbType dbType = ctx.getDbTypeMap().get(inheritInfo.getDiscriminatorType());
|
||||
String discDbType = dbType.renderType(inheritInfo.getDiscriminatorLength(), 0);
|
||||
|
||||
table.addColumn(new MColumn(discColumn, discDbType, true));
|
||||
}
|
||||
|
||||
CompoundUniqueContraint[] compoundUniqueConstraints = descriptor.getCompoundUniqueConstraints();
|
||||
if (compoundUniqueConstraints != null) {
|
||||
for (int i = 0; i < compoundUniqueConstraints.length; i++) {
|
||||
table.addCompoundUniqueConstraint(compoundUniqueConstraints[i].getColumns());
|
||||
}
|
||||
}
|
||||
|
||||
return new ModelBuildPropertyVisitor(ctx, table);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.avaje.ebean.dbmigration.model.build;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.config.dbplatform.DbTypeMap;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.ModelContainer;
|
||||
|
||||
/**
|
||||
* The context used during DDL generation.
|
||||
*/
|
||||
public class ModelBuildContext {
|
||||
|
||||
/**
|
||||
* Use platform agnostic logical types. These types are converted to
|
||||
* platform specific types in the DDL generation.
|
||||
*/
|
||||
private final DbTypeMap dbTypeMap = DbTypeMap.logicalTypes();
|
||||
|
||||
private final ModelContainer model;
|
||||
|
||||
public ModelBuildContext(ModelContainer model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void addTable(MTable table) {
|
||||
model.addTable(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the map used to determine the DB specific type
|
||||
* for a given bean property.
|
||||
*/
|
||||
public DbTypeMap getDbTypeMap() {
|
||||
return dbTypeMap;
|
||||
}
|
||||
|
||||
|
||||
public String getColumnDefn(BeanProperty p) {
|
||||
DbType dbType = getDbType(p);
|
||||
if (dbType == null) {
|
||||
throw new IllegalStateException("Unknown DbType mapping for " + p.getFullBeanName());
|
||||
}
|
||||
return p.renderDbType(dbType);
|
||||
}
|
||||
|
||||
private DbType getDbType(BeanProperty p) {
|
||||
|
||||
if (p.isDbEncrypted()) {
|
||||
return dbTypeMap.get(p.getDbEncryptedType());
|
||||
}
|
||||
|
||||
int dbType = p.getDbType();
|
||||
if (dbType == 0) {
|
||||
// ScalarType<Object> scalarType = p.getScalarType();
|
||||
// if (scalarType == null) {
|
||||
throw new RuntimeException("No scalarType for " + p.getFullBeanName());
|
||||
// }
|
||||
// dbType = scalarType.getJdbcType();
|
||||
}
|
||||
return dbTypeMap.get(dbType);
|
||||
}
|
||||
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
package com.avaje.ebean.dbmigration.model.build;
|
||||
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.TableJoin;
|
||||
import com.avaje.ebeaninternal.server.deploy.TableJoinColumn;
|
||||
import com.avaje.ebean.dbmigration.model.MColumn;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
|
||||
|
||||
/**
|
||||
* Add the intersection table to the model.
|
||||
*/
|
||||
public class ModelBuildIntersectionTable {
|
||||
|
||||
private final ModelBuildContext ctx;
|
||||
|
||||
private final BeanPropertyAssocMany<?> manyProp;
|
||||
private final TableJoin intersectionTableJoin;
|
||||
private final TableJoin tableJoin;
|
||||
|
||||
public ModelBuildIntersectionTable(ModelBuildContext ctx, BeanPropertyAssocMany<?> manyProp) {
|
||||
this.ctx = ctx;
|
||||
this.manyProp = manyProp;
|
||||
this.intersectionTableJoin = manyProp.getIntersectionTableJoin();
|
||||
this.tableJoin = manyProp.getTableJoin();
|
||||
}
|
||||
|
||||
public void build() {
|
||||
|
||||
MTable table = createTable();
|
||||
ctx.addTable(table);
|
||||
|
||||
//buildFkConstraints();
|
||||
}
|
||||
|
||||
// private void buildFkConstraints(MTable table) {
|
||||
//
|
||||
// BeanDescriptor<?> localDesc = manyProp.getBeanDescriptor();
|
||||
// String fk1 = buildFkConstraints(localDesc, intersectionTableJoin.columns(), true);
|
||||
// ctx.addIntersectionTableFk(fk1);
|
||||
//
|
||||
// BeanDescriptor<?> targetDesc = manyProp.getTargetDescriptor();
|
||||
// String fk2 = buildFkConstraints(targetDesc, tableJoin.columns(), false);
|
||||
// ctx.addIntersectionTableFk(fk2);
|
||||
// }
|
||||
|
||||
|
||||
// private String buildFkConstraints(BeanDescriptor<?> desc, TableJoinColumn[] columns, boolean direction) {
|
||||
//
|
||||
//
|
||||
// String fkName = "fk_"+intersectionTableJoin.getTable()+"_"+desc.getBaseTable();
|
||||
//
|
||||
// fkName = getFkNameWithSuffix(fkName);
|
||||
//
|
||||
// fkBuf.append("alter table ");
|
||||
// fkBuf.append(intersectionTableJoin.getTable());
|
||||
// fkBuf.append(" add constraint ").append(fkName);
|
||||
//
|
||||
// fkBuf.append(" foreign key (");
|
||||
//
|
||||
// for (int i = 0; i < columns.length; i++) {
|
||||
// if (i > 0) {
|
||||
// fkBuf.append(", ");
|
||||
// }
|
||||
// String col = direction ? columns[i].getForeignDbColumn() : columns[i].getLocalDbColumn();
|
||||
// fkBuf.append(col);
|
||||
// }
|
||||
// fkBuf.append(") references ").append(desc.getBaseTable()).append(" (");
|
||||
//
|
||||
// for (int i = 0; i < columns.length; i++) {
|
||||
// if (i > 0) {
|
||||
// fkBuf.append(", ");
|
||||
// }
|
||||
// String col = !direction ? columns[i].getForeignDbColumn() : columns[i].getLocalDbColumn();
|
||||
// fkBuf.append(col);
|
||||
// }
|
||||
// fkBuf.append(")");
|
||||
//
|
||||
// String fkeySuffix = ctx.getDdlSyntax().getForeignKeySuffix();
|
||||
// if (fkeySuffix != null){
|
||||
// fkBuf.append(" ");
|
||||
// fkBuf.append(fkeySuffix);
|
||||
// }
|
||||
// fkBuf.append(";").append(NEW_LINE);
|
||||
//
|
||||
// return fkBuf.toString();
|
||||
// }
|
||||
|
||||
private MTable createTable() {
|
||||
|
||||
BeanDescriptor<?> localDesc = manyProp.getBeanDescriptor();
|
||||
BeanDescriptor<?> targetDesc = manyProp.getTargetDescriptor();
|
||||
|
||||
MTable table = new MTable(intersectionTableJoin.getTable());
|
||||
|
||||
TableJoinColumn[] columns = intersectionTableJoin.columns();
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
addColumn(table, localDesc, columns[i].getForeignDbColumn(), columns[i].getLocalDbColumn());
|
||||
}
|
||||
|
||||
TableJoinColumn[] otherColumns = tableJoin.columns();
|
||||
for (int i = 0; i < otherColumns.length; i++) {
|
||||
addColumn(table, targetDesc, otherColumns[i].getLocalDbColumn(), otherColumns[i].getForeignDbColumn());
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private void addColumn(MTable table, BeanDescriptor<?> desc, String column, String findPropColumn) {
|
||||
|
||||
BeanProperty p = desc.getIdBinder().findBeanProperty(findPropColumn);
|
||||
if (p == null) {
|
||||
throw new RuntimeException("Could not find id property for " + findPropColumn);
|
||||
}
|
||||
|
||||
MColumn col = new MColumn(column, ctx.getColumnDefn(p), true);
|
||||
col.setPrimaryKey(true);
|
||||
|
||||
table.addColumn(col);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.avaje.ebean.dbmigration.model.build;
|
||||
|
||||
import com.avaje.ebean.dbmigration.model.MCompoundForeignKey;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound;
|
||||
import com.avaje.ebeaninternal.server.deploy.TableJoinColumn;
|
||||
import com.avaje.ebeaninternal.server.deploy.id.ImportedId;
|
||||
import com.avaje.ebean.dbmigration.model.MColumn;
|
||||
import com.avaje.ebean.dbmigration.model.MTable;
|
||||
import com.avaje.ebean.dbmigration.model.visitor.BaseTablePropertyVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Used as part of ModelBuildBeanVisitor and generally adds the MColumn to the associated
|
||||
* MTable model objects.
|
||||
*/
|
||||
public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
|
||||
private final ModelBuildContext ctx;
|
||||
|
||||
private final MTable table;
|
||||
|
||||
public ModelBuildPropertyVisitor(ModelBuildContext ctx, MTable table) {
|
||||
this.ctx = ctx;
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMany(BeanPropertyAssocMany<?> p) {
|
||||
if (p.isManyToMany()) {
|
||||
if (p.getMappedBy() == null) {
|
||||
// only create on other 'owning' side
|
||||
|
||||
//TableJoin intersectionTableJoin = p.getIntersectionTableJoin();
|
||||
// check if the intersection table has already been created
|
||||
|
||||
// build the create table and fkey constraints
|
||||
// putting the DDL into ctx for later output as we are
|
||||
// in the middle of rendering the create table DDL
|
||||
new ModelBuildIntersectionTable(ctx, p).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p) {
|
||||
visitScalar(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCompound(BeanPropertyCompound p) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne<?> embedded) {
|
||||
|
||||
//this.embedded = embedded;
|
||||
visitScalar(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOneImported(BeanPropertyAssocOne<?> p) {
|
||||
|
||||
TableJoinColumn[] columns = p.getTableJoin().columns();
|
||||
if (columns.length == 0) {
|
||||
String msg = "No join columns for " + p.getFullBeanName();
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
|
||||
ImportedId importedId = p.getImportedId();
|
||||
|
||||
List<MColumn> modelColumns = new ArrayList<MColumn>(columns.length);
|
||||
|
||||
MCompoundForeignKey compoundKey = null;
|
||||
if (columns.length > 1) {
|
||||
// compound foreign key
|
||||
String refTable = p.getTargetDescriptor().getBaseTable();
|
||||
compoundKey = new MCompoundForeignKey(refTable);
|
||||
table.addForeignKey(compoundKey);
|
||||
}
|
||||
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
|
||||
String dbCol = columns[i].getLocalDbColumn();
|
||||
BeanProperty importedProperty = importedId.findMatchImport(dbCol);
|
||||
if (importedProperty == null) {
|
||||
throw new RuntimeException("Imported BeanProperty not found?");
|
||||
}
|
||||
String columnDefn = ctx.getColumnDefn(importedProperty);
|
||||
String refColumn = importedProperty.getDbColumn();
|
||||
|
||||
MColumn col = new MColumn(dbCol, columnDefn, !p.isNullable());
|
||||
if (columns.length == 1) {
|
||||
// single references column (put it on the column)
|
||||
String refTable = importedProperty.getBeanDescriptor().getBaseTable();
|
||||
col.setReferences(refTable + "." + refColumn);
|
||||
} else {
|
||||
compoundKey.addColumnPair(dbCol, refColumn);
|
||||
}
|
||||
modelColumns.add(col);
|
||||
table.addColumn(col);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (p.isOneToOne()) {
|
||||
// Adding the unique constraint restricts the cardinality from OneToMany down to OneToOne
|
||||
if (modelColumns.size() == 1) {
|
||||
modelColumns.get(0).setUnique(true);
|
||||
} else {
|
||||
table.addCompoundUniqueConstraint(modelColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitScalar(BeanProperty p) {
|
||||
|
||||
if (p.isSecondaryTable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MColumn col = new MColumn(p.getDbColumn(), ctx.getColumnDefn(p));
|
||||
|
||||
if (p.isId()){
|
||||
col.setPrimaryKey(true);
|
||||
if (p.getBeanDescriptor().isUseIdGenerator()) {
|
||||
col.setIdentity(true);
|
||||
}
|
||||
} else if (!p.isNullable() || p.isDDLNotNull()) {
|
||||
col.setNotnull(true);
|
||||
}
|
||||
|
||||
if (p.isUnique() && !p.isId()) {
|
||||
col.setUnique(true);
|
||||
}
|
||||
col.setCheckConstraint(p.getDbConstraintExpression());
|
||||
|
||||
table.addColumn(col);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.avaje.ebean.dbmigration.model.visitor;
|
||||
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound;
|
||||
|
||||
/**
|
||||
* Used to help mark PropertyVisitor methods that need to be implemented
|
||||
* to visit base table properties.
|
||||
*/
|
||||
public abstract class BaseTablePropertyVisitor implements BeanPropertyVisitor {
|
||||
|
||||
/**
|
||||
* Not required in that you can use the visitEmbeddedScalar.
|
||||
*/
|
||||
public void visitEmbedded(BeanPropertyAssocOne<?> p) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method.
|
||||
*/
|
||||
public abstract void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne<?> embedded);
|
||||
|
||||
/**
|
||||
* Not part of base table.
|
||||
*/
|
||||
public void visitMany(BeanPropertyAssocMany<?> p) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not part of base table.
|
||||
*/
|
||||
public void visitOneExported(BeanPropertyAssocOne<?> p) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method for the foreign key.
|
||||
*/
|
||||
public abstract void visitOneImported(BeanPropertyAssocOne<?> p);
|
||||
|
||||
/**
|
||||
* Override this method for normal scalar property.
|
||||
*/
|
||||
public abstract void visitScalar(BeanProperty p);
|
||||
|
||||
/**
|
||||
* Not required in that the scalar properties map to the columns.
|
||||
*/
|
||||
public void visitCompound(BeanPropertyCompound p) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method for scalar property inside a Immutable Compound Value object.
|
||||
*/
|
||||
public abstract void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.avaje.ebean.dbmigration.model.visitor;
|
||||
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound;
|
||||
|
||||
/**
|
||||
* Used to visit a BeanProperty given the type of bean property it is.
|
||||
*/
|
||||
public interface BeanPropertyVisitor {
|
||||
|
||||
/**
|
||||
* Visit a OneToMany or ManyToMany property.
|
||||
*/
|
||||
void visitMany(BeanPropertyAssocMany<?> p);
|
||||
|
||||
/**
|
||||
* Visit the imported side of a OneToOne property.
|
||||
*/
|
||||
void visitOneImported(BeanPropertyAssocOne<?> p);
|
||||
|
||||
/**
|
||||
* Visit the exported side of a OneToOne property.
|
||||
*/
|
||||
void visitOneExported(BeanPropertyAssocOne<?> p);
|
||||
|
||||
/**
|
||||
* Visit an embedded property.
|
||||
*/
|
||||
void visitEmbedded(BeanPropertyAssocOne<?> p);
|
||||
|
||||
/**
|
||||
* Visit the scalar property of an embedded bean.
|
||||
*/
|
||||
void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne<?> embedded);
|
||||
|
||||
/**
|
||||
* Visit a scalar property.
|
||||
*/
|
||||
void visitScalar(BeanProperty p);
|
||||
|
||||
/**
|
||||
* Visit a compound value object.
|
||||
*/
|
||||
void visitCompound(BeanPropertyCompound p);
|
||||
|
||||
/**
|
||||
* Visit the scalar value inside a compound value object.
|
||||
*/
|
||||
void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.avaje.ebean.dbmigration.model.visitor;
|
||||
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
/**
|
||||
* Visitor pattern for visiting a BeanDescriptor and potentially all its bean
|
||||
* properties.
|
||||
*/
|
||||
public interface BeanVisitor {
|
||||
|
||||
/**
|
||||
* Visit a BeanDescriptor and return a PropertyVisitor to use to visit each
|
||||
* property on the entity bean (return null to skip visiting this bean).
|
||||
*/
|
||||
BeanPropertyVisitor visitBean(BeanDescriptor<?> descriptor);
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.avaje.ebean.dbmigration.model.visitor;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfoVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Makes use of BeanVisitor and PropertyVisitor to navigate BeanDescriptors
|
||||
* and their properties.
|
||||
*/
|
||||
public class VisitAllUsing {
|
||||
|
||||
protected final BeanVisitor visitor;
|
||||
|
||||
protected final List<BeanDescriptor<?>> descriptors;
|
||||
|
||||
/**
|
||||
* Visit all the descriptors for a given server.
|
||||
*/
|
||||
public VisitAllUsing(BeanVisitor visitor, SpiEbeanServer server) {
|
||||
|
||||
this(visitor, server.getBeanDescriptors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit all the descriptors in the list.
|
||||
*/
|
||||
public VisitAllUsing(BeanVisitor visitor, List<BeanDescriptor<?>> descriptors) {
|
||||
this.visitor = visitor;
|
||||
this.descriptors = descriptors;
|
||||
}
|
||||
|
||||
public void visitAllBeans() {
|
||||
for (BeanDescriptor<?> desc : descriptors) {
|
||||
if (desc.getBaseTable() != null) {
|
||||
visitBean(desc, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit the bean using a visitor.
|
||||
*/
|
||||
protected void visitBean(BeanDescriptor<?> desc, BeanVisitor visitor) {
|
||||
|
||||
BeanPropertyVisitor propertyVisitor = visitor.visitBean(desc);
|
||||
if (propertyVisitor != null) {
|
||||
|
||||
BeanProperty idProp = desc.getIdProperty();
|
||||
if (idProp != null) {
|
||||
visit(propertyVisitor, idProp);
|
||||
}
|
||||
|
||||
BeanPropertyAssocOne<?> unidirectional = desc.getUnidirectional();
|
||||
if (unidirectional != null) {
|
||||
visit(propertyVisitor, unidirectional);
|
||||
}
|
||||
|
||||
BeanProperty[] propertiesNonTransient = desc.propertiesNonTransient();
|
||||
for (int i = 0; i < propertiesNonTransient.length; i++) {
|
||||
BeanProperty p = propertiesNonTransient[i];
|
||||
if (!p.isFormula() && !p.isSecondaryTable()) {
|
||||
visit(propertyVisitor, p);
|
||||
}
|
||||
}
|
||||
|
||||
visitInheritanceProperties(desc, propertyVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit the property.
|
||||
*/
|
||||
protected void visit(BeanPropertyVisitor pv, BeanProperty p) {
|
||||
|
||||
if (p instanceof BeanPropertyAssocMany<?>) {
|
||||
// oneToMany or manyToMany
|
||||
pv.visitMany((BeanPropertyAssocMany<?>) p);
|
||||
|
||||
} else if (p instanceof BeanPropertyAssocOne<?>) {
|
||||
BeanPropertyAssocOne<?> assocOne = (BeanPropertyAssocOne<?>) p;
|
||||
if (assocOne.isEmbedded()) {
|
||||
// Embedded bean
|
||||
pv.visitEmbedded(assocOne);
|
||||
BeanProperty[] embProps = assocOne.getProperties();
|
||||
for (int i = 0; i < embProps.length; i++) {
|
||||
pv.visitEmbeddedScalar(embProps[i], assocOne);
|
||||
}
|
||||
|
||||
} else if (assocOne.isOneToOneExported()) {
|
||||
// associated one exported
|
||||
pv.visitOneExported(assocOne);
|
||||
|
||||
} else {
|
||||
// associated one imported
|
||||
pv.visitOneImported(assocOne);
|
||||
}
|
||||
|
||||
} else if (p instanceof BeanPropertyCompound) {
|
||||
// compound type
|
||||
BeanPropertyCompound compound = (BeanPropertyCompound) p;
|
||||
pv.visitCompound(compound);
|
||||
|
||||
BeanProperty[] properties = compound.getScalarProperties();
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
pv.visitCompoundScalar(compound, properties[i]);
|
||||
}
|
||||
|
||||
} else {
|
||||
// simple scalar type
|
||||
pv.visitScalar(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visit all the other inheritance properties that are not on the root.
|
||||
*/
|
||||
protected void visitInheritanceProperties(BeanDescriptor<?> descriptor, BeanPropertyVisitor pv) {
|
||||
|
||||
InheritInfo inheritInfo = descriptor.getInheritInfo();
|
||||
if (inheritInfo != null && inheritInfo.isRoot()) {
|
||||
// add all properties on the children objects
|
||||
InheritChildVisitor childVisitor = new InheritChildVisitor(this, pv);
|
||||
inheritInfo.visitChildren(childVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper used to visit all the inheritInfo/BeanDescriptor in
|
||||
* the inheritance hierarchy (to add their 'local' properties).
|
||||
*/
|
||||
protected class InheritChildVisitor implements InheritInfoVisitor {
|
||||
|
||||
private final VisitAllUsing owner;
|
||||
private final BeanPropertyVisitor pv;
|
||||
|
||||
protected InheritChildVisitor(VisitAllUsing owner, BeanPropertyVisitor pv) {
|
||||
this.owner = owner;
|
||||
this.pv = pv;
|
||||
}
|
||||
|
||||
public void visit(InheritInfo inheritInfo) {
|
||||
BeanProperty[] propertiesLocal = inheritInfo.getBeanDescriptor().propertiesLocal();
|
||||
for (int i = 0; i <propertiesLocal.length ; i++) {
|
||||
owner.visit(pv, propertiesLocal[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import java.util.List;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.dbmigration.model.CurrentModel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -39,6 +40,7 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
private boolean generateDdl;
|
||||
private boolean runDdl;
|
||||
|
||||
private CurrentModel currentModel;
|
||||
private String dropContent;
|
||||
private String createContent;
|
||||
|
||||
@@ -70,6 +72,10 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
if (generateDdl) {
|
||||
writeDrop(getDropFileName());
|
||||
writeCreate(getCreateFileName());
|
||||
|
||||
String mn = server.getName() + "-migration.xml";
|
||||
File migrationXml = new File(mn);
|
||||
writeMigration(migrationXml);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,44 +128,60 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
|
||||
public String generateDropDdl() {
|
||||
|
||||
DdlGenContext ctx = createContext();
|
||||
|
||||
if (ctx.getDdlSyntax().isDropKeyConstraints()) {
|
||||
// generate drop foreign key constraint statements (sql server joy)
|
||||
AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(false, ctx);
|
||||
VisitorUtil.visit(server, fkeys);
|
||||
ctx.writeNewLine();
|
||||
try {
|
||||
dropContent = currentModel().getDropDdl();
|
||||
return dropContent;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// DdlGenContext ctx = createContext();
|
||||
//
|
||||
// if (ctx.getDdlSyntax().isDropKeyConstraints()) {
|
||||
// // generate drop foreign key constraint statements (sql server joy)
|
||||
// AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(false, ctx);
|
||||
// VisitorUtil.visit(server, fkeys);
|
||||
// ctx.writeNewLine();
|
||||
// }
|
||||
//
|
||||
// DropTableVisitor drop = new DropTableVisitor(ctx);
|
||||
// VisitorUtil.visit(server, drop);
|
||||
//
|
||||
// DropSequenceVisitor dropSequence = new DropSequenceVisitor(ctx);
|
||||
// VisitorUtil.visit(server, dropSequence);
|
||||
//
|
||||
// ctx.flush();
|
||||
// dropContent = ctx.getContent();
|
||||
// return dropContent;
|
||||
}
|
||||
public void writeMigration(File file) {
|
||||
|
||||
DropTableVisitor drop = new DropTableVisitor(ctx);
|
||||
VisitorUtil.visit(server, drop);
|
||||
|
||||
DropSequenceVisitor dropSequence = new DropSequenceVisitor(ctx);
|
||||
VisitorUtil.visit(server, dropSequence);
|
||||
|
||||
ctx.flush();
|
||||
dropContent = ctx.getContent();
|
||||
return dropContent;
|
||||
currentModel().writeMigration(file);
|
||||
}
|
||||
|
||||
public String generateCreateDdl() {
|
||||
|
||||
DdlGenContext ctx = createContext();
|
||||
CreateTableVisitor create = new CreateTableVisitor(ctx);
|
||||
VisitorUtil.visit(server, create);
|
||||
|
||||
CreateSequenceVisitor createSequence = new CreateSequenceVisitor(ctx);
|
||||
VisitorUtil.visit(server, createSequence);
|
||||
|
||||
AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(true, ctx);
|
||||
VisitorUtil.visit(server, fkeys);
|
||||
|
||||
CreateIndexVisitor indexes = new CreateIndexVisitor(ctx);
|
||||
VisitorUtil.visit(server, indexes);
|
||||
|
||||
ctx.flush();
|
||||
createContent = ctx.getContent();
|
||||
return createContent;
|
||||
try {
|
||||
createContent = currentModel().getCreateDdl();
|
||||
return createContent;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// DdlGenContext ctx = createContext();
|
||||
// CreateTableVisitor create = new CreateTableVisitor(ctx);
|
||||
// VisitorUtil.visit(server, create);
|
||||
//
|
||||
// CreateSequenceVisitor createSequence = new CreateSequenceVisitor(ctx);
|
||||
// VisitorUtil.visit(server, createSequence);
|
||||
//
|
||||
// AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(true, ctx);
|
||||
// VisitorUtil.visit(server, fkeys);
|
||||
//
|
||||
// CreateIndexVisitor indexes = new CreateIndexVisitor(ctx);
|
||||
// VisitorUtil.visit(server, indexes);
|
||||
//
|
||||
// ctx.flush();
|
||||
// createContent = ctx.getContent();
|
||||
// return createContent;
|
||||
}
|
||||
|
||||
protected String getDropFileName() {
|
||||
@@ -174,6 +196,15 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
return new DdlGenContext(dbPlatform, namingConvention);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected CurrentModel currentModel() {
|
||||
if (currentModel == null) {
|
||||
currentModel = new CurrentModel(server);
|
||||
}
|
||||
return currentModel;
|
||||
}
|
||||
|
||||
protected void writeFile(String fileName, String fileContent) throws IOException {
|
||||
|
||||
File f = new File(fileName);
|
||||
@@ -199,7 +230,7 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
FileReader fr = new FileReader(f);
|
||||
LineNumberReader lr = new LineNumberReader(fr);
|
||||
try {
|
||||
String s = null;
|
||||
String s;
|
||||
while ((s = lr.readLine()) != null) {
|
||||
buf.append(s).append("\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user