Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
bd2fd48
Add TOML media type (#12082)
tomas-langer Jun 9, 2026
d66d38b
27.x: upgrade jackson, typesafe-config, snakeyaml (#11998)
barchetta Jun 9, 2026
eef416f
Adds data/runtime, data/jdbc/jdbc, and data/jdbc/executor modules
ljnelson Apr 15, 2026
8f1caf1
Squashable commit; refactoring
ljnelson Apr 15, 2026
1bb02dd
Squashable commit; refactoring
ljnelson Apr 15, 2026
f2ab2fb
Squashable commit; introduces data/plan modules; adds data/jdbc/named…
ljnelson Apr 16, 2026
a64eea1
Squashable commit; adds typeMap to connection state and JdbcPlanImpl
ljnelson Apr 16, 2026
86cd8fd
Squashable commit; ensure typeMap is immutable
ljnelson Apr 16, 2026
61f48f7
Squashable commit; ensuring clientInfo is copied
ljnelson Apr 16, 2026
3fe3e9c
Squashable commit; binding view implemented
ljnelson Apr 16, 2026
e238112
Squashable commit; introduces simple generic argument processing in J…
ljnelson Apr 16, 2026
8de10c7
Squashable commit; introduces JDBC transactions skeletally; tweaks Na…
ljnelson Apr 16, 2026
700481d
Squashable commit; JDBC transaction engine now functionally complete
ljnelson Apr 17, 2026
4a50381
Squashable commit; refactoring
ljnelson Apr 19, 2026
19e8eb2
Squashable commit; adds transformation abilities to plan/jdbc; adds t…
ljnelson Apr 21, 2026
69360c3
Squashable commit; moved poor-man's integration test of JDBC Transact…
ljnelson Apr 21, 2026
ff649d4
Squashable commit; refactoring
ljnelson Apr 23, 2026
7238919
Squashable commit; refactoring; JdbcResults now supports multiple sta…
ljnelson Apr 24, 2026
850e450
Squashable commit; refactoring; adds support for batch execution
ljnelson Apr 24, 2026
a2815b6
Squashable commit; refactoring; cleaning up naming
ljnelson Apr 24, 2026
0e72009
Squashable commit; refactoring; runtime layer first cut complete
ljnelson Apr 28, 2026
a3b6cbc
Squashable commit; refactoring and documentation
ljnelson May 11, 2026
dcdfda0
Squashable commit; interim checking before rebasing
ljnelson May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Squashable commit; refactoring; adds support for batch execution
Signed-off-by: Laird Nelson <laird.nelson@oracle.com>
  • Loading branch information
ljnelson committed Jun 10, 2026
commit 850e4503a004cf469df201a5a4987b51ed6e4adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2026 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.helidon.data.jdbc;

import java.sql.SQLException;

/**
* A {@link JdbcResult} providing access to the results of {@linkplain java.sql.Statement#executeBatch() a batch
* execution}.
*
* @see #batchExecutionResults()
*/
public non-sealed interface JdbcBatchExecutionResults extends JdbcResult {

/**
* Returns the results of the batch execution.
*
* @return a non-{@code null} {@code long} array containing a mix of update counts and status indicators
* @throws SQLException if a database error occurs
* @see java.sql.Statement#executeLargeBatch()
* @see java.sql.Statement#EXECUTE_FAILED
* @see java.sql.Statement#SUCCESS_NO_INFO
*/
long[] batchExecutionResults() throws SQLException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2026 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.helidon.data.jdbc;

import java.sql.CallableStatement;
import java.sql.SQLException;
import java.util.NoSuchElementException;

import static java.util.Objects.requireNonNull;

final class JdbcBatchExecutionResultsImpl implements JdbcBatchExecutionResults {

private static final long[] EMPTY_LONG_ARRAY = new long[0];

private final long[] results;

JdbcBatchExecutionResultsImpl(long[] results) {
super();
this.results = results == null || results.length == 0 ? EMPTY_LONG_ARRAY : results.clone();
}

@Override // JdbcBatchExecutionResults
public long[] batchExecutionResults() {
return this.results;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
* @see JdbcResultSet
* @see JdbcUpdateCount
* @see JdbcOutValues
* @see JdbcBatchExecutionResults
* @see JdbcResults
* @see java.sql.Statement#execute(String)
* @see java.sql.PreparedStatement#execute()
* @see java.sql.Statement#executeLargeBatch()
*/
public sealed interface JdbcResult permits JdbcResultSet, JdbcUpdateCount, JdbcOutValues {
public sealed interface JdbcResult permits JdbcResultSet, JdbcUpdateCount, JdbcOutValues, JdbcBatchExecutionResults {
}
89 changes: 79 additions & 10 deletions data/jdbc/jdbc/src/main/java/io/helidon/data/jdbc/JdbcResults.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public interface JdbcResults extends JdbcOpen, JdbcWarningsBearing {
*
* @return {@code true} if and only if advancement was successful
* @throws IllegalStateException if this {@link JdbcResults} is {@linkplain #close() closed}
* @throws java.sql.BatchUpdateException if advancement resulted in a batch execution and it failed
* @throws SQLException if a database error occurs
* @see #get()
*/
Expand Down Expand Up @@ -423,6 +424,8 @@ final class Preparation {

private final Statement statement;

private final boolean batch;

private final String sql;

private final GeneratedKeysBehavior generatedKeysBehavior;
Expand All @@ -449,6 +452,7 @@ final class Preparation {
*/
public Preparation(PreparedStatement ps) {
this(ps,
false,
null,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -468,6 +472,7 @@ public Preparation(PreparedStatement ps) {
*/
public Preparation(PreparedStatement ps, ResultsAdvancementBehavior resultsAdvancementBehavior) {
this(ps,
false,
null,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -487,6 +492,7 @@ public Preparation(PreparedStatement ps, ResultsAdvancementBehavior resultsAdvan
*/
public Preparation(CallableStatement cs, int[] outParameterIndices) {
this(cs,
false,
null,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -510,6 +516,7 @@ public Preparation(CallableStatement cs,
ResultsAdvancementBehavior resultsAdvancementBehavior,
int[] outParameterIndices) {
this(cs,
false,
null,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -519,6 +526,28 @@ public Preparation(CallableStatement cs,
outParameterIndices);
}

/**
* Creates a new {@link Preparation}.
*
* @param s a non-{@code null} {@link Statement}
* @param batchExecution a {@code boolean} which, if {@code true}, indicates that a {@linkplain
* Statement#executeLargeBatch() batch execution} is being requested; if {@code false} then {@code s} must be a
* {@link PreparedStatement}
* @throws NullPointerException if any argument is {@code null}
* @throws IllegalArgumentException if {@code batchExecution} is {@code false} and {@code s} is not a {@link PreparedStatement}
*/
public Preparation(Statement s, boolean batchExecution) {
this(s,
batchExecution,
null,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
EMPTY_STRING_ARRAY,
null,
ResultsAdvancementBehavior.CLOSE_CURRENT_RESULT,
EMPTY_INT_ARRAY);
}

/**
* Creates a new {@link Preparation}.
*
Expand All @@ -528,6 +557,7 @@ public Preparation(CallableStatement cs,
*/
public Preparation(Statement s, String sql) {
this(s,
false,
sql,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -548,6 +578,7 @@ public Preparation(Statement s, String sql) {
*/
public Preparation(Statement s, String sql, ResultsAdvancementBehavior resultsAdvancementBehavior) {
this(s,
false,
sql,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -567,6 +598,7 @@ public Preparation(Statement s, String sql, ResultsAdvancementBehavior resultsAd
*/
public Preparation(Statement s, String sql, GeneratedKeysBehavior generatedKeysBehavior) {
this(s,
false,
sql,
generatedKeysBehavior,
EMPTY_INT_ARRAY,
Expand All @@ -591,6 +623,7 @@ public Preparation(Statement s,
GeneratedKeysBehavior generatedKeysBehavior,
ResultsAdvancementBehavior resultsAdvancementBehavior) {
this(s,
false,
sql,
generatedKeysBehavior,
EMPTY_INT_ARRAY,
Expand All @@ -611,6 +644,7 @@ public Preparation(Statement s,
*/
public Preparation(Statement s, String sql, int[] columnIndices) {
this(s,
false,
sql,
GeneratedKeysBehavior.RETURN,
columnIndices,
Expand All @@ -633,6 +667,7 @@ public Preparation(Statement s, String sql, int[] columnIndices) {
*/
public Preparation(Statement s, String sql, int[] columnIndices, ResultsAdvancementBehavior resultsAdvancementBehavior) {
this(s,
false,
sql,
GeneratedKeysBehavior.RETURN,
columnIndices,
Expand All @@ -653,6 +688,7 @@ public Preparation(Statement s, String sql, int[] columnIndices, ResultsAdvancem
*/
public Preparation(Statement s, String sql, String[] columnNames) {
this(s,
false,
sql,
GeneratedKeysBehavior.RETURN,
EMPTY_INT_ARRAY,
Expand All @@ -675,6 +711,7 @@ public Preparation(Statement s, String sql, String[] columnNames) {
*/
public Preparation(Statement s, String sql, String[] columnNames, ResultsAdvancementBehavior resultsAdvancementBehavior) {
this(s,
false,
sql,
GeneratedKeysBehavior.RETURN,
EMPTY_INT_ARRAY,
Expand All @@ -693,6 +730,7 @@ public Preparation(Statement s, String sql, String[] columnNames, ResultsAdvance
*/
public Preparation(ResultSet rs) throws SQLException {
this(rs.getStatement(),
false,
null,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -713,6 +751,7 @@ public Preparation(ResultSet rs) throws SQLException {
*/
public Preparation(ResultSet rs, ResultsAdvancementBehavior resultsAdvancementBehavior) throws SQLException {
this(rs.getStatement(),
false,
null,
GeneratedKeysBehavior.NONE,
EMPTY_INT_ARRAY,
Expand All @@ -723,6 +762,7 @@ public Preparation(ResultSet rs, ResultsAdvancementBehavior resultsAdvancementBe
}

private Preparation(Statement statement,
boolean batch,
String sql,
GeneratedKeysBehavior generatedKeysBehavior,
int[] columnIndices,
Expand All @@ -731,6 +771,9 @@ private Preparation(Statement statement,
ResultsAdvancementBehavior resultsAdvancementBehavior,
int[] outParameterIndices) {
this.statement = requireNonNull(statement, "statement");
if (batch && jdbcResult != null) {
throw new IllegalArgumentException("jdbcResult may not be supplied when a batch execution has been requested");
}
if (statement instanceof PreparedStatement ps) {
// PreparedStatement or CallableStatement
if (sql != null) {
Expand All @@ -749,12 +792,15 @@ private Preparation(Statement statement,
throw new IllegalArgumentException("columnNames cannot be supplied with a PreparedStatement");
}
this.columnNames = EMPTY_STRING_ARRAY;
if (ps instanceof CallableStatement) {
this.outParameterIndices = outParameterIndices.length > 0 ? outParameterIndices.clone() : EMPTY_INT_ARRAY;
} else if (outParameterIndices.length > 0) {
throw new IllegalArgumentException("outParameterIndices may be supplied only for a CallableStatement");
} else {
if (outParameterIndices.length == 0) {
this.outParameterIndices = EMPTY_INT_ARRAY;
} else if (batch) {
throw new IllegalArgumentException("outParameterIndices may not be supplied when"
+ " a batch execution has been requested");
} else if (ps instanceof CallableStatement) {
this.outParameterIndices = outParameterIndices.clone();
} else {
throw new IllegalArgumentException("outParameterIndices may be supplied only for a CallableStatement");
}
} else {
// Plain Statement
Expand All @@ -764,24 +810,43 @@ private Preparation(Statement statement,
+ " the supplied Statement has already been executed");
}
this.sql = null;
} else if (batch) {
if (sql != null) {
throw new IllegalArgumentException("sql may not be supplied when"
+ " a batch execution has been requested");
}
this.sql = null;
} else if (sql == null) {
throw new IllegalArgumentException("sql must be supplied with non-PreparedStatements", new NullPointerException("sql"));
} else {
this.sql = requireNonNull(sql, "sql");
this.sql = sql;
}
if (columnIndices.length == 0) {
this.columnIndices = EMPTY_INT_ARRAY;
} else if (batch) {
throw new IllegalArgumentException("columnIndices may not be supplied when"
+ " a batch execution has been requested");
} else {
this.columnIndices = columnIndices.clone();
}
this.generatedKeysBehavior =
(columnIndices.length > 0 || columnNames.length > 0) ? GeneratedKeysBehavior.RETURN : generatedKeysBehavior;
this.columnIndices = columnIndices.length > 0 ? columnIndices.clone() : EMPTY_INT_ARRAY;
if (columnNames.length == 0) {
this.columnNames = EMPTY_STRING_ARRAY;
} else if (columnIndices.length > 0) {
} else if (batch) {
throw new IllegalArgumentException("columnNames may not be supplied when"
+ " a batch execution has been requested");
} else if (this.columnIndices.length > 0) {
throw new IllegalArgumentException("columnIndices and columnNames may not be supplied together");
} else {
this.columnNames = columnNames.clone();
}
this.generatedKeysBehavior =
(this.columnIndices.length > 0 || this.columnNames.length > 0) ? GeneratedKeysBehavior.RETURN : generatedKeysBehavior;
if (outParameterIndices.length > 0) {
throw new IllegalArgumentException("outParameterIndices may be supplied only for a CallableStatement");
}
this.outParameterIndices = EMPTY_INT_ARRAY;
}
this.batch = batch;
this.jdbcResult = jdbcResult;
this.resultsAdvancementBehavior =
resultsAdvancementBehavior == null ? ResultsAdvancementBehavior.CLOSE_CURRENT_RESULT : resultsAdvancementBehavior;
Expand All @@ -791,6 +856,10 @@ Statement statement() {
return this.statement;
}

boolean batch() {
return this.batch;
}

Optional<String> sql() {
return Optional.ofNullable(this.sql);
}
Expand Down
Loading