Skip to content

Commit 9c54349

Browse files
committed
Make ResultSetAdapter and StreamAdapter auto-closeable.
1 parent 6ebdced commit 9c54349

File tree

5 files changed

+29
-29
lines changed

5 files changed

+29
-29
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -809,10 +809,10 @@ root.getChildren().get(0).getChildren().get(0).getName(); // "January"
809809
The `ResultSetAdapter` class implements the `Iterable` interface and makes each row in a JDBC result set appear as an instance of `Map`, allowing query results to be efficiently serialized as JSON, CSV, or XML, or to any other format via a template. For example:
810810

811811
```java
812-
JSONEncoder jsonEncoder = new JSONEncoder();
813-
814-
try (ResultSet resultSet = statement.executeQuery()) {
815-
jsonEncoder.write(new ResultSetAdapter(resultSet), getResponse().getOutputStream());
812+
try (ResultSetAdapter resultSetAdapter = new ResultSetAdapter(statement.executeQuery())) {
813+
JSONEncoder jsonEncoder = new JSONEncoder();
814+
815+
jsonEncoder.write(, getResponse().getOutputStream());
816816
}
817817
```
818818

@@ -863,7 +863,7 @@ parameters.apply(statement, mapOf(
863863
Once applied, the statement can be executed:
864864

865865
```java
866-
return new ResultSetAdapter(statement.executeQuery());
866+
ResultSetAdapter resultSetAdapter = new ResultSetAdapter(statement.executeQuery());
867867
```
868868

869869
A complete example that uses both classes is shown below. It is based on the "pet" table from the MySQL "menagerie" sample database:
@@ -883,7 +883,7 @@ The following service method queries this table to retrieve a list of all pets b
883883

884884
```java
885885
@RequestMethod("GET")
886-
public void getPets(String owner) throws SQLException, IOException {
886+
public void getPets(String owner, String format) throws SQLException, IOException {
887887
Parameters parameters = Parameters.parse("SELECT name, species, sex, birth FROM pet WHERE owner = :owner");
888888

889889
try (Connection connection = dataSource.getConnection();
@@ -892,7 +892,7 @@ public void getPets(String owner) throws SQLException, IOException {
892892
entry("owner", owner)
893893
));
894894

895-
try (ResultSet resultSet = statement.executeQuery()) {
895+
try (ResultSetAdapter resultSetAdapter = new ResultSetAdapter(statement.executeQuery())) {
896896
JSONEncoder jsonEncoder = new JSONEncoder();
897897

898898
jsonEncoder.write(new ResultSetAdapter(resultSet), getResponse().getOutputStream());

httprpc-client/src/main/java/org/httprpc/sql/ResultSetAdapter.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,10 @@
2626

2727
/**
2828
* Class that presents the contents of a result set as an iterable sequence
29-
* of maps.
29+
* of maps. Map instances are mutable, and column order is preserved.
3030
*/
31-
public class ResultSetAdapter implements Iterable<Map<String, Object>> {
31+
public class ResultSetAdapter implements Iterable<Map<String, Object>>, AutoCloseable {
3232
private ResultSet resultSet;
33-
private ResultSetMetaData resultSetMetaData;
3433

3534
private Iterator<Map<String, Object>> iterator = new Iterator<Map<String, Object>>() {
3635
private Boolean hasNext = null;
@@ -58,6 +57,8 @@ public Map<String, Object> next() {
5857
LinkedHashMap<String, Object> row = new LinkedHashMap<>();
5958

6059
try {
60+
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
61+
6162
for (int i = 0, n = resultSetMetaData.getColumnCount(); i < n; i++) {
6263
String path = resultSetMetaData.getColumnLabel(i + 1);
6364

@@ -104,21 +105,21 @@ public ResultSetAdapter(ResultSet resultSet) {
104105
}
105106

106107
this.resultSet = resultSet;
107-
108-
try {
109-
resultSetMetaData = resultSet.getMetaData();
110-
} catch (SQLException exception) {
111-
throw new RuntimeException(exception);
112-
}
113108
}
114109

115110
@Override
116111
public Iterator<Map<String, Object>> iterator() {
117112
return iterator;
118113
}
119114

115+
@Override
116+
public void close() throws SQLException {
117+
resultSet.close();
118+
}
119+
120120
/**
121-
* Returns a stream over the results.
121+
* Returns a stream over the results. Closing the returned stream does not
122+
* close the underlying result set.
122123
*
123124
* @return
124125
* A stream over the results.

httprpc-client/src/main/java/org/httprpc/util/StreamAdapter.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/**
2121
* Class that presents the contents of a stream as an iterable sequence.
2222
*/
23-
public class StreamAdapter<T> implements Iterable<T> {
23+
public class StreamAdapter<T> implements Iterable<T>, AutoCloseable {
2424
private Stream<T> stream;
2525

2626
public StreamAdapter(Stream<T> stream) {
@@ -31,4 +31,9 @@ public StreamAdapter(Stream<T> stream) {
3131
public Iterator<T> iterator() {
3232
return stream.iterator();
3333
}
34+
35+
@Override
36+
public void close() {
37+
stream.close();
38+
}
3439
}

httprpc-client/src/test/java/org/httprpc/sql/ResultSetAdapterTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.junit.jupiter.api.Test;
1818

1919
import java.sql.Date;
20+
import java.sql.SQLException;
2021
import java.util.List;
2122
import java.util.Map;
2223
import java.util.stream.Collectors;
@@ -61,11 +62,9 @@ public class ResultSetAdapterTest {
6162
);
6263

6364
@Test
64-
public void testResultSetAdapter() {
65+
public void testResultSetAdapter() throws SQLException {
6566
List<Map<String, Object>> actual;
66-
try (TestResultSet resultSet = new TestResultSet()) {
67-
ResultSetAdapter adapter = new ResultSetAdapter(resultSet);
68-
67+
try (ResultSetAdapter adapter = new ResultSetAdapter(new TestResultSet())) {
6968
actual = adapter.stream().collect(Collectors.toList());
7069
}
7170

httprpc-test/src/main/java/org/httprpc/test/mysql/PetService.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import java.io.IOException;
3535
import java.sql.Connection;
3636
import java.sql.PreparedStatement;
37-
import java.sql.ResultSet;
3837
import java.sql.SQLException;
3938
import java.sql.Statement;
4039
import java.util.Arrays;
@@ -81,9 +80,7 @@ public void getPets(String owner, String format) throws SQLException, IOExceptio
8180
entry("owner", owner)
8281
));
8382

84-
try (ResultSet resultSet = statement.executeQuery()) {
85-
ResultSetAdapter resultSetAdapter = new ResultSetAdapter(resultSet);
86-
83+
try (ResultSetAdapter resultSetAdapter = new ResultSetAdapter(statement.executeQuery())) {
8784
if (format == null || format.equals("json")) {
8885
getResponse().setContentType("application/json");
8986

@@ -122,9 +119,7 @@ public double getAverageAge() throws SQLException {
122119
double averageAge;
123120
try (Connection connection = dataSource.getConnection();
124121
Statement statement = connection.createStatement();
125-
ResultSet resultSet = statement.executeQuery("SELECT birth FROM pet")) {
126-
ResultSetAdapter resultSetAdapter = new ResultSetAdapter(resultSet);
127-
122+
ResultSetAdapter resultSetAdapter = new ResultSetAdapter(statement.executeQuery("SELECT birth FROM pet"))) {
128123
Date now = new Date();
129124

130125
Stream<Pet> pets = resultSetAdapter.stream().map(result -> BeanAdapter.adapt(result, Pet.class));

0 commit comments

Comments
 (0)