Skip to content

Commit f393a1d

Browse files
authored
JDBC: Use PreparedStatement (#1802)
1 parent 1655dae commit f393a1d

File tree

13 files changed

+620
-374
lines changed

13 files changed

+620
-374
lines changed

persistence/relational-jdbc/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ dependencies {
3434
compileOnly(libs.jakarta.inject.api)
3535

3636
implementation(libs.smallrye.common.annotation) // @Identifier
37+
implementation(libs.postgresql)
3738

3839
testImplementation(libs.mockito.junit.jupiter)
3940
testImplementation(libs.h2)

persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/DatasourceOperations.java

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.IOException;
2727
import java.io.InputStreamReader;
2828
import java.sql.Connection;
29+
import java.sql.PreparedStatement;
2930
import java.sql.ResultSet;
3031
import java.sql.SQLException;
3132
import java.sql.Statement;
@@ -54,15 +55,23 @@ public class DatasourceOperations {
5455

5556
private final DataSource datasource;
5657
private final RelationalJdbcConfiguration relationalJdbcConfiguration;
58+
private final DatabaseType databaseType;
5759

5860
private final Random random = new Random();
5961

6062
public DatasourceOperations(
61-
DataSource datasource, RelationalJdbcConfiguration relationalJdbcConfiguration) {
63+
DataSource datasource,
64+
DatabaseType databaseType,
65+
RelationalJdbcConfiguration relationalJdbcConfiguration) {
6266
this.datasource = datasource;
67+
this.databaseType = databaseType;
6368
this.relationalJdbcConfiguration = relationalJdbcConfiguration;
6469
}
6570

71+
public DatabaseType getDatabaseType() {
72+
return databaseType;
73+
}
74+
6675
/**
6776
* Execute SQL script
6877
*
@@ -116,7 +125,8 @@ public void executeScript(String scriptFilePath) throws SQLException {
116125
* @param <T> : Business entity class
117126
* @throws SQLException : Exception during the query execution.
118127
*/
119-
public <T> List<T> executeSelect(@Nonnull String query, @Nonnull Converter<T> converterInstance)
128+
public <T> List<T> executeSelect(
129+
@Nonnull QueryGenerator.PreparedQuery query, @Nonnull Converter<T> converterInstance)
120130
throws SQLException {
121131
ArrayList<T> results = new ArrayList<>();
122132
executeSelectOverStream(query, converterInstance, stream -> stream.forEach(results::add));
@@ -134,38 +144,47 @@ public <T> List<T> executeSelect(@Nonnull String query, @Nonnull Converter<T> co
134144
* @throws SQLException : Exception during the query execution.
135145
*/
136146
public <T> void executeSelectOverStream(
137-
@Nonnull String query,
147+
@Nonnull QueryGenerator.PreparedQuery query,
138148
@Nonnull Converter<T> converterInstance,
139149
@Nonnull Consumer<Stream<T>> consumer)
140150
throws SQLException {
141151
withRetries(
142152
() -> {
143153
try (Connection connection = borrowConnection();
144-
Statement statement = connection.createStatement();
145-
ResultSet resultSet = statement.executeQuery(query)) {
146-
ResultSetIterator<T> iterator = new ResultSetIterator<>(resultSet, converterInstance);
147-
consumer.accept(iterator.toStream());
148-
return null;
154+
PreparedStatement statement = connection.prepareStatement(query.sql())) {
155+
List<Object> params = query.parameters();
156+
for (int i = 0; i < params.size(); i++) {
157+
statement.setObject(i + 1, params.get(i));
158+
}
159+
try (ResultSet resultSet = statement.executeQuery()) {
160+
ResultSetIterator<T> iterator = new ResultSetIterator<>(resultSet, converterInstance);
161+
consumer.accept(iterator.toStream());
162+
return null;
163+
}
149164
}
150165
});
151166
}
152167

153168
/**
154169
* Executes the UPDATE or INSERT Query
155170
*
156-
* @param query : query to be executed
171+
* @param preparedQuery : query to be executed
157172
* @return : Number of rows modified / inserted.
158173
* @throws SQLException : Exception during Query Execution.
159174
*/
160-
public int executeUpdate(String query) throws SQLException {
175+
public int executeUpdate(QueryGenerator.PreparedQuery preparedQuery) throws SQLException {
161176
return withRetries(
162177
() -> {
163178
try (Connection connection = borrowConnection();
164-
Statement statement = connection.createStatement()) {
179+
PreparedStatement statement = connection.prepareStatement(preparedQuery.sql())) {
180+
List<Object> params = preparedQuery.parameters();
181+
for (int i = 0; i < params.size(); i++) {
182+
statement.setObject(i + 1, params.get(i));
183+
}
165184
boolean autoCommit = connection.getAutoCommit();
166185
connection.setAutoCommit(true);
167186
try {
168-
return statement.executeUpdate(query);
187+
return statement.executeUpdate();
169188
} finally {
170189
connection.setAutoCommit(autoCommit);
171190
}
@@ -188,9 +207,7 @@ public void runWithinTransaction(TransactionCallback callback) throws SQLExcepti
188207
connection.setAutoCommit(false);
189208
try {
190209
try {
191-
try (Statement statement = connection.createStatement()) {
192-
success = callback.execute(statement);
193-
}
210+
success = callback.execute(connection);
194211
} finally {
195212
if (success) {
196213
connection.commit();
@@ -206,6 +223,17 @@ public void runWithinTransaction(TransactionCallback callback) throws SQLExcepti
206223
});
207224
}
208225

226+
public Integer execute(Connection connection, QueryGenerator.PreparedQuery preparedQuery)
227+
throws SQLException {
228+
try (PreparedStatement statement = connection.prepareStatement(preparedQuery.sql())) {
229+
List<Object> params = preparedQuery.parameters();
230+
for (int i = 0; i < params.size(); i++) {
231+
statement.setObject(i + 1, params.get(i));
232+
}
233+
return statement.executeUpdate();
234+
}
235+
}
236+
209237
private boolean isRetryable(SQLException e) {
210238
String sqlState = e.getSQLState();
211239

@@ -291,7 +319,7 @@ public interface Operation<T> {
291319

292320
// Interface for transaction callback
293321
public interface TransactionCallback {
294-
boolean execute(Statement statement) throws SQLException;
322+
boolean execute(Connection connection) throws SQLException;
295323
}
296324

297325
public boolean isConstraintViolation(SQLException e) {

0 commit comments

Comments
 (0)