Skip to content

Commit

Permalink
#1011 - Create valid migration scripts for non-Postgres databases and @…
Browse files Browse the repository at this point in the history
…DBArray columns.

    Merge branch 'test/dbarray-create-migration' of https://github.com/FOCONIS/ebean into FOCONIS-test/dbarray-create-migration

commit 3a8f32b
Author: Michael Benz <michael.benz@foconis.de>
Date:   Wed Apr 19 18:16:51 2017 +0200

    adding dbmigration ddlgeneration test for Ebean @DBArray extension.
  • Loading branch information
rbygrave committed May 20, 2017
1 parent 79f7c73 commit fe9500e
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ public H2Ddl(DatabasePlatform platform) {
this.historyDdl = new H2HistoryDdl();
}

@Override
protected String convertArrayType(String logicalArrayType) {
return "array";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public class PlatformDdl {

protected final DbDefaultValue dbDefaultValue;

protected String fallbackArrayType = "varchar(1000)";

public PlatformDdl(DatabasePlatform platform) {
this.platform = platform;
this.dbIdentity = platform.getDbIdentity();
Expand Down Expand Up @@ -215,10 +217,24 @@ public String alterTableDropForeignKey(String tableName, String fkName) {
* Convert the standard type to the platform specific type.
*/
public String convert(String type, boolean identity) {
if (type.contains("[]")) {
return convertArrayType(type);
}
String platformType = typeConverter.convert(type);
return identity ? asIdentityColumn(platformType) : platformType;
}

/**
* Convert the logical array type to a db platform specific type to support the array data.
*/
protected String convertArrayType(String logicalArrayType) {
if (logicalArrayType.endsWith("]")) {
return fallbackArrayType;
}
int colonPos = logicalArrayType.lastIndexOf(']');
return "varchar" + logicalArrayType.substring(colonPos + 1);
}

/**
* Add history support to this table using the platform specific mechanism.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ public PostgresDdl(DatabasePlatform platform) {
this.columnSetNull = "drop not null";
}

@Override
protected String convertArrayType(String logicalArrayType) {
int colonPos = logicalArrayType.lastIndexOf(']');
if (colonPos == -1) {
return logicalArrayType;
} else {
// trim of the fallback varchar length
return logicalArrayType.substring(0, colonPos + 1);
}
}

/**
* Map bigint, integer and smallint into their equivalent serial types.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,15 @@ public void setDbArray(DeployBeanProperty prop, DbArray dbArray) {
prop.setDbType(dbType);
prop.setScalarType(scalarType);
if (scalarType instanceof ScalarTypeArray) {
prop.setDbColumnDefn(((ScalarTypeArray) scalarType).getDbColumnDefn());
}
if (dbType == Types.VARCHAR) {
// determine the db column size
int dbLength = dbArray.length();
int columnLength = (dbLength > 0) ? dbLength : DEFAULT_ARRAY_VARCHAR_LENGTH;
prop.setDbLength(columnLength);
String columnDefn = ((ScalarTypeArray) scalarType).getDbColumnDefn();
if (dbArray.length() > 0) {
// fallback varchar column length when ARRAY not support by DB
columnDefn += "(" + dbArray.length() + ")";
}
prop.setDbLength(dbArray.length());
prop.setDbColumnDefn(columnDefn);
} else {
throw new RuntimeException("Not mapped to ScalarTypeArray? " + scalarType.getClass());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ private ScalarTypeArrayListH2(String arrayType, DocPropertyType docPropertyType,
super(arrayType, docPropertyType, converter);
}

@Override
public String getDbColumnDefn() {
return "array";
}

@Override
public void bind(DataBind bind, List value) throws SQLException {
if (value == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ private ScalarTypeArraySetH2(String arrayType, DocPropertyType docPropertyType,
super(arrayType, docPropertyType, converter);
}

@Override
public String getDbColumnDefn() {
return "array";
}

@Override
public void bind(DataBind bind, Set value) throws SQLException {
if (value == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.io.DataOutput;
import java.io.IOException;

abstract class ScalarTypeJsonCollection<T> extends ScalarTypeBase<T> {
abstract class ScalarTypeJsonCollection<T> extends ScalarTypeBase<T> implements ScalarTypeArray {

protected DocPropertyType docPropertyType;

Expand All @@ -15,6 +15,23 @@ public ScalarTypeJsonCollection(Class<T> type, int dbType, DocPropertyType docPr
this.docPropertyType = docPropertyType;
}

/**
* Return the logical db column definition based on the element document type.
*/
@Override
public String getDbColumnDefn() {
switch (docPropertyType) {
case SHORT:
case INTEGER:
case LONG:
return "integer[]";
case DOUBLE:
case FLOAT:
return "decimal[]";
}
return "varchar[]";
}

/**
* Consider as a mutable type. Use the isDirty() method to check for dirty state.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.h2.H2Platform;
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
import io.ebean.config.dbplatform.sqlserver.SqlServerPlatform;
import io.ebean.dbmigration.migration.ChangeSet;
import io.ebean.dbmigration.model.CurrentModel;
import io.ebeaninternal.api.SpiEbeanServer;
Expand All @@ -26,17 +27,78 @@ private DdlHandler postgresHandler() {
return new PostgresPlatform().createDdlHandler(serverConfig);
}

private DdlHandler sqlserverHandler() {
return new SqlServerPlatform().createDdlHandler(serverConfig);
}

@Test
public void addColumn_nullable_noConstraint() throws Exception {

DdlWrite write = new DdlWrite();
h2Handler().generate(write, Helper.getAddColumn());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column added_to_foo varchar(20);\n\n");

DdlHandler handler = h2Handler();
handler.generate(write, Helper.getAddColumn());

write = new DdlWrite();
sqlserverHandler().generate(write, Helper.getAddColumn());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column added_to_foo varchar(20);\n\n");
}

/**
* Test the functionality of the Ebean {@literal @}DbArray extension during DDL generation.
*/
@Test
public void addColumn_dbarray() throws Exception {

DdlWrite write = new DdlWrite();

DdlHandler postgresHandler = postgresHandler();
postgresHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());

assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_added_to_foo varchar[];\n\n");

write = new DdlWrite();

DdlHandler sqlserverHandler = sqlserverHandler();
sqlserverHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_added_to_foo varchar(1000);\n\n");
}

@Test
public void addColumn_dbarray_withLength() throws Exception {

DdlWrite write = new DdlWrite();

postgresHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety varchar[];\n\n");

write = new DdlWrite();
h2Handler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety array;\n\n");

write = new DdlWrite();
sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety varchar(90);\n\n");
}

@Test
public void addColumn_dbarray_integer_withLength() throws Exception {

DdlWrite write = new DdlWrite();
postgresHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer integer[];\n\n");

write = new DdlWrite();
h2Handler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer array;\n\n");

write = new DdlWrite();
sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer varchar(90);\n\n");

write = new DdlWrite();
sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnInteger());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer varchar(1000);\n\n");
}

@Test
public void addColumn_withForeignKey() throws Exception {
Expand Down
16 changes: 16 additions & 0 deletions src/test/java/io/ebean/dbmigration/ddlgeneration/Helper.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ public static AddColumn getAlterTableAddColumn() {
return (AddColumn) alterTableChangeSetChildren.get(0);
}

public static AddColumn getAlterTableAddDbArrayColumn() {
return (AddColumn) alterTableChangeSetChildren.get(1);
}

public static AddColumn getAlterTableAddDbArrayColumnWithLength() {
return (AddColumn) alterTableChangeSetChildren.get(2);
}

public static AddColumn getAlterTableAddDbArrayColumnIntegerWithLength() {
return (AddColumn) alterTableChangeSetChildren.get(3);
}

public static AddColumn getAlterTableAddDbArrayColumnInteger() {
return (AddColumn) alterTableChangeSetChildren.get(4);
}

public static DropColumn getDropColumn() {
return (DropColumn) changeSetChildren.get(2);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import io.ebean.dbmigration.migration.AlterColumn;
import org.junit.Test;

import static org.junit.Assert.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

public class PlatformDdl_AlterColumnTest {

Expand All @@ -29,6 +31,30 @@ AlterColumn alterNotNull() {
return alterColumn;
}

@Test
public void convertArrayType_default() {
assertThat(mysqlDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar(90)");
assertThat(mysqlDdl.convertArrayType("integer[](60)")).isEqualTo("varchar(60)");
assertThat(mysqlDdl.convertArrayType("varchar[]")).isEqualTo("varchar(1000)");
assertThat(mysqlDdl.convertArrayType("integer[]")).isEqualTo("varchar(1000)");
}

@Test
public void convertArrayType_h2() {
assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("array");
assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("array");
assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("array");
assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("array");
}

@Test
public void convertArrayType_postgres() {
assertThat(pgDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar[]");
assertThat(pgDdl.convertArrayType("integer[](60)")).isEqualTo("integer[]");
assertThat(pgDdl.convertArrayType("varchar[]")).isEqualTo("varchar[]");
assertThat(pgDdl.convertArrayType("integer[]")).isEqualTo("integer[]");
}

@Test
public void testAlterColumnBaseAttributes() throws Exception {

Expand Down
18 changes: 17 additions & 1 deletion src/test/resources/container/test-alter-table.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@
<column name="some_id" type="integer" references="bar.id" foreignKeyName="fk_foo_some_id" foreignKeyIndex="idx_foo_some_id"/>
</addColumn>

<addColumn tableName="foo">
<column name="dbarray_added_to_foo" type="varchar[]"/>
</addColumn>

<addColumn tableName="foo">
<column name="dbarray_ninety" type="varchar[](90)"/>
</addColumn>

<addColumn tableName="foo">
<column name="dbarray_integer" type="integer[](90)"/>
</addColumn>

<addColumn tableName="foo">
<column name="dbarray_integer" type="integer[]"/>
</addColumn>

</changeSet>

</migration>
</migration>

0 comments on commit fe9500e

Please sign in to comment.