From a580bebbfe1f65d26e8496cf900991a8d1e1b2f1 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 10 May 2013 16:51:40 +0200 Subject: [PATCH] [#2457] Add Result.resultSet() and Result.close() to handle the referenced ResultSet's lifecycle --- jOOQ/src/main/java/org/jooq/Result.java | 26 ++++++++++ .../java/org/jooq/impl/AbstractRecord.java | 4 +- .../org/jooq/impl/AbstractResultQuery.java | 2 +- .../org/jooq/impl/AbstractStoreQuery.java | 2 +- .../main/java/org/jooq/impl/CursorImpl.java | 2 +- .../java/org/jooq/impl/DSLContextImpl.java | 6 +-- .../java/org/jooq/impl/ReferenceImpl.java | 4 +- .../main/java/org/jooq/impl/ResultImpl.java | 51 +++++++++++++++---- 8 files changed, 76 insertions(+), 21 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/Result.java b/jOOQ/src/main/java/org/jooq/Result.java index 2180a8a2d2..c07ae08a34 100644 --- a/jOOQ/src/main/java/org/jooq/Result.java +++ b/jOOQ/src/main/java/org/jooq/Result.java @@ -41,6 +41,7 @@ import java.sql.Statement; import java.util.List; import java.util.Map; +import org.jooq.exception.DataAccessException; import org.jooq.exception.DataTypeException; import org.jooq.exception.InvalidResultException; import org.jooq.exception.MappingException; @@ -1081,4 +1082,29 @@ public interface Result extends List, Attachable { * @see String#intern() */ Result intern(String... fieldNames); + + /** + * Close the underlying JDBC {@link ResultSet}, if applicable. + *

+ * If this Result was created using + * {@link ResultQuery#keepResultSet(KeepResultSetMode)}, then it closes the + * underlying JDBC {@link ResultSet}. Otherwise, this method has no effect. + * + * @throws DataAccessException If something went wrong closing the + * underlying {@link ResultSet} + * @see #resultSet() + */ + void close() throws DataAccessException; + + /** + * Get the underlying JDBC {@link ResultSet}, if applicable. + *

+ * This method returns the underlying JDBC {@link ResultSet}, if this + * Result was created using + * {@link ResultQuery#keepResultSet(KeepResultSetMode)}. Otherwise, this + * method returns null. + * + * @return The underlying JDBC ResultSet, or null + */ + ResultSet resultSet(); } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java index 6618f08484..44d6d30d12 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java @@ -511,7 +511,7 @@ abstract class AbstractRecord extends AbstractStore implements Record { @Override public final ResultSet intoResultSet() { - ResultImpl result = new ResultImpl(configuration(), fields.fields.fields); + ResultImpl result = new ResultImpl(configuration(), rs, fields.fields.fields); result.add(this); return result.intoResultSet(); } @@ -654,7 +654,7 @@ abstract class AbstractRecord extends AbstractStore implements Record { @Override public String toString() { - Result result = new ResultImpl(configuration(), fields.fields.fields); + Result result = new ResultImpl(configuration(), null, fields.fields.fields); result.add(this); return result.toString(); } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java index fb464a9515..994e11f421 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java @@ -284,7 +284,7 @@ abstract class AbstractResultQuery extends AbstractQuery imple } } else { - result = new ResultImpl(ctx.configuration()); + result = new ResultImpl(ctx.configuration(), null); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java index 64383a9cf0..ea93b08aee 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java @@ -142,7 +142,7 @@ abstract class AbstractStoreQuery extends AbstractQuery implem @Override public final Result getReturnedRecords() { if (returned == null) { - returned = new ResultImpl(configuration(), returning); + returned = new ResultImpl(configuration(), null, returning); } return returned; diff --git a/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java b/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java index adb9a27f36..8674a1702b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java @@ -177,7 +177,7 @@ class CursorImpl implements Cursor { // Before listener.resultStart(ctx) iterator(); - ResultImpl result = new ResultImpl(ctx.configuration(), fields); + ResultImpl result = new ResultImpl(ctx.configuration(), closeAfterFetch() ? null : rs, fields); R record = null; ctx.result(result); diff --git a/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java b/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java index eaa1ea034c..533ae88a3a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java @@ -637,7 +637,7 @@ class DSLContextImpl implements DSLContext, Serializable { @Override public final Result fetchFromStringData(List data) { if (data.size() == 0) { - return new ResultImpl(configuration); + return new ResultImpl(configuration, null); } else { List> fields = new ArrayList>(); @@ -646,7 +646,7 @@ class DSLContextImpl implements DSLContext, Serializable { fields.add(fieldByName(String.class, name)); } - Result result = new ResultImpl(configuration, fields); + Result result = new ResultImpl(configuration, null, fields); if (data.size() > 1) { for (String[] values : data.subList(1, data.size())) { @@ -1548,7 +1548,7 @@ class DSLContextImpl implements DSLContext, Serializable { @Override public final Result newResult(Table table) { - return new ResultImpl(configuration, table.fields()); + return new ResultImpl(configuration, null, table.fields()); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java b/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java index 636be55f9e..62fd065499 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java @@ -104,7 +104,7 @@ class ReferenceImpl extends AbstractKey i @Override public final Result fetchParents(Collection records) { if (records == null || records.size() == 0) { - return new ResultImpl(new DefaultConfiguration(), key.getFields()); + return new ResultImpl(new DefaultConfiguration(), null, key.getFields()); } else { return fetch(records, key.getTable(), key.getFieldsArray(), getFieldsArray()); @@ -114,7 +114,7 @@ class ReferenceImpl extends AbstractKey i @Override public final Result fetchChildren(Collection records) { if (records == null || records.size() == 0) { - return new ResultImpl(new DefaultConfiguration(), getFields()); + return new ResultImpl(new DefaultConfiguration(), null, getFields()); } else { return fetch(records, getTable(), getFieldsArray(), key.getFieldsArray()); diff --git a/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java b/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java index a3f0eb03c4..60bfc50415 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java @@ -38,12 +38,14 @@ package org.jooq.impl; import static java.lang.Math.max; import static java.lang.Math.min; +import static org.jooq.impl.Utils.translate; import static org.jooq.tools.StringUtils.abbreviate; import static org.jooq.tools.StringUtils.leftPad; import static org.jooq.tools.StringUtils.rightPad; import java.lang.reflect.Array; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -94,22 +96,24 @@ class ResultImpl implements Result, AttachableInternal { */ private static final long serialVersionUID = 6416154375799578362L; + private Configuration configuration; + private ResultSet rs; private final Fields fields; private final List records; - private Configuration configuration; - ResultImpl(Configuration configuration, Collection> fields) { - this(configuration, new Fields(fields)); + ResultImpl(Configuration configuration, ResultSet rs, Collection> fields) { + this(configuration, rs, new Fields(fields)); } - ResultImpl(Configuration configuration, Field... fields) { - this(configuration, new Fields(fields)); + ResultImpl(Configuration configuration, ResultSet rs, Field... fields) { + this(configuration, rs, new Fields(fields)); } - ResultImpl(Configuration configuration, Fields fields) { - this.fields = fields; - this.records = new ArrayList(); + ResultImpl(Configuration configuration, ResultSet rs, Fields fields) { this.configuration = configuration; + this.fields = fields; + this.rs = rs; + this.records = new ArrayList(); } // ------------------------------------------------------------------------- @@ -859,7 +863,7 @@ class ResultImpl implements Result, AttachableInternal { Result result = map.get(val); if (result == null) { - result = new ResultImpl(configuration, fields); + result = new ResultImpl(configuration, rs, fields); map.put(val, result); } @@ -911,7 +915,7 @@ class ResultImpl implements Result, AttachableInternal { Result result = map.get(key); if (result == null) { - result = new ResultImpl(configuration(), this.fields); + result = new ResultImpl(configuration(), rs, this.fields); map.put(key, result); } @@ -1055,7 +1059,7 @@ class ResultImpl implements Result, AttachableInternal { @Override public final Result into(Table table) { - Result list = new ResultImpl(configuration(), table.fields()); + Result list = new ResultImpl(configuration(), rs, table.fields()); for (R record : this) { list.add(record.into(table)); @@ -1188,6 +1192,31 @@ class ResultImpl implements Result, AttachableInternal { return intern(fields.indexesOf(fieldNames)); } + @Override + public final void close() { + try { + if (rs != null) { + rs.close(); + rs = null; + + for (Record record : this) { + if (record instanceof AbstractRecord) { + ((AbstractRecord) record).rs = null; + ((AbstractRecord) record).rsIndex = 0; + } + } + } + } + catch (SQLException e) { + throw translate("Cannot close ResultSet", e); + } + } + + @Override + public final ResultSet resultSet() { + return rs; + } + /** * A comparator for records, wrapping another comparator for <T> */