forked from helidon-io/helidon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue helidon-io#6991 - Blocking DB Client: All simple Statement inte…
…gration tests are passing Signed-off-by: Tomáš Kraus <tomas.kraus@oracle.com>
- Loading branch information
1 parent
7511994
commit d40d508
Showing
14 changed files
with
1,005 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
187 changes: 187 additions & 0 deletions
187
dbclient/jdbc/src/main/java/io/helidon/dbclient/jdbc/JdbcStatementQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* | ||
* Copyright (c) 2023 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.dbclient.jdbc; | ||
|
||
import java.sql.Connection; | ||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.sql.Statement; | ||
import java.util.Spliterator; | ||
import java.util.Spliterators; | ||
import java.util.function.Consumer; | ||
import java.util.stream.Stream; | ||
import java.util.stream.StreamSupport; | ||
|
||
import io.helidon.dbclient.DbRow; | ||
import io.helidon.dbclient.DbStatementException; | ||
import io.helidon.dbclient.DbStatementQuery; | ||
|
||
public class JdbcStatementQuery | ||
extends JdbcStatement<DbStatementQuery, Stream<DbRow>, Stream<DbRow>> | ||
implements DbStatementQuery { | ||
|
||
JdbcStatementQuery(Connection connection, JdbcExecuteContext context) { | ||
super(connection, context); | ||
} | ||
|
||
@Override | ||
public Stream<DbRow> execute() { | ||
return prepare().execute(); | ||
} | ||
|
||
@Override | ||
PrepareIndex<Stream<DbRow>> createPrepareIndex(PreparedStatement statement) { | ||
return new JdbcStatementQuery.PrepareIndexQuery(context(), statement); | ||
} | ||
|
||
@Override | ||
PrepareName<Stream<DbRow>> createPrepareName(JdbcCallableStatement statement) { | ||
return new JdbcStatementQuery.PrepareNameQuery(context(), statement); | ||
} | ||
|
||
@Override | ||
Stream<DbRow> executeStatement(Connection connection, String statementString) { | ||
try { | ||
Statement statement = connection.createStatement(); | ||
ResultSet rs = statement.executeQuery(statementString); | ||
return StreamSupport.stream( | ||
new DbRowSpliterator(rs, context(), statementString), | ||
false) | ||
.onClose(new CloseResources(rs, statement, statementString)); | ||
} catch (SQLException ex) { | ||
throw new DbStatementException("Failed to execute Statement", statementString, ex); | ||
} | ||
} | ||
|
||
private static final class PrepareIndexQuery extends PrepareIndex<Stream<DbRow>> { | ||
|
||
private final JdbcExecuteContext context; | ||
|
||
PrepareIndexQuery(JdbcExecuteContext context, PreparedStatement statement) { | ||
super(context.statement(), statement); | ||
this.context = context; | ||
} | ||
|
||
@Override | ||
Stream<DbRow> execute() { | ||
try { | ||
ResultSet rs = preparedStatement().executeQuery(); | ||
return StreamSupport.stream( | ||
new DbRowSpliterator(rs, context, statementString()), | ||
false) | ||
.onClose(new ClosePreparedResources(rs, this)); | ||
} catch (SQLException ex) { | ||
throw new DbStatementException("Failed to execute PreparedStatement", statementString(), ex); | ||
} | ||
} | ||
|
||
} | ||
|
||
private static final class PrepareNameQuery extends PrepareName<Stream<DbRow>> { | ||
|
||
private final JdbcExecuteContext context; | ||
|
||
PrepareNameQuery(JdbcExecuteContext context, JdbcCallableStatement statement) { | ||
super(context.statement(), statement); | ||
this.context = context; | ||
} | ||
|
||
@Override | ||
Stream<DbRow> execute() { | ||
try { | ||
ResultSet rs = callableStatement().executeQuery(); | ||
return StreamSupport.stream( | ||
new DbRowSpliterator(rs, context, statementString()), | ||
false) | ||
.onClose(new ClosePreparedResources(rs, this)); | ||
} catch (SQLException ex) { | ||
throw new DbStatementException("Failed to execute CallableStatement", statementString(), ex); | ||
} | ||
} | ||
|
||
} | ||
|
||
private static final class DbRowSpliterator extends Spliterators.AbstractSpliterator<DbRow> { | ||
|
||
private final ResultSet rs; | ||
private final JdbcExecuteContext context; | ||
private final String statementString; | ||
|
||
DbRowSpliterator(ResultSet rs, JdbcExecuteContext context, String statementString) { | ||
super(Long.MAX_VALUE, Spliterator.ORDERED); | ||
this.rs = rs; | ||
this.context = context; | ||
this.statementString = statementString; | ||
} | ||
|
||
@Override | ||
public boolean tryAdvance(Consumer<? super DbRow> action) { | ||
try { | ||
if (rs.next()) { | ||
action.accept(JdbcRow.create(rs, | ||
context.dbMapperManager(), | ||
context.mapperManager())); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} catch (SQLException ex) { | ||
throw new DbStatementException("Failed to retrieve next row from ResultSet", | ||
statementString, | ||
ex); | ||
} | ||
} | ||
|
||
} | ||
|
||
private record CloseResources(ResultSet rs, Statement statement, String statementString) implements Runnable { | ||
@Override | ||
public void run() throws DbStatementException { | ||
try { | ||
rs.close(); | ||
} catch (SQLException ex) { | ||
throw new DbStatementException("Failed to close ResultSet", statementString, ex); | ||
} finally { | ||
closeStatement(); | ||
} | ||
} | ||
|
||
// Close Statement and wrap any SQLException with DbStatementException | ||
private void closeStatement() { | ||
try { | ||
statement.close(); | ||
} catch (SQLException ex) { | ||
throw new DbStatementException("Failed to close Statement", statementString, ex); | ||
} | ||
} | ||
|
||
} | ||
|
||
private record ClosePreparedResources(ResultSet rs, PrepareCloseable<Stream<DbRow>> statement) implements Runnable { | ||
@Override | ||
public void run() { | ||
try { | ||
rs.close(); | ||
} catch (SQLException ex) { | ||
throw new DbStatementException("Failed to close ResultSet", statement.statementString(), ex); | ||
} finally { | ||
statement.close(); | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.