From 58ebdbce7c8d379f182c1e2768ca6f76d3aa9c2f Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Thu, 5 Feb 2026 16:10:22 +0100 Subject: [PATCH] Configurable statement options for Oracle Client In the Vert.x JDBC Client, it is possible to configure different statement options in JDBCConnectOptions: - query timeout - max rows - fetch direction - fetch size This change provides a similar feature for the Reactive Oracle Client. Signed-off-by: Thomas Segismont --- .../io/vertx/oracleclient/FetchDirection.java | 33 ++++++++++ .../oracleclient/OracleConnectOptions.java | 60 ++++++++++++++++++- .../impl/OracleJdbcConnection.java | 23 +++---- .../impl/commands/OracleCommand.java | 22 ++++++- .../commands/OracleCursorQueryCommand.java | 10 ++-- .../OraclePrepareStatementCommand.java | 9 ++- ...a => OraclePreparedBatchQueryCommand.java} | 8 +-- .../commands/OraclePreparedQueryCommand.java | 6 +- .../impl/commands/OracleQueryCommand.java | 8 ++- .../commands/OracleSimpleQueryCommand.java | 10 ++-- 10 files changed, 151 insertions(+), 38 deletions(-) create mode 100644 vertx-oracle-client/src/main/java/io/vertx/oracleclient/FetchDirection.java rename vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/{OraclePreparedBatchQuery.java => OraclePreparedBatchQueryCommand.java} (88%) diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/FetchDirection.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/FetchDirection.java new file mode 100644 index 0000000000..f2fc0c14d9 --- /dev/null +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/FetchDirection.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package io.vertx.oracleclient; + +import java.sql.ResultSet; + +/** + * Represents the fetch direction hint + */ +public enum FetchDirection { + + FORWARD(ResultSet.FETCH_FORWARD), + REVERSE(ResultSet.FETCH_REVERSE), + UNKNOWN(ResultSet.FETCH_UNKNOWN); + + private final int type; + + FetchDirection(int type) { + this.type = type; + } + + public int getType() { + return type; + } +} diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java index b4ee520216..025f3dbf00 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -52,6 +52,12 @@ public static OracleConnectOptions wrap(SqlConnectOptions options) { private String tnsAdmin; private boolean ssl; + private int queryTimeout; + private int maxRows; + private FetchDirection fetchDirection; + private int fetchSize; + + public OracleConnectOptions() { super(); } @@ -69,6 +75,10 @@ private void copyFields(OracleConnectOptions other) { this.tnsAlias = other.tnsAlias; this.tnsAdmin = other.tnsAdmin; this.ssl = other.ssl; + this.queryTimeout = other.queryTimeout; + this.maxRows = other.maxRows; + this.fetchDirection = other.fetchDirection; + this.fetchSize = other.fetchSize; } public OracleConnectOptions(SqlConnectOptions options) { @@ -208,6 +218,54 @@ public OracleConnectOptions setTnsAdmin(String tnsAdmin) { return this; } + public int getQueryTimeout() { + return queryTimeout; + } + + /** + * @see java.sql.PreparedStatement#setQueryTimeout(int) + */ + public OracleConnectOptions setQueryTimeout(int queryTimeout) { + this.queryTimeout = queryTimeout; + return this; + } + + public int getMaxRows() { + return maxRows; + } + + /** + * @see java.sql.PreparedStatement#setMaxRows(int) + */ + public OracleConnectOptions setMaxRows(int maxRows) { + this.maxRows = maxRows; + return this; + } + + public FetchDirection getFetchDirection() { + return fetchDirection; + } + + /** + * @see java.sql.PreparedStatement#setFetchDirection(int) + */ + public OracleConnectOptions setFetchDirection(FetchDirection fetchDirection) { + this.fetchDirection = fetchDirection; + return this; + } + + public int getFetchSize() { + return fetchSize; + } + + /** + * @see java.sql.PreparedStatement#setFetchSize(int) + */ + public OracleConnectOptions setFetchSize(int fetchSize) { + this.fetchSize = fetchSize; + return this; + } + // Non-specific options @Override diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java index 6971788725..e0790416b6 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -20,17 +20,10 @@ import io.vertx.core.tracing.TracingPolicy; import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.oracleclient.impl.commands.*; -import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.spi.connection.ConnectionContext; -import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; -import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; -import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; -import io.vertx.sqlclient.spi.protocol.CommandBase; -import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; -import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; -import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; -import io.vertx.sqlclient.spi.protocol.TxCommand; +import io.vertx.sqlclient.spi.protocol.*; import oracle.jdbc.OracleConnection; import java.sql.SQLException; @@ -206,9 +199,9 @@ private void checkPending() { private OracleCommand wrap(CommandBase cmd) { OracleCommand action; if (cmd instanceof SimpleQueryCommand) { - action = OracleSimpleQueryCommand.create(connection, context, (SimpleQueryCommand) cmd); + action = OracleSimpleQueryCommand.create(connection, context, (SimpleQueryCommand) cmd, options); } else if (cmd instanceof PrepareStatementCommand) { - action = new OraclePrepareStatementCommand(connection, context, (PrepareStatementCommand) cmd); + action = new OraclePrepareStatementCommand(connection, context, (PrepareStatementCommand) cmd, options); } else if (cmd instanceof ExtendedQueryCommand) { action = forExtendedQuery((ExtendedQueryCommand) cmd); } else if (cmd instanceof TxCommand) { @@ -236,12 +229,12 @@ private OracleCommand forExtendedQuery(ExtendedQueryCommand cmd) { if (rowReader != null) { action = OracleCursorFetchCommand.create(connection, context, cmd, rowReader); } else { - action = OracleCursorQueryCommand.create(connection, context, cmd, cmd.collector(), rr -> cursors.put(cursorId, rr)); + action = OracleCursorQueryCommand.create(connection, context, cmd, cmd.collector(), rr -> cursors.put(cursorId, rr), options); } } else if (cmd.isBatch()) { - action = new OraclePreparedBatchQuery(connection, context, cmd, cmd.collector()); + action = new OraclePreparedBatchQueryCommand(connection, context, cmd, cmd.collector(), options); } else { - action = new OraclePreparedQueryCommand(connection, context, cmd, cmd.collector()); + action = new OraclePreparedQueryCommand(connection, context, cmd, cmd.collector(), options); } return action; } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java index 72ec84fca3..86df01853b 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -15,9 +15,12 @@ import io.vertx.core.Future; import io.vertx.core.Promise; import io.vertx.core.internal.ContextInternal; +import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.oracleclient.impl.Helper.SQLBlockingCodeHandler; import oracle.jdbc.OracleConnection; +import java.sql.SQLException; +import java.sql.Statement; import java.util.concurrent.Flow; import static io.vertx.oracleclient.impl.FailureUtil.sanitize; @@ -86,4 +89,21 @@ public void onComplete() { public final void fireResponse() { handler.complete(result.result(), result.cause()); } + + protected void applyStatementOptions(Statement stmt, OracleConnectOptions connectOptions) throws SQLException { + if (connectOptions != null) { + if (connectOptions.getQueryTimeout() > 0) { + stmt.setQueryTimeout(connectOptions.getQueryTimeout()); + } + if (connectOptions.getMaxRows() > 0) { + stmt.setMaxRows(connectOptions.getMaxRows()); + } + if (connectOptions.getFetchDirection() != null) { + stmt.setFetchDirection(connectOptions.getFetchDirection().getType()); + } + if (connectOptions.getFetchSize() > 0) { + stmt.setFetchSize(connectOptions.getFetchSize()); + } + } + } } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java index 07f8b84fd5..b100c17b1f 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -38,8 +38,8 @@ public class OracleCursorQueryCommand extends OracleQueryCommand { private final Collector collector; private final QueryResultHandler resultHandler; - private OracleCursorQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector, Consumer> store) { - super(oracleConnection, connectionContext, collector); + private OracleCursorQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector, Consumer> store, io.vertx.oracleclient.OracleConnectOptions connectOptions) { + super(oracleConnection, connectionContext, collector, connectOptions); sql = cmd.sql(); fetch = cmd.fetch(); params = cmd.params(); @@ -49,8 +49,8 @@ private OracleCursorQueryCommand(OracleConnection oracleConnection, ContextInter this.store = store; } - public static OracleCursorQueryCommand create(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector, Consumer> store) { - return new OracleCursorQueryCommand<>(oracleConnection, connectionContext, cmd, collector, store); + public static OracleCursorQueryCommand create(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector, Consumer> store, io.vertx.oracleclient.OracleConnectOptions connectOptions) { + return new OracleCursorQueryCommand<>(oracleConnection, connectionContext, cmd, collector, store, connectOptions); } @Override diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java index 2242c3e22b..284775ca6d 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -13,6 +13,7 @@ import io.vertx.core.Future; import io.vertx.core.internal.ContextInternal; import io.vertx.core.json.JsonArray; +import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.oracleclient.OraclePrepareOptions; import io.vertx.sqlclient.internal.PreparedStatement; import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; @@ -25,11 +26,13 @@ public class OraclePrepareStatementCommand extends OracleCommand prepareWithAutoGeneratedIndexes() { keys[i] = indexes.getInteger(i); } try (java.sql.PreparedStatement statement = oracleConnection.prepareStatement(sql, keys)) { + applyStatementOptions(statement, connectOptions); return new OraclePreparedStatement(sql, statement); } } @@ -65,6 +69,7 @@ private Future prepareWithAutoGeneratedIndexes() { keys[i] = indexes.getString(i); } try (java.sql.PreparedStatement statement = oracleConnection.prepareStatement(sql, keys)) { + applyStatementOptions(statement, connectOptions); return new OraclePreparedStatement(sql, statement); } } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQuery.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQueryCommand.java similarity index 88% rename from vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQuery.java rename to vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQueryCommand.java index 6a32dc94e1..cc2274f325 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQuery.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQueryCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -33,14 +33,14 @@ import static io.vertx.oracleclient.impl.FailureUtil.sanitize; -public class OraclePreparedBatchQuery extends OracleQueryCommand { +public class OraclePreparedBatchQueryCommand extends OracleQueryCommand { private final String sql; private final List listParams; private final QueryResultHandler resultHandler; - public OraclePreparedBatchQuery(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector) { - super(oracleConnection, connectionContext, collector); + public OraclePreparedBatchQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector, io.vertx.oracleclient.OracleConnectOptions connectOptions) { + super(oracleConnection, connectionContext, collector, connectOptions); sql = cmd.sql(); listParams = cmd.paramsList(); resultHandler = cmd.resultHandler(); diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java index 0b4d92b8fe..58f1196922 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -33,8 +33,8 @@ public class OraclePreparedQueryCommand extends OracleQueryCommand { private final PrepareOptions prepareOptions; private final QueryResultHandler resultHandler; - public OraclePreparedQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector) { - super(oracleConnection, connectionContext, collector); + public OraclePreparedQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector, io.vertx.oracleclient.OracleConnectOptions connectOptions) { + super(oracleConnection, connectionContext, collector, connectOptions); sql = cmd.sql(); params = cmd.params(); prepareOptions = cmd.options(); diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java index d30ed317b9..a0c2a58695 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -16,6 +16,7 @@ import io.vertx.core.buffer.Buffer; import io.vertx.core.internal.ContextInternal; import io.vertx.core.json.JsonArray; +import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.oracleclient.OraclePrepareOptions; import io.vertx.oracleclient.data.Blob; import io.vertx.oracleclient.impl.Helper; @@ -40,10 +41,12 @@ public abstract class OracleQueryCommand extends OracleCommand { private final Collector collector; + private final OracleConnectOptions connectOptions; - protected OracleQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, Collector collector) { + protected OracleQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, Collector collector, io.vertx.oracleclient.OracleConnectOptions connectOptions) { super(oracleConnection, connectionContext); this.collector = collector; + this.connectOptions = connectOptions; } @Override @@ -126,6 +129,7 @@ private Future prepare(Connection conn, OraclePrepareOp ps = conn.prepareStatement(query()); } + applyStatementOptions(ps, connectOptions); fillStatement(ps, conn); return ps.unwrap(OraclePreparedStatement.class); diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java index 9c2e06b29d..e89cc2c4c2 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -29,14 +29,14 @@ public class OracleSimpleQueryCommand extends OracleQueryCommand { private final String sql; private final QueryResultHandler resultHandler; - private OracleSimpleQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, SimpleQueryCommand cmd, Collector collector) { - super(oracleConnection, connectionContext, collector); + private OracleSimpleQueryCommand(OracleConnection oracleConnection, ContextInternal connectionContext, SimpleQueryCommand cmd, Collector collector, io.vertx.oracleclient.OracleConnectOptions connectOptions) { + super(oracleConnection, connectionContext, collector, connectOptions); sql = cmd.sql(); resultHandler = cmd.resultHandler(); } - public static OracleSimpleQueryCommand create(OracleConnection oracleConnection, ContextInternal connectionContext, SimpleQueryCommand cmd) { - return new OracleSimpleQueryCommand<>(oracleConnection, connectionContext, cmd, cmd.collector()); + public static OracleSimpleQueryCommand create(OracleConnection oracleConnection, ContextInternal connectionContext, SimpleQueryCommand cmd, io.vertx.oracleclient.OracleConnectOptions connectOptions) { + return new OracleSimpleQueryCommand<>(oracleConnection, connectionContext, cmd, cmd.collector(), connectOptions); } @Override