Skip to content

Commit f712635

Browse files
authored
Merge pull request #3107 from FOCONIS/json-tests
DB specific length support in JSONs/Varchars/binary data
2 parents 47a0e38 + 994fb26 commit f712635

File tree

103 files changed

+3279
-222
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+3279
-222
lines changed

ebean-api/src/main/java/io/ebean/config/dbplatform/DbPlatformType.java

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ public class DbPlatformType implements ExtraDbTypes {
2828
*/
2929
private final boolean canHaveLength;
3030

31+
/**
32+
* The maximum length supported by this platform type. If length is too big, fallback is used.
33+
*/
34+
private final int maxLength;
35+
36+
/**
37+
* Use this platform type if length exceedes
38+
*/
39+
private final DbPlatformType fallback;
40+
3141
/**
3242
* Parse a type definition into a DbPlatformType.
3343
* <p>
@@ -53,6 +63,41 @@ public DbPlatformType(String name, int defaultLength) {
5363
this(name, defaultLength, 0);
5464
}
5565

66+
/**
67+
* Construct without length, but with a max length limit and a fallback type, that is used if maxLength is exceeded.
68+
* This can be used to use <ul>
69+
* <li>"longtext" for unspecified length</li>
70+
* <li>"text" for length up to 2^16-1</li>
71+
* <li>"mediumtext" for length up to 2^24-1</li>
72+
* <li>"longtext" else</li>
73+
* </ul>
74+
*/
75+
public DbPlatformType(String name, int maxLength, DbPlatformType fallback) {
76+
this.name = name;
77+
this.defaultLength = 0;
78+
this.defaultScale = 0;
79+
this.canHaveLength = false;
80+
this.maxLength = maxLength;
81+
this.fallback = fallback;
82+
}
83+
84+
/**
85+
* Construct with a given default length, a max length limit and a fallback type, that is used if maxLength is exceeded.
86+
* This can be used to use <ul>
87+
* <li>"varchar(255)" for unspecified length</li>
88+
* <li>"varchar(N)" for N <= maxLength</li>
89+
* <li>"varchar(max)" else</li>
90+
* </ul>
91+
*/
92+
public DbPlatformType(String name, int defaultPrecision, int maxLength, DbPlatformType fallback) {
93+
this.name = name;
94+
this.defaultLength = defaultPrecision;
95+
this.defaultScale = 0;
96+
this.canHaveLength = true;
97+
this.maxLength = maxLength;
98+
this.fallback = fallback;
99+
}
100+
56101
/**
57102
* Construct for Decimal with precision and scale.
58103
*/
@@ -61,6 +106,8 @@ public DbPlatformType(String name, int defaultPrecision, int defaultScale) {
61106
this.defaultLength = defaultPrecision;
62107
this.defaultScale = defaultScale;
63108
this.canHaveLength = true;
109+
this.maxLength = Integer.MAX_VALUE;
110+
this.fallback = null;
64111
}
65112

66113
/**
@@ -74,6 +121,8 @@ public DbPlatformType(String name, boolean canHaveLength) {
74121
this.defaultLength = 0;
75122
this.defaultScale = 0;
76123
this.canHaveLength = canHaveLength;
124+
this.maxLength = Integer.MAX_VALUE;
125+
this.fallback = null;
77126
}
78127

79128
/**
@@ -124,33 +173,33 @@ public String renderType(int deployLength, int deployScale) {
124173
*/
125174
public String renderType(int deployLength, int deployScale, boolean strict) {
126175

127-
StringBuilder sb = new StringBuilder();
128-
sb.append(name);
129-
if (canHaveLength || !strict) {
130-
renderLengthScale(deployLength, deployScale, sb);
131-
}
176+
int len = deployLength != 0 ? deployLength : defaultLength;
177+
if (len > maxLength) {
178+
return fallback.renderType(deployLength, deployScale, strict);
179+
} else {
180+
StringBuilder sb = new StringBuilder();
181+
sb.append(name);
182+
if ((canHaveLength || !strict) && len > 0) {
183+
renderLengthScale(len, deployScale, sb);
184+
}
132185

133-
return sb.toString();
186+
return sb.toString();
187+
}
134188
}
135189

136190
/**
137191
* Render the length and scale part of the column definition.
138192
*/
139-
protected void renderLengthScale(int deployLength, int deployScale, StringBuilder sb) {
193+
protected void renderLengthScale(int len, int deployScale, StringBuilder sb) {
140194
// see if there is a precision/scale to add (or not)
141-
int len = deployLength != 0 ? deployLength : defaultLength;
142-
if (len == Integer.MAX_VALUE) {
143-
sb.append("(max)"); // TODO: this is sqlserver specific
144-
} else if (len > 0) {
145-
sb.append("(");
146-
sb.append(len);
147-
int scale = deployScale != 0 ? deployScale : defaultScale;
148-
if (scale > 0) {
149-
sb.append(",");
150-
sb.append(scale);
151-
}
152-
sb.append(")");
195+
sb.append('(');
196+
sb.append(len);
197+
int scale = deployScale != 0 ? deployScale : defaultScale;
198+
if (scale > 0) {
199+
sb.append(',');
200+
sb.append(scale);
153201
}
202+
sb.append(')');
154203
}
155204

156205
/**

ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class ClickHouseDbArray {
1515
mapping.put("integer[]", "Array(UInt32)");
1616
mapping.put("bigint[]", "Array(UInt64)");
1717
mapping.put("float[]", "Array(Float32)");
18+
mapping.put("float4[]", "Array(Float32)");
1819
mapping.put("decimal[]", "Array(Decimal)");
1920
}
2021

ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,13 @@ public String convert(String type) {
279279
if (type == null) {
280280
return null;
281281
}
282-
type = extract(type);
282+
String[] tmp = type.split(";", -1); // do not discard trailing empty strings
283+
int index = extract(tmp);
284+
if (index < tmp.length - 1) {
285+
// this is a platform specific definition. So do not apply further conversions
286+
return tmp[index];
287+
}
288+
type = tmp[index];
283289
if (type.contains("[]")) {
284290
return convertArrayType(type);
285291
}
@@ -294,18 +300,22 @@ protected String extract(String type) {
294300
return null;
295301
}
296302
String[] tmp = type.split(";", -1); // do not discard trailing empty strings
297-
if (tmp.length % 2 == 0) {
298-
throw new IllegalArgumentException("You need an odd number of arguments in '" + type + "'. See Issue #2559 for details");
303+
return tmp[extract(tmp)]; // else
304+
}
305+
306+
protected int extract(String[] types) {
307+
if (types.length % 2 == 0) {
308+
throw new IllegalArgumentException("You need an odd number of arguments in '" + String.join(";", types) + "'. See Issue #2559 for details");
299309
}
300-
for (int i = 0; i < tmp.length - 2; i += 2) {
301-
String[] platforms = tmp[i].split(",");
310+
for (int i = 0; i < types.length - 2; i += 2) {
311+
String[] platforms = types[i].split(",");
302312
for (String plat : platforms) {
303313
if (platform.isPlatform(Platform.valueOf(plat.toUpperCase(Locale.ENGLISH)))) {
304-
return tmp[i + 1];
314+
return i + 1;
305315
}
306316
}
307317
}
308-
return tmp[tmp.length - 1]; // else
318+
return types.length - 1; // else
309319
}
310320

311321
/**

ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MySqlPlatformTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,23 @@
1010
public class MySqlPlatformTest {
1111

1212
MySqlPlatform mySqlPlatform = new MySqlPlatform();
13-
13+
private static int X = 0xFFFFFF;
1414
@Test
1515
public void testTypeConversion() {
1616
PlatformDdl ddl = PlatformDdlBuilder.create(mySqlPlatform);
1717
assertThat(ddl.convert("clob")).isEqualTo("longtext");
18+
assertThat(ddl.convert("clob(65535)")).isEqualTo("text");
19+
assertThat(ddl.convert("clob(65536)")).isEqualTo("mediumtext");
20+
assertThat(ddl.convert("clob(16777215)")).isEqualTo("mediumtext");
21+
assertThat(ddl.convert("clob(16777216)")).isEqualTo("longtext");
1822
assertThat(ddl.convert("json")).isEqualTo("json");
1923
assertThat(ddl.convert("jsonb")).isEqualTo("json");
2024
assertThat(ddl.convert("varchar(20)")).isEqualTo("varchar(20)");
2125
assertThat(ddl.convert("boolean")).isEqualTo("tinyint(1)");
2226
assertThat(ddl.convert("bit")).isEqualTo("tinyint(1)");
2327
assertThat(ddl.convert("decimal")).isEqualTo("decimal(16,3)");
28+
29+
2430
}
2531

2632
}

ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/SqlserverPlatformTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void testTypeConversion() {
1919
PlatformDdl ddl = PlatformDdlBuilder.create(platform);
2020

2121
assertThat(ddl.convert("clob")).isEqualTo("nvarchar(max)");
22-
assertThat(ddl.convert("blob")).isEqualTo("image");
22+
assertThat(ddl.convert("blob")).isEqualTo("varbinary(max)");
2323
assertThat(ddl.convert("json")).isEqualTo("nvarchar(max)");
2424
assertThat(ddl.convert("jsonb")).isEqualTo("nvarchar(max)");
2525

@@ -32,6 +32,10 @@ public void testTypeConversion() {
3232
assertThat(ddl.convert("bit")).isEqualTo("bit");
3333
assertThat(ddl.convert("tinyint")).isEqualTo("smallint");
3434
assertThat(ddl.convert("binary(16)")).isEqualTo("binary(16)");
35+
36+
assertThat(ddl.convert("varchar")).isEqualTo("nvarchar(255)");
37+
assertThat(ddl.convert("varchar(4000)")).isEqualTo("nvarchar(4000)");
38+
assertThat(ddl.convert("varchar(4001)")).isEqualTo("nvarchar(max)");
3539
}
3640

3741
@Test

ebean-test/src/main/java/io/ebean/test/config/platform/ClickHouseSetup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public Properties setup(Config config) {
1212
config.setUsername("default");
1313
config.setPassword("");
1414
config.setUrl("jdbc:clickhouse://${host}:${port}/${databaseName}");
15-
config.setDriver("ru.yandex.clickhouse.ClickHouseDriver");
15+
config.setDriver("com.clickhouse.jdbc.ClickHouseDriver");
1616
config.datasourceDefaults();
1717

1818
return dockerProperties(config);

ebean-test/src/test/java/io/ebean/xtest/config/dbplatform/DbTypeMapTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ void testLookupRender_given_sqlserver17() {
6262
assertThat(dbTypeMap.lookup("json", false).renderType(0, 0)).isEqualTo("nvarchar(max)");
6363
assertThat(dbTypeMap.lookup("jsonb", false).renderType(0, 0)).isEqualTo("nvarchar(max)");
6464
assertThat(dbTypeMap.lookup("jsonclob", false).renderType(0, 0)).isEqualTo("nvarchar(max)");
65-
assertThat(dbTypeMap.lookup("jsonblob", false).renderType(0, 0)).isEqualTo("image");
65+
assertThat(dbTypeMap.lookup("jsonblob", false).renderType(0, 0)).isEqualTo("varbinary(max)");
6666
assertThat(dbTypeMap.lookup("jsonvarchar", false).renderType(200, 0)).isEqualTo("nvarchar(200)");
6767
}
6868

ebean-test/src/test/java/io/ebean/xtest/dbmigration/DbMigrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public void testRunMigration() throws IOException, SQLException {
5757
"migtest_ckey_detail",
5858
"migtest_ckey_parent",
5959
"migtest_e_basic",
60+
"migtest_e_test_binary",
61+
"migtest_e_test_varchar",
62+
"migtest_e_test_lob",
63+
"migtest_e_test_json",
6064
"migtest_e_enum",
6165
"migtest_e_history",
6266
"migtest_e_history2",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package misc.migration.v1_1;
2+
3+
import javax.persistence.Entity;
4+
import javax.persistence.Id;
5+
import javax.persistence.Table;
6+
import javax.validation.constraints.Size;
7+
8+
@Entity
9+
@Table(name = "migtest_e_test_binary")
10+
public class ETestBinary {
11+
12+
@Id
13+
int id;
14+
15+
@Size(max = 16)
16+
byte[] test_byte16;
17+
18+
@Size(max = 256)
19+
byte[] test_byte256;
20+
21+
@Size(max = 512)
22+
byte[] test_byte512;
23+
24+
@Size(max = 1024)
25+
byte[] test_byte1k;
26+
27+
@Size(max = 2 * 1024)
28+
byte[] test_byte2k;
29+
30+
@Size(max = 4 * 1024)
31+
byte[] test_byte4k;
32+
33+
@Size(max = 8 * 1024)
34+
byte[] test_byte8k;
35+
36+
@Size(max = 16 * 1024)
37+
byte[] test_byte16k;
38+
39+
@Size(max = 32 * 1024)
40+
byte[] test_byte32k;
41+
42+
@Size(max = 64 * 1024)
43+
byte[] test_byte64k;
44+
45+
@Size(max = 128 * 1024)
46+
byte[] test_byte128k;
47+
48+
@Size(max = 256 * 1024)
49+
byte[] test_byte256k;
50+
51+
@Size(max = 512 * 1024)
52+
byte[] test_byte512k;
53+
54+
@Size(max = 1024 * 1024)
55+
byte[] test_byte1m;
56+
57+
@Size(max = 2 * 1024 * 1024)
58+
byte[] test_byte2m;
59+
60+
@Size(max = 4 * 1024 * 1024)
61+
byte[] test_byte4m;
62+
63+
@Size(max = 8 * 1024 * 1024)
64+
byte[] test_byte8m;
65+
66+
@Size(max = 16 * 1024 * 1024)
67+
byte[] test_byte16m;
68+
69+
@Size(max = 32 * 1024 * 1024)
70+
byte[] test_byte32m;
71+
72+
}

0 commit comments

Comments
 (0)