From 31d81da8c49e7942ccc3edf603fc6f7ca1823683 Mon Sep 17 00:00:00 2001 From: mrgrew Date: Thu, 8 Aug 2019 22:33:15 -0400 Subject: [PATCH 1/5] Addresses issue #110 - Support for storing binary data --- src/main/asciidoc/index.adoc | 4 ++++ .../jdbc/impl/actions/JDBCStatementHelper.java | 14 ++++++++++---- .../ext/jdbc/impl/actions/OptimisticCastTest.java | 5 +++-- .../ext/jdbc/impl/actions/SQLConvertTest.java | 15 +++++++++------ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 8a324507..70fbe38f 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -206,6 +206,10 @@ a VARCHAR(36) column. For other engines UUID optimistic casting can be enabled u When this config is present UUIDs will be handled as a native type. +Storing data to a binary column encounters an issue because the internally stored Based64 encoding of the array +isn't recognized as a byte array. Enable optimistic casting of a Base64-encoded string to a byte[] using: + +{ "castBase64": true } == Use as OSGi bundle diff --git a/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java b/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java index 5cc8b714..231c78f8 100644 --- a/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java +++ b/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java @@ -16,6 +16,7 @@ package io.vertx.ext.jdbc.impl.actions; +import io.vertx.core.json.Json; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.core.impl.logging.Logger; @@ -41,10 +42,7 @@ import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZoneOffset; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.TimeZone; +import java.util.*; import java.util.regex.Pattern; import static java.time.format.DateTimeFormatter.*; @@ -63,8 +61,10 @@ public final class JDBCStatementHelper { private static final Pattern DATE = Pattern.compile("^\\d{4}-(?:0[0-9]|1[0-2])-[0-9]{2}$"); private static final Pattern TIME = Pattern.compile("^\\d{2}:\\d{2}:\\d{2}$"); private static final Pattern UUID = Pattern.compile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"); + private static final Pattern BASE64 = Pattern.compile("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)$"); private final boolean castUUID; + private final boolean castBase64; public JDBCStatementHelper() { this(new JsonObject()); @@ -72,6 +72,7 @@ public JDBCStatementHelper() { public JDBCStatementHelper(JsonObject config) { this.castUUID = config.getBoolean("castUUID", false); + this.castBase64 = config.getBoolean("castBase64", false); } public void fillStatement(PreparedStatement statement, JsonArray in) throws SQLException { @@ -302,6 +303,11 @@ public Object optimisticCast(String value) { return java.util.UUID.fromString(value); } + // possible byte[] + if (castBase64 && BASE64.matcher(value).matches()) { + return Base64.getDecoder().decode(value); + } + } catch (RuntimeException e) { log.debug(e); } diff --git a/src/test/java/io/vertx/ext/jdbc/impl/actions/OptimisticCastTest.java b/src/test/java/io/vertx/ext/jdbc/impl/actions/OptimisticCastTest.java index 545034d8..785327e9 100644 --- a/src/test/java/io/vertx/ext/jdbc/impl/actions/OptimisticCastTest.java +++ b/src/test/java/io/vertx/ext/jdbc/impl/actions/OptimisticCastTest.java @@ -13,7 +13,7 @@ @RunWith(Parameterized.class) public class OptimisticCastTest { - private JDBCStatementHelper helper = new JDBCStatementHelper(new JsonObject().put("castUUID", true)); + private JDBCStatementHelper helper = new JDBCStatementHelper(new JsonObject().put("castUUID", true).put("castBase64", true)); @Parameterized.Parameters public static Collection generateData() { @@ -23,6 +23,7 @@ public static Collection generateData() { {"2016-03-16", "java.sql.Date"}, {"2016-03-16T16:00:00Z", "java.sql.Timestamp"}, {"f47ac10b-58cc-4372-a567-0e02b2c3d479", "java.util.UUID"}, + {"Dyu+lY5vAxJhM8UCCOtk7w==", "[B"}, // bad variations {"2016-03-16T16:00:00", "java.lang.String"}, {"24:00:00", "java.lang.String"}, @@ -43,4 +44,4 @@ public OptimisticCastTest(String value, String expectedType) { public void testOptimisticCast() { assertEquals(value, expectedType, helper.optimisticCast(value).getClass().getName()); } -} \ No newline at end of file +} diff --git a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java index 4c620463..34c03152 100644 --- a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java +++ b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java @@ -1,5 +1,6 @@ package io.vertx.ext.jdbc.impl.actions; +import com.mysql.cj.core.util.Base64Decoder; import io.vertx.core.json.JsonObject; import org.junit.Test; import org.junit.runner.RunWith; @@ -9,10 +10,7 @@ import java.sql.SQLException; import java.time.ZoneId; import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.UUID; +import java.util.*; import static java.time.format.DateTimeFormatter.*; import static org.hamcrest.CoreMatchers.*; @@ -21,7 +19,7 @@ @RunWith(Parameterized.class) public class SQLConvertTest { - private JsonObject config = new JsonObject().put("castUUID", true); + private JsonObject config = new JsonObject().put("castUUID", true).put("castBase64", true); private JDBCStatementHelper helper = new JDBCStatementHelper(config); @@ -38,6 +36,7 @@ public static Collection generateData() { params.add(new Object[]{dateTime.toLocalDate().toString(), java.sql.Date.class}); params.add(new Object[]{"f47ac10b-58cc-4372-a567-0e02b2c3d479", UUID.class}); + params.add(new Object[]{"Dyu+lY5vAxJhM8UCCOtk7w==", byte[].class}); return params; } @@ -56,6 +55,10 @@ public void testSQLConvert() throws SQLException { assertThat(cast, instanceOf(expectedSqlType)); Object convert = JDBCStatementHelper.convertSqlValue(cast); - assertEquals(value, convert); + if ( convert instanceof byte[] ) { + assertArrayEquals(Base64.getDecoder().decode(value), (byte[])convert); + } else { + assertEquals(value, convert); + } } } From 9d59d9fb3f98b52d32a35e06a21b1c2a895bacc7 Mon Sep 17 00:00:00 2001 From: mrgrew Date: Wed, 4 Sep 2019 07:58:20 -0400 Subject: [PATCH 2/5] Remove extraneous import --- src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java index 34c03152..55ed0162 100644 --- a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java +++ b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java @@ -1,6 +1,5 @@ package io.vertx.ext.jdbc.impl.actions; -import com.mysql.cj.core.util.Base64Decoder; import io.vertx.core.json.JsonObject; import org.junit.Test; import org.junit.runner.RunWith; From a99f7eaa12d9490efed5a4bd7856bbe9ea46cdfa Mon Sep 17 00:00:00 2001 From: mrgrew Date: Wed, 4 Sep 2019 08:48:29 -0400 Subject: [PATCH 3/5] Arranged imports to better focus on the actual changes. --- .../vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java | 7 +++++-- .../io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java b/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java index 231c78f8..a3ff0b61 100644 --- a/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java +++ b/src/main/java/io/vertx/ext/jdbc/impl/actions/JDBCStatementHelper.java @@ -16,7 +16,6 @@ package io.vertx.ext.jdbc.impl.actions; -import io.vertx.core.json.Json; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.core.impl.logging.Logger; @@ -42,7 +41,11 @@ import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZoneOffset; -import java.util.*; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.TimeZone; import java.util.regex.Pattern; import static java.time.format.DateTimeFormatter.*; diff --git a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java index 55ed0162..338e9d2c 100644 --- a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java +++ b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java @@ -9,8 +9,11 @@ import java.sql.SQLException; import java.time.ZoneId; import java.time.ZonedDateTime; -import java.util.*; - +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collection; +import java.util.List; +import java.util.UUID; import static java.time.format.DateTimeFormatter.*; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; From 79f01b1b7f0460805b7a45bd932cfebe014a1818 Mon Sep 17 00:00:00 2001 From: mrgrew Date: Wed, 4 Sep 2019 08:51:52 -0400 Subject: [PATCH 4/5] Restore line munged by editor (software or person - take your pick) --- src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java index 338e9d2c..0e27657f 100644 --- a/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java +++ b/src/test/java/io/vertx/ext/jdbc/impl/actions/SQLConvertTest.java @@ -14,6 +14,7 @@ import java.util.Collection; import java.util.List; import java.util.UUID; + import static java.time.format.DateTimeFormatter.*; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; From 8d452a3e38bef740248d95eb0f8e1798354af567 Mon Sep 17 00:00:00 2001 From: mrgrew Date: Sun, 15 Sep 2019 20:05:04 -0400 Subject: [PATCH 5/5] Add whitespace to trigger build --- src/main/asciidoc/index.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 70fbe38f..bc4b9a58 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -206,6 +206,7 @@ a VARCHAR(36) column. For other engines UUID optimistic casting can be enabled u When this config is present UUIDs will be handled as a native type. + Storing data to a binary column encounters an issue because the internally stored Based64 encoding of the array isn't recognized as a byte array. Enable optimistic casting of a Base64-encoded string to a byte[] using: