From 6f2e1c024825b9fc7a168a3d5a3f5880c9f99141 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 1 Mar 2018 12:55:22 +1300 Subject: [PATCH] #1295 - Multiple platform DbMigration generation with non-native boolean type (BIT, INTEGER etc) produces incorrect DDL for other DB Platform with native boolean --- .../config/dbplatform/DbPlatformType.java | 36 +++++++++++-------- .../dbplatform/DbPlatformTypeMapping.java | 17 ++++++++- .../server/type/ScalarTypeBool.java | 2 +- .../server/type/ScalarTypeBoolean.java | 5 +++ .../dbplatform/DbPlatformTypeMappingTest.java | 20 +++++++++++ .../server/type/ScalarTypeBooleanTest.java | 16 ++++++++- 6 files changed, 78 insertions(+), 18 deletions(-) create mode 100644 src/test/java/io/ebean/config/dbplatform/DbPlatformTypeMappingTest.java diff --git a/src/main/java/io/ebean/config/dbplatform/DbPlatformType.java b/src/main/java/io/ebean/config/dbplatform/DbPlatformType.java index 4a65853ff..13c0d1fcb 100644 --- a/src/main/java/io/ebean/config/dbplatform/DbPlatformType.java +++ b/src/main/java/io/ebean/config/dbplatform/DbPlatformType.java @@ -126,27 +126,33 @@ public class DbPlatformType implements ExtraDbTypes { StringBuilder sb = new StringBuilder(); sb.append(name); - if (canHaveLength || !strict) { - // see if there is a precision/scale to add (or not) - int len = deployLength != 0 ? deployLength : defaultLength; - if (len == Integer.MAX_VALUE) { - sb.append("(max)"); // TODO: this is sqlserver specific - } else if (len > 0) { - sb.append("("); - sb.append(len); - int scale = deployScale != 0 ? deployScale : defaultScale; - if (scale > 0) { - sb.append(","); - sb.append(scale); - } - sb.append(")"); - } + renderLengthScale(deployLength, deployScale, sb); } return sb.toString(); } + /** + * Render the length and scale part of the column definition. + */ + protected void renderLengthScale(int deployLength, int deployScale, StringBuilder sb) { + // see if there is a precision/scale to add (or not) + int len = deployLength != 0 ? deployLength : defaultLength; + if (len == Integer.MAX_VALUE) { + sb.append("(max)"); // TODO: this is sqlserver specific + } else if (len > 0) { + sb.append("("); + sb.append(len); + int scale = deployScale != 0 ? deployScale : defaultScale; + if (scale > 0) { + sb.append(","); + sb.append(scale); + } + sb.append(")"); + } + } + /** * Create a copy of the type with a new default length. */ diff --git a/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java b/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java index 6ad6f9e95..b26576247 100644 --- a/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java +++ b/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java @@ -10,8 +10,23 @@ import java.util.Map; */ public class DbPlatformTypeMapping { + /** + * Boolean type used for logical model. + */ + private static class BooleanLogicalType extends DbPlatformType { + BooleanLogicalType() { + super("boolean", false); + } + @Override + protected void renderLengthScale(int deployLength, int deployScale, StringBuilder sb) { + // do not have length - even if platform boolean type does like integer(1) + } + } + private static DbPlatformTypeLookup lookup = new DbPlatformTypeLookup(); + private static final DbPlatformType BOOLEAN_LOGICAL = new BooleanLogicalType(); + private static final DbPlatformType UUID_NATIVE = new DbPlatformType("uuid", false); @SuppressWarnings("unused") private static final DbPlatformType UUID_PLACEHOLDER = new DbPlatformType("uuidPlaceholder"); @@ -51,7 +66,7 @@ public class DbPlatformTypeMapping { */ private void loadDefaults(boolean logicalTypes) { - put(DbType.BOOLEAN); + put(DbType.BOOLEAN, BOOLEAN_LOGICAL); put(DbType.BIT); put(DbType.INTEGER); put(DbType.BIGINT); diff --git a/src/main/java/io/ebeaninternal/server/type/ScalarTypeBool.java b/src/main/java/io/ebeaninternal/server/type/ScalarTypeBool.java index a64663837..35a5a9346 100644 --- a/src/main/java/io/ebeaninternal/server/type/ScalarTypeBool.java +++ b/src/main/java/io/ebeaninternal/server/type/ScalarTypeBool.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.type; /** * Boolean ScalarType's must implement to support DDL default values etc. */ -public interface ScalarTypeBool extends ScalarType { +public interface ScalarTypeBool extends ScalarType, ScalarTypeLogicalType { /** * Return the DB literal value for FALSE. diff --git a/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java b/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java index b25df4beb..d6f411684 100644 --- a/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java +++ b/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java @@ -302,6 +302,11 @@ public class ScalarTypeBoolean { super(Boolean.class, jdbcNative, jdbcType); } + @Override + public int getLogicalType() { + return Types.BOOLEAN; + } + /** * Return the DB literal value for false. */ diff --git a/src/test/java/io/ebean/config/dbplatform/DbPlatformTypeMappingTest.java b/src/test/java/io/ebean/config/dbplatform/DbPlatformTypeMappingTest.java new file mode 100644 index 000000000..0f1307446 --- /dev/null +++ b/src/test/java/io/ebean/config/dbplatform/DbPlatformTypeMappingTest.java @@ -0,0 +1,20 @@ +package io.ebean.config.dbplatform; + +import org.junit.Test; + +import java.sql.Types; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DbPlatformTypeMappingTest { + + @Test + public void logicalBoolean_renderType_expect_noLength() { + + DbPlatformTypeMapping logicalMapping = DbPlatformTypeMapping.logicalTypes(); + + DbPlatformType type = logicalMapping.get(Types.BOOLEAN); + String colDefinition = type.renderType(1, 1, false); + assertThat(colDefinition).isEqualTo("boolean"); + } +} diff --git a/src/test/java/io/ebeaninternal/server/type/ScalarTypeBooleanTest.java b/src/test/java/io/ebeaninternal/server/type/ScalarTypeBooleanTest.java index 2347e913c..5c4c83ea5 100644 --- a/src/test/java/io/ebeaninternal/server/type/ScalarTypeBooleanTest.java +++ b/src/test/java/io/ebeaninternal/server/type/ScalarTypeBooleanTest.java @@ -6,7 +6,12 @@ import io.ebean.text.json.JsonContext; import org.tests.model.basic.TOne; import org.junit.Test; -import static org.junit.Assert.*; +import java.sql.Types; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class ScalarTypeBooleanTest { @@ -40,4 +45,13 @@ public class ScalarTypeBooleanTest { assertEquals(json, "{\"id\":42,\"active\":false}"); } + + @Test + public void IntBoolean_isLogicalBoolean() { + + ScalarTypeBoolean.IntBoolean intBoolean = new ScalarTypeBoolean.IntBoolean(1, 0); + assertThat(intBoolean).isInstanceOf(ScalarTypeLogicalType.class); + + assertThat(intBoolean.getLogicalType()).isEqualTo(Types.BOOLEAN); + } }