NEU: Db2 Tablespaces (#59)

* first commit

* second commit, it works for db2

* create table index in TS

* IndexTS & runPlacholdersMap

* Zwischencommit

* Implemented Tablespaces

* Update PR

* Zwischencommit

* release.md

* add lobTablespace support

* ebean-annotation 7.7

* create index in TS ausgebaut

* Fix Mergekonflikte

* Migrationsskripte neu generiert

* Revert "Migrationsskripte neu generiert"

This reverts commit 2690718b92701c0f34661d309c129b97e3cbe053.

* Revert "Fix Mergekonflikte"

This reverts commit e073e25048af88205259fd6b0873c4227b27d205.

* revert merge commit

* Resolved merge commits

* FIX: More merge conflicts and compile errors

* FIX: platform.base problem

* tableName uppercase

* Reviewkommentare Teil 1

* Reviewkommentare Teil 2

* DbMigrationTest für DB2 gefixt

* revert whitespaces

* Review

* review

Co-authored-by: Roland Praml <roland.praml@foconis.de>
This commit is contained in:
NSzemenyeiandRoland Praml authored and GitHub committed 2022-02-04 13:04:34 +01:00
1 parent 09230924f7
commit 4fe6f0cb13
41 files changed
+996 -42

No files matched your search

@@ -9,6 +9,7 @@ import io.ebeaninternal.dbmigration.migration.AddTableComment;
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
import io.ebeaninternal.dbmigration.migration.AlterTable;
import io.ebeaninternal.dbmigration.migration.ChangeSet;
import io.ebeaninternal.dbmigration.migration.CreateIndex;
import io.ebeaninternal.dbmigration.migration.CreateTable;
@@ -49,6 +50,8 @@ public class BaseDdlHandler implements DdlHandler {
// ignore
} else if (change instanceof DropTable) {
generate(writer, (DropTable) change);
} else if (change instanceof AlterTable) {
generate(writer, (AlterTable) change);
} else if (change instanceof AddTableComment) {
generate(writer, (AddTableComment) change);
} else if (change instanceof CreateIndex) {
@@ -94,6 +97,11 @@ public class BaseDdlHandler implements DdlHandler {
public void generate(DdlWrite writer, DropTable dropTable) throws IOException {
tableDdl.generate(writer, dropTable);
}
@Override
public void generate(DdlWrite writer, AlterTable alterTable) throws IOException {
tableDdl.generate(writer, alterTable);
}
@Override
public void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException {
@@ -6,6 +6,7 @@ import io.ebeaninternal.dbmigration.migration.AddTableComment;
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
import io.ebeaninternal.dbmigration.migration.AlterTable;
import io.ebeaninternal.dbmigration.migration.ChangeSet;
import io.ebeaninternal.dbmigration.migration.CreateIndex;
import io.ebeaninternal.dbmigration.migration.CreateTable;
@@ -26,6 +27,8 @@ public interface DdlHandler {
void generate(DdlWrite writer, CreateTable createTable) throws IOException;
void generate(DdlWrite writer, DropTable dropTable) throws IOException;
void generate(DdlWrite writer, AlterTable dropTable) throws IOException;
void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException;
@@ -6,6 +6,7 @@ import io.ebeaninternal.dbmigration.migration.AddTableComment;
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
import io.ebeaninternal.dbmigration.migration.AlterTable;
import io.ebeaninternal.dbmigration.migration.CreateIndex;
import io.ebeaninternal.dbmigration.migration.CreateTable;
import io.ebeaninternal.dbmigration.migration.DropColumn;
@@ -29,6 +30,11 @@ public interface TableDdl {
* Write the drop column change.
*/
void generate(DdlWrite writer, DropTable dropTable) throws IOException;
/**
* Write alter table changes.
*/
void generate(DdlWrite writer, AlterTable dropTable) throws IOException;
/**
* Write the add column change.
@@ -18,6 +18,7 @@ import io.ebeaninternal.dbmigration.migration.AddTableComment;
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
import io.ebeaninternal.dbmigration.migration.AlterTable;
import io.ebeaninternal.dbmigration.migration.Column;
import io.ebeaninternal.dbmigration.migration.CreateIndex;
import io.ebeaninternal.dbmigration.migration.CreateTable;
@@ -198,7 +199,7 @@ public class BaseTableDdl implements TableDdl {
private void handleStrictError(String tableName, String columnName) {
if (strictMode) {
String message = "DB Migration of non-null column with no default value specified for: " + tableName + "." + columnName+" Use @DbDefault to specify a default value or specify dbMigration.setStrictMode(false)";
String message = "DB Migration of non-null column with no default value specified for: " + tableName + "." + columnName+" Use @DbDefault to specify a default value or disable strict mode for migration";
throw new IllegalArgumentException(message);
}
}
@@ -279,6 +280,10 @@ public class BaseTableDdl implements TableDdl {
writeInlineForeignKeys(writer, createTable);
}
apply.newLine().append(")");
if (createTable.getTablespace() != null) {
platformDdl.addTablespace(apply, createTable.getTablespace(), createTable.getIndexTablespace(),
createTable.getLobTablespace());
}
addTableStorageEngine(apply, createTable);
addTableCommentInline(apply, createTable);
if (partitionMode != null) {
@@ -582,12 +587,12 @@ public class BaseTableDdl implements TableDdl {
}
return pk;
}
@Override
public void generate(DdlWrite writer, CreateIndex index) throws IOException {
if (platformInclude(index.getPlatforms())) {
flushReorgTables(writer.apply());
writer.apply().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
writer.apply().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
writer.dropAll().appendStatement(platformDdl.dropIndex(index.getIndexName(), index.getTableName(), Boolean.TRUE.equals(index.isConcurrent())));
}
}
@@ -712,6 +717,26 @@ public class BaseTableDdl implements TableDdl {
}
}
@Override
public void generate(DdlWrite writer, AlterTable alterTable) throws IOException {
if (hasValue(alterTable.getTablespace()) || hasValue(alterTable.getIndexTablespace()) || hasValue(alterTable.getLobTablespace())) {
writer.apply().appendStatement(platformDdl.alterTableTablespace(alterTable.getName(),
DdlHelp.toTablespace(alterTable.getTablespace()),
DdlHelp.toTablespace(alterTable.getIndexTablespace()),
DdlHelp.toTablespace(alterTable.getLobTablespace())));
}
}
protected void writeTablespaceChange(DdlBuffer buffer, String tablename, String tableSpace, String indexSpace,
String lobSpace) throws IOException {
buffer.appendStatement("-- TableSpace changed: Table: " + tablename + ", tableSpace " + tableSpace + ", indexSpace "
+ indexSpace + ", lobSpace " + lobSpace);
if (strictMode) {
throw new UnsupportedOperationException(
"Tablespace change is not supported by this platform. Disable strict mode for migration and write migration manually");
}
}
/**
* Add drop column DDL.
*/
@@ -1,7 +1,10 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import java.io.IOException;
import io.ebean.annotation.ConstraintMode;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
/**
* DB2 platform specific DDL.
@@ -29,7 +32,8 @@ import io.ebean.config.dbplatform.DatabasePlatform;
*
*/
public class DB2Ddl extends PlatformDdl {
private static final String MOVE_TABLE = "CALL SYSPROC.ADMIN_MOVE_TABLE(CURRENT_SCHEMA,'%s','%s','%s','%s','','','','','','MOVE')";
public DB2Ddl(DatabasePlatform platform) {
super(platform);
this.dropTableIfExists = "drop table ";
@@ -42,6 +46,16 @@ public class DB2Ddl extends PlatformDdl {
this.inlineUniqueWhenNullable = false;
}
@Override
public String alterTableTablespace(String tablename, String tableSpace, String indexSpace, String lobSpace) {
if(tableSpace == null) {
// if no tableSpace set, use the default tablespace USERSPACE1
return String.format(MOVE_TABLE, tablename.toUpperCase(), "USERSPACE1", "USERSPACE1", "USERSPACE1");
} else {
return String.format(MOVE_TABLE, tablename.toUpperCase(), tableSpace, indexSpace, lobSpace);
}
}
@Override
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns,
String[] nullableColumns) {
@@ -135,8 +149,13 @@ public class DB2Ddl extends PlatformDdl {
@Override
public String reorgTable(String table, int counter) {
// TODO Auto-generated method stub
return "call sysproc.admin_cmd('reorg table " + lowerTableName(table) + "') /* reorg #" + counter + " */";
}
@Override
public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace)
throws IOException {
apply.append(" in ").append(tablespaceName).append(" index in ").append(indexTablespace).append(" long in ").append(lobTablespace);
}
}
@@ -1,6 +1,8 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
public class DdlHelp {
public static final String TABLESPACE_DEFAULT = "$TABLESPACE_DEFAULT";
public static final String DROP_DEFAULT = "DROP DEFAULT";
public static final String DROP_COMMENT = "DROP COMMENT";
@@ -36,4 +38,15 @@ public class DdlHelp {
public static boolean isDropForeignKey(String value) {
return DROP_FOREIGN_KEY.equals(value);
}
/**
* Returns the tablespace. Returns null, if this is the special '$TABLESPACE_DEFAULT' value.
*/
public static String toTablespace(String tablespace) {
if (TABLESPACE_DEFAULT.equals(tablespace)) {
return null;
} else {
return tablespace;
}
}
}
@@ -127,7 +127,7 @@ public class PlatformDdl {
protected boolean inlineForeignKeys;
protected boolean includeStorageEngine;
protected final DbDefaultValue dbDefaultValue;
protected String fallbackArrayType = "varchar(1000)";
@@ -400,7 +400,7 @@ public class PlatformDdl {
public String dropIndex(String indexName, String tableName, boolean concurrent) {
return dropIndexIfExists + maxConstraintName(indexName);
}
public String createIndex(WriteCreateIndex create) {
if (create.useDefinition()) {
return create.getDefinition();
@@ -508,6 +508,13 @@ public class PlatformDdl {
return "alter table " + tableName + " " + dropConstraintIfExists + " " + maxConstraintName(constraintName);
}
/**
* Moves the table to an other tablespace.
*/
public String alterTableTablespace(String tablename, String tableSpace, String indexSpace, String lobSpace) {
return null;
}
/**
* Add a unique constraint to the table.
* <p>
@@ -772,6 +779,14 @@ public class PlatformDdl {
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
// only supported by postgres initially
}
/**
* Adds tablespace declaration. Now only supported for db2.
* @throws IOException
*/
public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace) throws IOException{
// now only supported for db2
}
/**
* Returns a statement to reorganize the table. This is required mainly for DB2.
@@ -0,0 +1,526 @@
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2022.02.01 at 12:03:38 PM CET
//
package io.ebeaninternal.dbmigration.migration;
import java.math.BigInteger;
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.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;attGroup ref="{http://ebean-orm.github.io/xml/ns/dbmigration}tablespaceAttributes"/>
* &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="newName" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="partitionMode" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="partitionColumn" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="identityType" type="{http://ebean-orm.github.io/xml/ns/dbmigration}identityType" />
* &lt;attribute name="identityStart" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
* &lt;attribute name="identityIncrement" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
* &lt;attribute name="identityCache" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
* &lt;attribute name="identityGenerated" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="sequenceName" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="sequenceInitial" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
* &lt;attribute name="sequenceAllocate" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
* &lt;attribute name="pkName" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="storageEngine" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlRootElement(name = "alterTable")
public class AlterTable {
@XmlAttribute(name = "name", required = true)
protected String name;
@XmlAttribute(name = "newName")
protected String newName;
@XmlAttribute(name = "partitionMode")
protected String partitionMode;
@XmlAttribute(name = "partitionColumn")
protected String partitionColumn;
@XmlAttribute(name = "identityType")
protected IdentityType identityType;
@XmlAttribute(name = "identityStart")
@XmlSchemaType(name = "positiveInteger")
protected BigInteger identityStart;
@XmlAttribute(name = "identityIncrement")
@XmlSchemaType(name = "positiveInteger")
protected BigInteger identityIncrement;
@XmlAttribute(name = "identityCache")
@XmlSchemaType(name = "positiveInteger")
protected BigInteger identityCache;
@XmlAttribute(name = "identityGenerated")
protected String identityGenerated;
@XmlAttribute(name = "sequenceName")
protected String sequenceName;
@XmlAttribute(name = "sequenceInitial")
@XmlSchemaType(name = "positiveInteger")
protected BigInteger sequenceInitial;
@XmlAttribute(name = "sequenceAllocate")
@XmlSchemaType(name = "positiveInteger")
protected BigInteger sequenceAllocate;
@XmlAttribute(name = "pkName")
protected String pkName;
@XmlAttribute(name = "storageEngine")
protected String storageEngine;
@XmlAttribute(name = "tablespace")
protected String tablespace;
@XmlAttribute(name = "indexTablespace")
protected String indexTablespace;
@XmlAttribute(name = "lobTablespace")
protected String lobTablespace;
@XmlAttribute(name = "comment")
protected String comment;
/**
* 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 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 partitionMode property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPartitionMode() {
return partitionMode;
}
/**
* Sets the value of the partitionMode property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPartitionMode(String value) {
this.partitionMode = value;
}
/**
* Gets the value of the partitionColumn property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPartitionColumn() {
return partitionColumn;
}
/**
* Sets the value of the partitionColumn property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPartitionColumn(String value) {
this.partitionColumn = value;
}
/**
* Gets the value of the identityType property.
*
* @return
* possible object is
* {@link IdentityType }
*
*/
public IdentityType getIdentityType() {
return identityType;
}
/**
* Sets the value of the identityType property.
*
* @param value
* allowed object is
* {@link IdentityType }
*
*/
public void setIdentityType(IdentityType value) {
this.identityType = value;
}
/**
* Gets the value of the identityStart property.
*
* @return
* possible object is
* {@link BigInteger }
*
*/
public BigInteger getIdentityStart() {
return identityStart;
}
/**
* Sets the value of the identityStart property.
*
* @param value
* allowed object is
* {@link BigInteger }
*
*/
public void setIdentityStart(BigInteger value) {
this.identityStart = value;
}
/**
* Gets the value of the identityIncrement property.
*
* @return
* possible object is
* {@link BigInteger }
*
*/
public BigInteger getIdentityIncrement() {
return identityIncrement;
}
/**
* Sets the value of the identityIncrement property.
*
* @param value
* allowed object is
* {@link BigInteger }
*
*/
public void setIdentityIncrement(BigInteger value) {
this.identityIncrement = value;
}
/**
* Gets the value of the identityCache property.
*
* @return
* possible object is
* {@link BigInteger }
*
*/
public BigInteger getIdentityCache() {
return identityCache;
}
/**
* Sets the value of the identityCache property.
*
* @param value
* allowed object is
* {@link BigInteger }
*
*/
public void setIdentityCache(BigInteger value) {
this.identityCache = value;
}
/**
* Gets the value of the identityGenerated property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getIdentityGenerated() {
return identityGenerated;
}
/**
* Sets the value of the identityGenerated property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setIdentityGenerated(String value) {
this.identityGenerated = value;
}
/**
* Gets the value of the sequenceName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getSequenceName() {
return sequenceName;
}
/**
* Sets the value of the sequenceName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setSequenceName(String value) {
this.sequenceName = value;
}
/**
* Gets the value of the sequenceInitial property.
*
* @return
* possible object is
* {@link BigInteger }
*
*/
public BigInteger getSequenceInitial() {
return sequenceInitial;
}
/**
* Sets the value of the sequenceInitial property.
*
* @param value
* allowed object is
* {@link BigInteger }
*
*/
public void setSequenceInitial(BigInteger value) {
this.sequenceInitial = value;
}
/**
* Gets the value of the sequenceAllocate property.
*
* @return
* possible object is
* {@link BigInteger }
*
*/
public BigInteger getSequenceAllocate() {
return sequenceAllocate;
}
/**
* Sets the value of the sequenceAllocate property.
*
* @param value
* allowed object is
* {@link BigInteger }
*
*/
public void setSequenceAllocate(BigInteger value) {
this.sequenceAllocate = value;
}
/**
* Gets the value of the pkName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPkName() {
return pkName;
}
/**
* Sets the value of the pkName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPkName(String value) {
this.pkName = value;
}
/**
* Gets the value of the storageEngine property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getStorageEngine() {
return storageEngine;
}
/**
* Sets the value of the storageEngine property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setStorageEngine(String value) {
this.storageEngine = 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 lobTablespace property.
*
* @return possible object is
* {@link String }
*/
public String getLobTablespace() {
return lobTablespace;
}
/**
* Sets the value of the lobTablespace property.
*
* @param value allowed object is
* {@link String }
*/
public void setLobTablespace(String value) {
this.lobTablespace = 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;
}
}
@@ -47,6 +47,7 @@ public class ChangeSet {
@XmlElement(name = "configuration", type = Configuration.class),
@XmlElement(name = "sql", type = Sql.class),
@XmlElement(name = "createTable", type = CreateTable.class),
@XmlElement(name = "alterTable", type = AlterTable.class),
@XmlElement(name = "dropTable", type = DropTable.class),
@XmlElement(name = "renameTable", type = RenameTable.class),
@XmlElement(name = "addTableComment", type = AddTableComment.class),
@@ -99,6 +99,8 @@ public class CreateTable {
protected String tablespace;
@XmlAttribute(name = "indexTablespace")
protected String indexTablespace;
@XmlAttribute(name = "lobTablespace")
protected String lobTablespace;
@XmlAttribute(name = "comment")
protected String comment;
@@ -522,6 +524,26 @@ public class CreateTable {
public void setIndexTablespace(String value) {
this.indexTablespace = value;
}
/**
* Gets the value of the lobTablespace property.
*
* @return possible object is
* {@link String }
*/
public String getLobTablespace() {
return lobTablespace;
}
/**
* Sets the value of the lobTablespace property.
*
* @param value allowed object is
* {@link String }
*/
public void setLobTablespace(String value) {
this.lobTablespace = value;
}
/**
* Gets the value of the comment property.
@@ -187,6 +187,14 @@ public class ObjectFactory {
return new ChangeSet();
}
/**
* Create an instance of {@link AlterTable }
*
*/
public AlterTable createAlterTable() {
return new AlterTable();
}
/**
* Create an instance of {@link AddHistoryTable }
*/
@@ -5,6 +5,7 @@ import io.ebeaninternal.dbmigration.migration.AddColumn;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
import io.ebeaninternal.dbmigration.migration.AddTableComment;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterTable;
import io.ebeaninternal.dbmigration.migration.Column;
import io.ebeaninternal.dbmigration.migration.CreateTable;
import io.ebeaninternal.dbmigration.migration.DropColumn;
@@ -17,6 +18,8 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.IdentityMode;
import io.ebeaninternal.server.deploy.PartitionMeta;
import io.ebeaninternal.server.deploy.TablespaceMeta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,6 +29,7 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.split;
@@ -56,11 +60,10 @@ public class MTable {
*/
private boolean draft;
private PartitionMeta partitionMeta;
private TablespaceMeta tablespaceMeta;
private String pkName;
private String comment;
private String tablespace;
private String storageEngine;
private String indexTablespace;
private IdentityMode identityMode;
private boolean withHistory;
private final Map<String, MColumn> columns = new LinkedHashMap<>();
@@ -93,6 +96,7 @@ public class MTable {
this.identityMode = descriptor.identityMode();
this.storageEngine = descriptor.storageEngine();
this.partitionMeta = descriptor.partitionMeta();
this.tablespaceMeta = descriptor.tablespaceMeta();
this.comment = descriptor.dbComment();
if (descriptor.isHistorySupport()) {
withHistory = true;
@@ -104,11 +108,28 @@ public class MTable {
}
/**
* Construct for element collection or intersection table.
* Constructor for test cases only!
*/
@Deprecated
public MTable(String name) {
this(name, null, null);
}
/**
* Construct for element collection or intersection table. They have same table space and storage engine.
*/
public MTable(String name, BeanDescriptor<?> descriptor) {
this(name, descriptor.tablespaceMeta(), descriptor.storageEngine());
}
/**
* Constructor for dependant tables (draft/element collection or intersection).
*/
private MTable(String name, TablespaceMeta tablespaceMeta, String storageEngine) {
this.name = name;
this.identityMode = IdentityMode.NONE;
this.tablespaceMeta = tablespaceMeta;
this.storageEngine = storageEngine;
}
/**
@@ -118,7 +139,7 @@ public class MTable {
* later when creating the CreateTable object.
*/
public MTable createDraftTable() {
draftTable = new MTable(name + "_draft");
draftTable = new MTable(name + "_draft", this.tablespaceMeta, this.storageEngine);
draftTable.draft = true;
draftTable.whenCreatedColumn = whenCreatedColumn;
// compoundKeys
@@ -138,8 +159,13 @@ public class MTable {
this.pkName = createTable.getPkName();
this.comment = createTable.getComment();
this.storageEngine = createTable.getStorageEngine();
this.tablespace = createTable.getTablespace();
this.indexTablespace = createTable.getIndexTablespace();
if (createTable.getTablespace() != null) {
this.tablespaceMeta = new TablespaceMeta(createTable.getTablespace(),
createTable.getIndexTablespace() != null ? createTable.getIndexTablespace() : createTable.getTablespace(),
createTable.getLobTablespace() != null ? createTable.getLobTablespace() : createTable.getTablespace());
} else {
this.tablespaceMeta = null;
}
this.withHistory = Boolean.TRUE.equals(createTable.isWithHistory());
this.draft = Boolean.TRUE.equals(createTable.isDraft());
this.identityMode = fromCreateTable(createTable);
@@ -210,8 +236,11 @@ public class MTable {
createTable.setPartitionColumn(partitionMeta.getProperty());
}
createTable.setStorageEngine(storageEngine);
createTable.setTablespace(tablespace);
createTable.setIndexTablespace(indexTablespace);
if (tablespaceMeta != null) {
createTable.setTablespace(tablespaceMeta.getTablespaceName());
createTable.setIndexTablespace(tablespaceMeta.getIndexTablespace());
createTable.setLobTablespace(tablespaceMeta.getLobTablespace());
}
toCreateTable(identityMode, createTable);
if (withHistory) {
createTable.setWithHistory(Boolean.TRUE);
@@ -266,6 +295,8 @@ public class MTable {
compareCompoundKeys(modelDiff, newTable);
compareUniqueKeys(modelDiff, newTable);
compareTableAttrs(modelDiff, newTable);
}
private void compareColumns(ModelDiff modelDiff, MTable newTable) {
@@ -335,6 +366,29 @@ public class MTable {
modelDiff.addUniqueConstraint(newKey.addUniqueConstraint(name));
}
}
private void compareTableAttrs(ModelDiff modelDiff, MTable newTable) {
AlterTable alterTable = new AlterTable();
alterTable.setName(newTable.getName());
boolean altered = false;
if (!Objects.equals(tablespaceMeta, newTable.getTablespaceMeta())) {
if (newTable.getTablespaceMeta() == null) {
alterTable.setTablespace(DdlHelp.TABLESPACE_DEFAULT);
alterTable.setIndexTablespace(DdlHelp.TABLESPACE_DEFAULT);
alterTable.setLobTablespace(DdlHelp.TABLESPACE_DEFAULT);
} else {
alterTable.setTablespace(newTable.getTablespaceMeta().getTablespaceName());
alterTable.setIndexTablespace(newTable.getTablespaceMeta().getIndexTablespace());
alterTable.setLobTablespace(newTable.getTablespaceMeta().getLobTablespace());
}
altered = true;
}
if (altered) {
modelDiff.addAlterTable(alterTable);
}
}
/**
* Apply AddColumn migration.
@@ -424,13 +478,13 @@ public class MTable {
public void setComment(String comment) {
this.comment = comment;
}
public String getTablespace() {
return tablespace;
public void setTablespaceMeta(TablespaceMeta tablespaceMeta) {
this.tablespaceMeta = tablespaceMeta;
}
public String getIndexTablespace() {
return indexTablespace;
public TablespaceMeta getTablespaceMeta() {
return tablespaceMeta;
}
public boolean isWithHistory() {
@@ -8,6 +8,7 @@ import io.ebeaninternal.dbmigration.migration.AddTableComment;
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
import io.ebeaninternal.dbmigration.migration.AlterTable;
import io.ebeaninternal.dbmigration.migration.ChangeSet;
import io.ebeaninternal.dbmigration.migration.ChangeSetType;
import io.ebeaninternal.dbmigration.migration.CreateIndex;
@@ -19,6 +20,7 @@ import io.ebeaninternal.dbmigration.migration.DropTable;
import io.ebeaninternal.dbmigration.migration.Migration;
import io.ebeaninternal.dbmigration.migration.RenameColumn;
import io.ebeaninternal.dbmigration.migration.Sql;
import io.ebeaninternal.server.deploy.TablespaceMeta;
import java.util.ArrayList;
import java.util.Collection;
@@ -155,6 +157,8 @@ public class ModelContainer {
applyChange((CreateTable) change);
} else if (change instanceof DropTable) {
applyChange((DropTable) change);
} else if (change instanceof AlterTable) {
applyChange((AlterTable) change);
} else if (change instanceof AlterColumn) {
applyChange((AlterColumn) change);
} else if (change instanceof AddColumn) {
@@ -261,6 +265,32 @@ public class ModelContainer {
protected void applyChange(DropTable dropTable) {
tables.remove(dropTable.getName());
}
protected void applyChange(AlterTable alterTable) {
MTable table = getTable(alterTable.getName());
if (table == null) {
throw new IllegalStateException("Table [" + alterTable.getName() + "] does not exist in model?");
}
// Handle Tablespace change
TablespaceMeta ts = table.getTablespaceMeta();
if (alterTable.getTablespace() != null) {
String currentTableSpace = DdlHelp.toTablespace(alterTable.getTablespace());
String currentIndexSpace = DdlHelp.toTablespace(alterTable.getIndexTablespace());
String currentLobSpace = DdlHelp.toTablespace(alterTable.getLobTablespace());
if (currentTableSpace != null) {
assert currentIndexSpace != null;
assert currentLobSpace != null;
table.setTablespaceMeta(new TablespaceMeta(currentTableSpace, currentIndexSpace, currentLobSpace));
} else {
assert currentIndexSpace == null;
assert currentLobSpace == null;
table.setTablespaceMeta(null);
}
}
}
/**
* Apply a CreateTable change to the model.
@@ -6,6 +6,7 @@ import io.ebeaninternal.dbmigration.migration.AddTableComment;
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
import io.ebeaninternal.dbmigration.migration.AlterTable;
import io.ebeaninternal.dbmigration.migration.ChangeSet;
import io.ebeaninternal.dbmigration.migration.ChangeSetType;
import io.ebeaninternal.dbmigration.migration.CreateIndex;
@@ -252,4 +253,11 @@ public class ModelDiff {
public void addAlterForeignKey(AlterForeignKey alterForeignKey) {
applyChanges.add(alterForeignKey);
}
/**
* Adds a table alter.
*/
public void addAlterTable(AlterTable alterTable) {
applyChanges.add(alterTable);
}
}
@@ -18,7 +18,7 @@ public class ModelBuildElementTable {
BeanTable beanTable = manyProp.beanTable();
BeanDescriptor<?> targetDescriptor = manyProp.targetDescriptor();
MTable table = new MTable(beanTable.getBaseTable());
MTable table = new MTable(beanTable.getBaseTable(), manyProp.descriptor());
VisitProperties.visit(targetDescriptor, new ModelBuildPropertyVisitor(ctx, table, targetDescriptor));
ctx.addTableElementCollection(table);
@@ -62,7 +62,7 @@ class ModelBuildIntersectionTable {
BeanDescriptor<?> targetDesc = manyProp.targetDescriptor();
String tableName = intersectionTableJoin.getTable();
MTable table = new MTable(tableName);
MTable table = new MTable(tableName, localDesc);
if (!manyProp.isExcludedFromHistory()) {
if (localDesc.isHistorySupport()) {
table.setWithHistory(true);
@@ -218,6 +218,27 @@
<xsd:attribute name="baseTable" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="alterTable">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="newName" type="xsd:string"/>
<xsd:attribute name="partitionMode" type="xsd:string"/>
<xsd:attribute name="partitionColumn" type="xsd:string"/>
<xsd:attribute name="identityType" type="identityType"/>
<xsd:attribute name="identityStart" type="xsd:positiveInteger"/>
<xsd:attribute name="identityIncrement" type="xsd:positiveInteger"/>
<xsd:attribute name="identityCache" type="xsd:positiveInteger"/>
<xsd:attribute name="identityGenerated" type="xsd:string"/>
<xsd:attribute name="sequenceName" type="xsd:string"/>
<xsd:attribute name="sequenceInitial" type="xsd:positiveInteger"/>
<xsd:attribute name="sequenceAllocate" type="xsd:positiveInteger"/>
<xsd:attribute name="pkName" type="xsd:string"/>
<xsd:attribute name="storageEngine" type="xsd:string"/>
<xsd:attributeGroup ref="tablespaceAttributes"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="dropHistoryTable">
<xsd:complexType>
@@ -341,6 +362,7 @@
<xsd:attributeGroup name="tablespaceAttributes">
<xsd:attribute name="tablespace" type="xsd:string"/>
<xsd:attribute name="indexTablespace" type="xsd:string"/>
<xsd:attribute name="lobTablespace" type="xsd:string"/>
<xsd:attribute name="comment" type="xsd:string"/>
</xsd:attributeGroup>
@@ -351,6 +373,7 @@
<xsd:element ref="sql" maxOccurs="unbounded"/>
<xsd:element ref="createTable" maxOccurs="unbounded"/>
<xsd:element ref="alterTable" maxOccurs="unbounded"/>
<xsd:element ref="dropTable" maxOccurs="unbounded"/>
<xsd:element ref="renameTable" maxOccurs="unbounded"/>
<xsd:element ref="addTableComment" maxOccurs="unbounded"/>
@@ -109,4 +109,12 @@ public class PlatformDdl_CreateIndexTest {
assertEquals("create index ix_mytab_acol on mytab (acol)", sql);
}
@Test
public void db2luw_tablespaceIndex() {
String sql = db2LuwDdl.createIndex(new WriteCreateIndex("ix_mytab_acol", "mytab", new String[]{"acol"}, false));
assertEquals("create index ix_mytab_acol on mytab (acol)", sql);
sql = db2LuwDdl.createIndex(new WriteCreateIndex("ix_mytab_acol", "mytab", new String[]{"acol"}, true));
assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql);
}
}
@@ -34,8 +34,8 @@ public class ModelContainerApplyTest {
MTable foo = model.getTable("foo");
assertThat(foo.getComment()).isEqualTo("comment");
assertThat(foo.getTablespace()).isEqualTo("fooSpace");
assertThat(foo.getIndexTablespace()).isEqualTo("fooIndexSpace");
assertThat(foo.getTablespaceMeta().getTablespaceName()).isEqualTo("fooSpace");
assertThat(foo.getTablespaceMeta().getIndexTablespace()).isEqualTo("fooIndexSpace");
assertThat(foo.isWithHistory()).isEqualTo(false);
assertThat(foo.allColumns()).extracting("name").contains("col1", "col3", "added_to_foo");
}
@@ -14,5 +14,3 @@ datasource.db2.url=jdbc:db2://localhost:50005/migtest
datasource.pg.username=sa
datasource.pg.password=
datasource.pg.url=jdbc:h2:mem:h2AutoTune