Skip to content

Commit 44d94ed

Browse files
authored
Add support of java.sql.PreparedStatement to HoptimatorConnection (#139)
This is to add another option to send SQL statements with many advantages, particularly preventing SQL injection attacks: https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
1 parent b26900f commit 44d94ed

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

hoptimator-jdbc/src/main/java/com/linkedin/hoptimator/jdbc/HoptimatorConnection.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.linkedin.hoptimator.jdbc;
22

3+
import java.sql.PreparedStatement;
34
import java.sql.SQLException;
45
import java.sql.Statement;
56
import java.util.ArrayList;
@@ -32,6 +33,11 @@ public Statement createStatement() throws SQLException {
3233
return connection.createStatement();
3334
}
3435

36+
@Override
37+
public PreparedStatement prepareStatement(String sql) throws SQLException {
38+
return connection.prepareStatement(sql);
39+
}
40+
3541
public Properties connectionProperties() {
3642
return connectionProperties;
3743
}

hoptimator-jdbc/src/test/java/com/linkedin/hoptimator/jdbc/JdbcTestBase.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.sql.Connection;
44
import java.sql.DriverManager;
5+
import java.sql.PreparedStatement;
56
import java.sql.ResultSet;
67
import java.sql.SQLException;
78
import java.sql.Statement;
@@ -34,8 +35,10 @@ protected void sql(String sql) throws SQLException {
3435
}
3536

3637
protected void assertQueriesEqual(String q1, String q2) throws SQLException {
37-
List<Object[]> res1 = query(q1);
38-
List<Object[]> res2 = query(q2);
38+
assertResultSetsEqual(query(q1), query(q2));
39+
}
40+
41+
protected void assertResultSetsEqual(List<Object[]> res1, List<Object[]> res2) {
3942
Assertions.assertEquals(res1.size(), res2.size(), "ResultSets are not the same size");
4043
for (int i = 0; i < res1.size(); i++) {
4144
Assertions.assertArrayEquals(res1.get(i), res2.get(i), "Rows did not match at row #" + i);
@@ -53,17 +56,31 @@ protected void assertQueryNonEmpty(String q) throws SQLException {
5356
}
5457

5558
protected List<Object[]> query(String query) throws SQLException {
56-
List<Object[]> results = new ArrayList<>();
5759
try (Statement stmt = conn.createStatement()) {
5860
ResultSet cursor = stmt.executeQuery(query);
59-
while (cursor.next()) {
60-
int n = cursor.getMetaData().getColumnCount();
61-
Object[] row = new Object[n];
62-
for (int i = 0; i < n; i++) {
63-
row[i] = cursor.getObject(i + 1);
64-
}
65-
results.add(row);
61+
return buildRows(cursor);
62+
}
63+
}
64+
65+
protected List<Object[]> queryUsingPreparedStatement(String query, List<String> params) throws SQLException {
66+
try (PreparedStatement stmt = conn.prepareStatement(query)) {
67+
for (int i = 0; i < params.size(); i++) {
68+
stmt.setString(i + 1, params.get(i));
69+
}
70+
ResultSet cursor = stmt.executeQuery();
71+
return buildRows(cursor);
72+
}
73+
}
74+
75+
private static List<Object[]> buildRows(ResultSet cursor) throws SQLException {
76+
List<Object[]> results = new ArrayList<>();
77+
while (cursor.next()) {
78+
int n = cursor.getMetaData().getColumnCount();
79+
Object[] row = new Object[n];
80+
for (int i = 0; i < n; i++) {
81+
row[i] = cursor.getObject(i + 1);
6682
}
83+
results.add(row);
6784
}
6885
return results;
6986
}

hoptimator-jdbc/src/test/java/com/linkedin/hoptimator/jdbc/TestBasicSql.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.linkedin.hoptimator.jdbc;
22

3+
import java.util.Arrays;
4+
35
import org.junit.jupiter.api.Test;
46

57

@@ -21,6 +23,8 @@ public void insertIntoSelectFrom() throws Exception {
2123
sql("CREATE TABLE T2 (A VARCHAR, B INT)");
2224
sql("INSERT INTO T2 SELECT * FROM T1");
2325
assertQueriesEqual("SELECT * FROM T1", "SELECT * FROM T2");
26+
assertResultSetsEqual(query("SELECT * FROM T1 WHERE X = 'one'"),
27+
queryUsingPreparedStatement("SELECT * FROM T1 WHERE X = ?", Arrays.asList("one")));
2428
sql("DROP TABLE T1");
2529
sql("DROP TABLE T2");
2630
}

0 commit comments

Comments
 (0)