From 8036db5c1797d50d80f50bd4c0336b4963265be3 Mon Sep 17 00:00:00 2001 From: turakamou Date: Wed, 19 Feb 2025 07:17:08 +0100 Subject: [PATCH 1/4] simple fix of oracle stream API for RAW column Signed-off-by: turakamou --- .../io/vertx/oracleclient/impl/RowReader.java | 3 +++ .../OracleBinaryDataTypesTest.java | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java index 051725a30..e8eecb17a 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java @@ -187,6 +187,9 @@ private static Row transform(List ors, RowDesc desc, oracle.jdbc.OracleR private static Class getType(String cn) { try { + if (cn.equals(byte[].class.getName())) { + return byte[].class; + } return OraclePreparedQueryCommand.class.getClassLoader().loadClass(cn); } catch (ClassNotFoundException e) { return null; diff --git a/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java b/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java index 5d01fed0f..fd929ef1b 100644 --- a/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java +++ b/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java @@ -101,6 +101,28 @@ private void testDecode(TestContext ctx, String columnName, JDBCType jdbcTyp })); } + private void testDecodeUsingStream(TestContext ctx, String columnName, JDBCType jdbcType, Buffer expected) { + pool.getConnection(ctx.asyncAssertSuccess(conn -> { + conn.prepare("SELECT " + columnName + " FROM binary_data_types WHERE id = 1") + .onComplete(ctx.asyncAssertSuccess(preparedStatement -> { + preparedStatement.cursor().read(10).onComplete(ctx.asyncAssertSuccess(result -> { + ctx.assertEquals(1, result.size()); + Row row = result.iterator().next(); + ctx.assertEquals(expected, row.get(Buffer.class, 0)); + ctx.assertEquals(expected, row.get(Buffer.class, columnName)); + ColumnDescriptor columnDescriptor = result.columnDescriptors().get(0); + ctx.assertEquals(jdbcType, columnDescriptor.jdbcType()); + ctx.assertNotNull(columnDescriptor); + })); + })); + })); + } + + @Test + public void testDecodeRawUsingStream(TestContext ctx) { + testDecodeUsingStream(ctx, "test_raw", JDBCType.VARBINARY, Buffer.buffer("See you space cowboy...")); + } + @Test public void testEncodeNull(TestContext ctx) { pool From 83c2dedf856ac66ba0305b241aa3152941b24b43 Mon Sep 17 00:00:00 2001 From: turakamou Date: Fri, 14 Mar 2025 09:43:12 +0100 Subject: [PATCH 2/4] fixup! simple fix of oracle stream API for RAW column Oracle will return "[B" as class name for byte[], I don't know why the class loader is not able to load this. So when we try to call getObject for this column, it is called with null class argument. So let's return the correct class in this case. Signed-off-by: turakamou --- .../src/main/java/io/vertx/oracleclient/impl/RowReader.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java index e8eecb17a..f06f24ebe 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java @@ -38,6 +38,7 @@ public class RowReader implements Flow.Subscriber, Function { private static final Logger LOG = LoggerFactory.getLogger(RowReader.class); + private static final String byteArrayClassName = byte[].class.getName(); private final ContextInternal context; private final List types; @@ -187,7 +188,9 @@ private static Row transform(List ors, RowDesc desc, oracle.jdbc.OracleR private static Class getType(String cn) { try { - if (cn.equals(byte[].class.getName())) { + // Oracle will return "[B" as class name for byte[], I don't know why the class loader is not able to load this + // So let's return the correct class in this case + if (cn.equals(byteArrayClassName)) { return byte[].class; } return OraclePreparedQueryCommand.class.getClassLoader().loadClass(cn); From 2b22fecf2b2b714bfc79a436ef05a2346620a7fe Mon Sep 17 00:00:00 2001 From: turakamou Date: Fri, 14 Mar 2025 09:55:18 +0100 Subject: [PATCH 3/4] fixup! simple fix of oracle stream API for RAW column Fix unit test for master Signed-off-by: turakamou --- .../test/java/tests/oracleclient/OracleBinaryDataTypesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java b/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java index fd929ef1b..c277770da 100644 --- a/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java +++ b/vertx-oracle-client/src/test/java/tests/oracleclient/OracleBinaryDataTypesTest.java @@ -102,7 +102,7 @@ private void testDecode(TestContext ctx, String columnName, JDBCType jdbcTyp } private void testDecodeUsingStream(TestContext ctx, String columnName, JDBCType jdbcType, Buffer expected) { - pool.getConnection(ctx.asyncAssertSuccess(conn -> { + pool.getConnection().onComplete(ctx.asyncAssertSuccess(conn -> { conn.prepare("SELECT " + columnName + " FROM binary_data_types WHERE id = 1") .onComplete(ctx.asyncAssertSuccess(preparedStatement -> { preparedStatement.cursor().read(10).onComplete(ctx.asyncAssertSuccess(result -> { From 321dfd270e8e788b325de3ee08ec80d4ef1e2ace Mon Sep 17 00:00:00 2001 From: turakamou Date: Mon, 17 Mar 2025 08:54:23 +0100 Subject: [PATCH 4/4] simple fix of oracle stream API for RAW column Take into account tsegismont review comments Signed-off-by: turakamou --- .../io/vertx/oracleclient/impl/RowReader.java | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java index f06f24ebe..4348047fd 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java @@ -16,7 +16,6 @@ import io.vertx.core.internal.logging.Logger; import io.vertx.core.internal.logging.LoggerFactory; import io.vertx.oracleclient.OracleException; -import io.vertx.oracleclient.impl.commands.OraclePreparedQueryCommand; import io.vertx.oracleclient.impl.commands.OracleResponse; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.internal.RowDesc; @@ -38,10 +37,9 @@ public class RowReader implements Flow.Subscriber, Function { private static final Logger LOG = LoggerFactory.getLogger(RowReader.class); - private static final String byteArrayClassName = byte[].class.getName(); private final ContextInternal context; - private final List types; + private final List> classes; private final RowDesc description; private final Statement resultSetStatement; @@ -64,9 +62,9 @@ public RowReader(ContextInternal context, Collector collector, Oracle resultSetStatement = ors.getStatement(); ResultSetMetaData metaData = ors.getMetaData(); int cols = metaData.getColumnCount(); - types = new ArrayList<>(cols); + classes = new ArrayList<>(cols); for (int i = 1; i <= cols; i++) { - types.add(metaData.getColumnClassName(i)); + classes.add(getType(metaData.getColumnClassName(i))); } Flow.Publisher publisher = ors.publisherOracle(this); description = OracleRowDesc.create(metaData); @@ -171,16 +169,16 @@ private OracleResponse createResponse() { @Override public Row apply(oracle.jdbc.OracleRow oracleRow) { try { - return transform(types, description, oracleRow); + return transform(classes, description, oracleRow); } catch (SQLException e) { throw new OracleException(e); } } - private static Row transform(List ors, RowDesc desc, oracle.jdbc.OracleRow or) throws SQLException { + private static Row transform(List> classes, RowDesc desc, oracle.jdbc.OracleRow or) throws SQLException { Row row = new OracleRow(desc); for (int i = 1; i <= desc.columnNames().size(); i++) { - Object res = convertSqlValue(or.getObject(i, getType(ors.get(i - 1)))); + Object res = convertSqlValue(or.getObject(i, classes.get(i - 1))); row.addValue(res); } return row; @@ -188,12 +186,7 @@ private static Row transform(List ors, RowDesc desc, oracle.jdbc.OracleR private static Class getType(String cn) { try { - // Oracle will return "[B" as class name for byte[], I don't know why the class loader is not able to load this - // So let's return the correct class in this case - if (cn.equals(byteArrayClassName)) { - return byte[].class; - } - return OraclePreparedQueryCommand.class.getClassLoader().loadClass(cn); + return Class.forName(cn, true, RowReader.class.getClassLoader()); } catch (ClassNotFoundException e) { return null; }