Skip to content

Commit 4756abb

Browse files
authored
add support for enum data type in MySQL (#620)
Signed-off-by: Billy Yuan <billy112487983@gmail.com>
1 parent ca6c8b8 commit 4756abb

File tree

5 files changed

+95
-3
lines changed

5 files changed

+95
-3
lines changed

vertx-mysql-client/src/main/asciidoc/index.adoc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,24 @@ The {@link io.vertx.sqlclient.data.Numeric} Java type is used to represent the M
347347
{@link examples.MySQLClientExamples#numericExample(io.vertx.sqlclient.Row)}
348348
----
349349

350+
=== Handling ENUM
351+
352+
MySQL supports ENUM data type and the client retrieves these types as String data type.
353+
354+
You can encode Java enums as String like this:
355+
356+
[source,$lang]
357+
----
358+
{@link examples.MySQLClientExamples#enumeratedType01Example}
359+
----
360+
361+
You can retrieve the ENUM column as Java enums like this:
362+
363+
[source,$lang]
364+
----
365+
{@link examples.MySQLClientExamples#enumeratedType02Example}
366+
----
367+
350368
=== Handling GEOMETRY
351369

352370
MYSQL `GEOMETRY` data type is also supported, Here are some examples showing that you can handle the geometry data in Well-Known Text (WKT) format or Well-Known Binary (WKB) format, the data are decoded as MySQL TEXT OR BLOB data type. There are many great third-party libraries for handling data in this format.

vertx-mysql-client/src/main/java/examples/MySQLClientExamples.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,32 @@ public void numericExample(Row row) {
311311
}
312312
}
313313

314+
enum Color {
315+
red
316+
}
317+
318+
public void enumeratedType01Example(SqlClient client) {
319+
client
320+
.preparedQuery("INSERT INTO colors VALUES (?)")
321+
.execute(Tuple.of(Color.red), res -> {
322+
// ...
323+
});
324+
}
325+
326+
public void enumeratedType02Example(SqlClient client) {
327+
client
328+
.preparedQuery("SELECT color FROM colors")
329+
.execute()
330+
.onComplete(res -> {
331+
if (res.succeeded()) {
332+
RowSet<Row> rows = res.result();
333+
for (Row row : rows) {
334+
System.out.println(row.get(Color.class, "color"));
335+
}
336+
}
337+
});
338+
}
339+
314340
public void geometryExample01(SqlClient client) {
315341
client
316342
.query("SELECT ST_AsText(g) FROM geom;")

vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public <T> T get(Class<T> type, int position) {
8888
return type.cast(getMultiPolygon(position));
8989
} else if (type == GeometryCollection.class) {
9090
return type.cast(getGeometryCollection(position));
91+
} else if (type.isEnum()) {
92+
return type.cast(getEnum(type, position));
9193
} else {
9294
throw new UnsupportedOperationException("Unsupported type " + type.getName());
9395
}
@@ -326,6 +328,22 @@ public LocalTime getLocalTime(int pos) {
326328
}
327329
}
328330

331+
private Object getEnum(Class enumType, int position) {
332+
Object val = getValue(position);
333+
if (val instanceof String) {
334+
return Enum.valueOf(enumType, (String) val);
335+
} else if (val instanceof Number) {
336+
int ordinal = ((Number) val).intValue();
337+
if (ordinal >= 0) {
338+
Object[] constants = enumType.getEnumConstants();
339+
if (ordinal < constants.length) {
340+
return constants[ordinal];
341+
}
342+
}
343+
}
344+
return null;
345+
}
346+
329347
private <T> String buildIllegalAccessMessage(Object value, String columnName, Class<T> clazz) {
330348
return String.format("Can not retrieve row value[%s] as class[%s], columnName=[%s]", value.toString(), clazz.getName(), columnName);
331349
}

vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ public static void encodeBinary(DataType dataType, Object value, Charset charset
183183
} else if (value == Tuple.JSON_NULL) {
184184
// we have to make JSON literal null send as a STRING data type
185185
BufferUtils.writeLengthEncodedString(buffer, "null", charset);
186+
} else if (value instanceof Enum) {
187+
binaryEncodeText(((Enum<?>)value).name(), buffer, charset);
186188
} else {
187189
binaryEncodeText(String.valueOf(value), buffer, charset);
188190
}

vertx-mysql-client/src/test/java/io/vertx/mysqlclient/data/StringDataTypeTest.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
@RunWith(VertxUnitRunner.class)
2323
public class StringDataTypeTest extends MySQLDataTypeTestBase {
24+
private enum Size {
25+
x_small, small, medium, large, x_large;
26+
}
27+
2428
@Test
2529
public void testBinaryDecodeAll(TestContext ctx) {
2630
MySQLConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
@@ -212,20 +216,44 @@ public void testBinaryDecodeLongText(TestContext ctx) {
212216
}
213217

214218
@Test
215-
public void testBinaryEncodeEnum(TestContext ctx) {
219+
public void testBinaryEncodeEnumWithString(TestContext ctx) {
216220
testBinaryEncodeGeneric(ctx, "test_enum", "medium");
217221
}
218222

219223
@Test
220-
public void testTextDecodeEnum(TestContext ctx) {
224+
public void testTextDecodeEnumToString(TestContext ctx) {
221225
testTextDecodeGenericWithTable(ctx, "test_enum", "small");
222226
}
223227

224228
@Test
225-
public void testBinaryDecodeEnum(TestContext ctx) {
229+
public void testBinaryDecodeEnumToString(TestContext ctx) {
226230
testBinaryDecodeGenericWithTable(ctx, "test_enum", "small");
227231
}
228232

233+
@Test
234+
public void testBinaryEncodeEnumWithJavaEnum(TestContext ctx) {
235+
testBinaryEncodeGeneric(ctx, "test_enum", Size.medium, ((row, colName) -> {
236+
ctx.assertEquals(Size.medium, row.get(Size.class, colName));
237+
ctx.assertEquals(Size.medium, row.get(Size.class, 0));
238+
}));
239+
}
240+
241+
@Test
242+
public void testTextDecodeEnumToJavaEnum(TestContext ctx) {
243+
testTextDecodeGenericWithTable(ctx, "test_enum", ((row, colName) -> {
244+
ctx.assertEquals(Size.small, row.get(Size.class, colName));
245+
ctx.assertEquals(Size.small, row.get(Size.class, 0));
246+
}));
247+
}
248+
249+
@Test
250+
public void testBinaryDecodeEnumToJavaEnum(TestContext ctx) {
251+
testBinaryDecodeGenericWithTable(ctx, "test_enum", ((row, colName) -> {
252+
ctx.assertEquals(Size.small, row.get(Size.class, colName));
253+
ctx.assertEquals(Size.small, row.get(Size.class, 0));
254+
}));
255+
}
256+
229257
@Test
230258
public void testBinaryEncodeSet(TestContext ctx) {
231259
testBinaryEncodeGeneric(ctx, "test_set", "a,b,c");

0 commit comments

Comments
 (0)