From ce7a71b346ba9adb9e7443f995cd2fad9d965e25 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 5 Jun 2013 09:42:26 +0200 Subject: [PATCH] [#1846] [#2265] Reverted changes for 3.1 --- .../test/_/testcases/KeepResultSetTests.java | 441 ------------------ .../src/org/jooq/test/jOOQAbstractTest.java | 31 -- jOOQ/src/main/java/org/jooq/Cursor.java | 9 - .../main/java/org/jooq/KeepResultSetMode.java | 134 ------ jOOQ/src/main/java/org/jooq/Record.java | 105 ----- jOOQ/src/main/java/org/jooq/Result.java | 30 -- jOOQ/src/main/java/org/jooq/ResultQuery.java | 12 - .../main/java/org/jooq/UpdatableRecord.java | 56 ++- .../java/org/jooq/impl/AbstractRecord.java | 125 +---- .../org/jooq/impl/AbstractResultQuery.java | 42 +- .../org/jooq/impl/AbstractStoreQuery.java | 5 +- .../main/java/org/jooq/impl/CursorImpl.java | 29 +- .../java/org/jooq/impl/DefaultDSLContext.java | 9 +- .../java/org/jooq/impl/ReferenceImpl.java | 4 +- .../main/java/org/jooq/impl/ResultImpl.java | 44 +- .../main/java/org/jooq/impl/SelectImpl.java | 6 - .../org/jooq/impl/UpdatableRecordImpl.java | 35 +- jOOQ/src/main/java/org/jooq/impl/Utils.java | 4 +- 18 files changed, 110 insertions(+), 1011 deletions(-) delete mode 100644 jOOQ-test/src/org/jooq/test/_/testcases/KeepResultSetTests.java delete mode 100644 jOOQ/src/main/java/org/jooq/KeepResultSetMode.java diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/KeepResultSetTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/KeepResultSetTests.java deleted file mode 100644 index 369c92afe4..0000000000 --- a/jOOQ-test/src/org/jooq/test/_/testcases/KeepResultSetTests.java +++ /dev/null @@ -1,441 +0,0 @@ -/** - * Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com - * All rights reserved. - * - * This software is licensed to you under the Apache License, Version 2.0 - * (the "License"); You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name "jOOQ" nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -package org.jooq.test._.testcases; - -import static java.util.Arrays.asList; -import static org.jooq.KeepResultSetMode.CLOSE_AFTER_FETCH; -import static org.jooq.KeepResultSetMode.KEEP_AFTER_FETCH; -import static org.jooq.KeepResultSetMode.UPDATE_ON_CHANGE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.sql.Date; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collections; - -import org.jooq.Cursor; -import org.jooq.DSLContext; -import org.jooq.Delete; -import org.jooq.ExecuteContext; -import org.jooq.Query; -import org.jooq.Record; -import org.jooq.Record1; -import org.jooq.Record2; -import org.jooq.Record3; -import org.jooq.Record6; -import org.jooq.Result; -import org.jooq.Select; -import org.jooq.TableRecord; -import org.jooq.UpdatableRecord; -import org.jooq.exception.DataAccessException; -import org.jooq.impl.DefaultExecuteListener; -import org.jooq.test.BaseTest; -import org.jooq.test.jOOQAbstractTest; - -import org.junit.Test; - -public class KeepResultSetTests< - A extends UpdatableRecord & Record6, - AP, - B extends UpdatableRecord, - S extends UpdatableRecord & Record1, - B2S extends UpdatableRecord & Record3, - BS extends UpdatableRecord, - L extends TableRecord & Record2, - X extends TableRecord, - DATE extends UpdatableRecord, - BOOL extends UpdatableRecord, - D extends UpdatableRecord, - T extends UpdatableRecord, - U extends TableRecord, - UU extends UpdatableRecord, - I extends TableRecord, - IPK extends UpdatableRecord, - T725 extends UpdatableRecord, - T639 extends UpdatableRecord, - T785 extends TableRecord> -extends BaseTest { - - public KeepResultSetTests(jOOQAbstractTest delegate) { - super(delegate); - } - - /** - * This listener is used to check if a SELECT statement is - * issued after a call to {@link Record#refresh()}. - */ - private static class NoStatementAfterCRUDListener extends DefaultExecuteListener { - - /** - * Default UID - */ - private static final long serialVersionUID = 1L; - - private final Class type; - private final String crudMethod; - - NoStatementAfterCRUDListener(Class type, String crudMethod) { - this.type = type; - this.crudMethod = crudMethod; - } - - @Override - public void start(ExecuteContext ctx) { - super.start(ctx); - - if (ctx.query() != null) { - if (type.isAssignableFrom(ctx.query().getClass())) { - for (StackTraceElement e : Thread.currentThread().getStackTrace()) { - if (e.getMethodName().equals(crudMethod)) { - fail("Record." + crudMethod + "() should not execute any " + type.getName() + " queries"); - } - } - } - } - } - } - - private void testFailUpdateRow(ResultSet rs) { - try { - rs.updateRow(); - fail(); - } - catch (SQLException expected) {} - - } - - private void testFailRefresh(Record record) { - try { - record.refresh(); - fail(); - } - catch (DataAccessException expected) {} - } - - @Test - public void testKeepRSWithCloseAfterFetch() throws Exception { - DSLContext create = create(new NoStatementAfterCRUDListener(Select.class, "refresh")); - - Result b1 = create.selectFrom(TBook()).fetch(); - assertNull(b1.resultSet()); - - // Use plain SQL to prevent fetching of UpdatableRecord - Result b2 = create.select().from(TBook().getName()).keepResultSet(CLOSE_AFTER_FETCH).fetch(); - assertNull(b2.resultSet()); - - // Changing a TITLE has no effect - Record r = b2.get(0); - r.setValue(TBook_TITLE(), "XX"); - assertTrue(r.changed()); - assertFalse(r.original().equals(r)); - assertEquals(BOOK_TITLES.get(0), getBook(1).getValue(TBook_TITLE())); - testFailRefresh(r); - - Cursor c1 = create.select().from(TBook().getName()).keepResultSet(CLOSE_AFTER_FETCH).fetchLazy(); - assertTrue(c1.closesAfterFetch()); - while (c1.hasNext()) { - Result result = c1.fetch(1); - assertNull(result.get(0).resultSet()); - assertNull(result.resultSet()); - assertNotNull(c1.resultSet()); - } - - assertNull(c1.resultSet()); - } - - private void testOriginalBook1(B book) { - assertEquals(BOOK_TITLES.get(0), book.getValue(TBook_TITLE())); - assertEquals(BOOK_AUTHOR_IDS.get(0), book.getValue(TBook_AUTHOR_ID())); - assertFalse(book.changed()); - assertEquals(book.original(), book); - assertNotNull(book.resultSet()); - } - - private void testModifiedBook1(B book) { - book.setValue(TBook_TITLE(), "XX"); - book.setValue(TBook_AUTHOR_ID(), 15); - assertEquals("XX", book.getValue(TBook_TITLE())); - assertEquals(15, (int) book.getValue(TBook_AUTHOR_ID())); - assertTrue(book.changed()); - assertFalse(book.original().equals(book)); - } - - @Test - public void testKeepRSWithKeepAfterFetch() throws Exception { - switch (dialect()) { - case SQLITE: - log.info("SKIPPING", "KeepResultSet tests"); - return; - } - - DSLContext create = create(new NoStatementAfterCRUDListener(Select.class, "refresh")); - Result b2 = create.selectFrom(TBook()).keepResultSet(KEEP_AFTER_FETCH).fetch(); - B r = b2.get(0); - assertNotNull(b2.resultSet()); - assertNotNull(r.resultSet()); - testFailUpdateRow(b2.resultSet()); - - testModifiedBook1(r); - B dbBook = getBook(1); - assertEquals(BOOK_TITLES.get(0), dbBook.getValue(TBook_TITLE())); - assertEquals(BOOK_AUTHOR_IDS.get(0), dbBook.getValue(TBook_AUTHOR_ID())); - - // Refresh the record - r.refresh(TBook_TITLE()); - assertEquals(BOOK_TITLES.get(0), r.getValue(TBook_TITLE())); - assertEquals(15, (int) r.getValue(TBook_AUTHOR_ID())); - assertTrue(r.changed()); - assertFalse(r.original().equals(r)); - - r.refresh(); - testOriginalBook1(r); - - b2.close(); - assertNull(b2.resultSet()); - - // Changing a TITLE still has no effect - testModifiedBook1(r); - - // But refreshing should work through a new query (UpdatableRecord) - // For this, remove the NoSelectAfterRefreshListener - r.attach(create().configuration()); - r.refresh(); - testOriginalBook1(r); - - // Further refreshing should again not trigger new SQL statements - r.attach(create.configuration()); - testModifiedBook1(r); - - r.refresh(); - testOriginalBook1(r); - r.close(); - - Cursor c1 = create.select().from(TBook().getName()).keepResultSet(KEEP_AFTER_FETCH).fetchLazy(); - assertFalse(c1.closesAfterFetch()); - while (c1.hasNext()) { - Result result = c1.fetch(1); - assertNotNull(result.get(0).resultSet()); - assertNotNull(result.resultSet()); - assertNotNull(c1.resultSet()); - } - - assertNotNull(c1.resultSet()); - c1.close(); - assertNull(c1.resultSet()); - } - - @Test - public void testKeepRSWithUpdateOnChange() throws Exception { - switch (dialect()) { - // There's a critical bug in Derby. When this test is executed, the - // connection is killed - // https://issues.apache.org/jira/browse/DERBY-6228 - case DERBY: - case SQLITE: - log.info("SKIPPING", "KeepResultSet tests"); - return; - } - - jOOQAbstractTest.reset = false; - DSLContext create = create(new NoStatementAfterCRUDListener(Select.class, "refresh")); - - // Use plain SQL to prevent fetching of UpdatableRecord - Result books = - create.selectFrom(TBook()) - .orderBy(TBook_ID()) - .keepResultSet(UPDATE_ON_CHANGE) - .fetch(); - - assertNotNull(books.resultSet()); - for (int i = 0; i < books.size(); i++) { - assertNotNull(books.get(i).resultSet()); - books.get(i).setValue(TBook_TITLE(), "Title " + i); - } - - Result booksTest = getBooks(); - assertEquals( - asList("Title 0", "Title 1", "Title 2", "Title 3"), - booksTest.getValues(TBook_TITLE())); - - // After closing, setting values to records should no longer have any - // effect - assertNotNull(books.resultSet()); - books.close(); - assertNull(books.resultSet()); - books.get(0).setValue(TBook_TITLE(), "XX"); - assertEquals("Title 0", getBook(1).getValue(TBook_TITLE())); - } - - @Test - public void testKeepRSWithUpdateOnChangeLazy() throws Exception { - switch (dialect()) { - // There's a critical bug in Derby. When this test is executed, the - // connection is killed - // https://issues.apache.org/jira/browse/DERBY-6228 - case DERBY: - case SQLITE: - log.info("SKIPPING", "KeepResultSet tests"); - return; - } - - jOOQAbstractTest.reset = false; - DSLContext create = create(new NoStatementAfterCRUDListener(Select.class, "refresh")); - - Cursor books = - create.selectFrom(TBook()) - .orderBy(TBook_ID()) - .keepResultSet(UPDATE_ON_CHANGE) - .fetchLazy(); - - assertNotNull(books.resultSet()); - assertFalse(books.closesAfterFetch()); - while (books.hasNext()) { - B book = books.fetchOne(); - assertNotNull(book.resultSet()); - book.setValue(TBook_TITLE(), "Title X"); - } - - Result booksTest = getBooks(); - assertEquals( - Collections.nCopies(4, "Title X"), - booksTest.getValues(TBook_TITLE())); - - // After closing, setting values to records should no longer have any - // effect - assertNotNull(books.resultSet()); - assertFalse(books.isClosed()); - books.close(); - assertNull(books.resultSet()); - assertTrue(books.isClosed()); - } - - @Test - public void testKeepRSWithUpdateOnChangeFetchOne() throws Exception { - switch (dialect()) { - case SQLITE: - log.info("SKIPPING", "KeepResultSet tests"); - return; - } - - jOOQAbstractTest.reset = false; - - DSLContext create = create(new NoStatementAfterCRUDListener(Select.class, "refresh")); - Record book = - create.select() - .from(TBook().getName()) - .where(TBook_ID().eq(1)) - .keepResultSet(UPDATE_ON_CHANGE) - .fetchOne(); - - assertNotNull(book.resultSet()); - assertFalse(book.changed()); - assertEquals(book, book.original()); - - book.setValue(TBook_AUTHOR_ID(), 2); - assertEquals(2, (int) book.getValue(TBook_AUTHOR_ID())); - assertFalse(book.changed()); - assertEquals(book, book.original()); - - book.refresh(); - assertEquals(2, (int) book.getValue(TBook_AUTHOR_ID())); - assertFalse(book.changed()); - assertEquals(book, book.original()); - - try { - book.setValue(TBook_AUTHOR_ID(), -1); - fail(); - } - catch (DataAccessException expected) {} - - assertEquals(2, (int) book.getValue(TBook_AUTHOR_ID())); - assertFalse(book.changed()); - assertEquals(book, book.original()); - - book.close(); - assertNull(book.resultSet()); - } - - @Test - public void testKeepRSWithUpdateOnChangeDelete() throws Exception { - switch (dialect()) { - // There's a critical bug in Derby. When this test is executed, the - // connection is killed - // https://issues.apache.org/jira/browse/DERBY-6228 - case DERBY: - case SQLITE: - log.info("SKIPPING", "KeepResultSet tests"); - return; - } - - jOOQAbstractTest.reset = false; - - DSLContext create = create(new NoStatementAfterCRUDListener(Delete.class, "delete")); - Result books = - create.selectFrom(TBook()) - .orderBy(TBook_ID()) - .keepResultSet(UPDATE_ON_CHANGE) - .fetch(); - - B b2 = books.get(1); - assertEquals(1, b2.delete()); - ResultSet rs = b2.resultSet(); - rs.beforeFirst(); - assertTrue(rs.next()); - assertTrue(rs.next()); - assertTrue(rs.next()); - assertFalse(rs.next()); - - System.out.println(books); - } - - /* - * TODO: More tests: - * ----------------- - * - * [#2265] Pull up store(), delete(), refresh() from UpdatableRecord - * - store() will perform a scan and update if UPDATE_ON_STORE is set. Otherwise: no-op - * - delete() will remove the record - * - * [#1846] Add ResultQuery.keepResultSet() with UPDATE_ON_CHANGE - * - Implement all data types from ResultSet.updateXXX() (e.g. updateInt(), etc) - * - Implement UPDATE_ON_STORE - */ -} diff --git a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java index 63688a8bef..0e40ead152 100644 --- a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java +++ b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java @@ -121,7 +121,6 @@ import org.jooq.test._.testcases.GroupByTests; import org.jooq.test._.testcases.InsertUpdateTests; import org.jooq.test._.testcases.JDBCTests; import org.jooq.test._.testcases.JoinTests; -import org.jooq.test._.testcases.KeepResultSetTests; import org.jooq.test._.testcases.LoaderTests; import org.jooq.test._.testcases.MetaDataTests; import org.jooq.test._.testcases.OrderByTests; @@ -2225,36 +2224,6 @@ public abstract class jOOQAbstractTest< new BenchmarkTests(this).testBenchmarkSelect(); } - @Test - public void testKeepRSWithCloseAfterFetch() throws Exception { - new KeepResultSetTests(this).testKeepRSWithCloseAfterFetch(); - } - - @Test - public void testKeepRSWithKeepAfterFetch() throws Exception { - new KeepResultSetTests(this).testKeepRSWithKeepAfterFetch(); - } - - @Test - public void testKeepRSWithUpdateOnChange() throws Exception { - new KeepResultSetTests(this).testKeepRSWithUpdateOnChange(); - } - - @Test - public void testKeepRSWithUpdateOnChangeLazy() throws Exception { - new KeepResultSetTests(this).testKeepRSWithUpdateOnChangeLazy(); - } - - @Test - public void testKeepRSWithUpdateOnChangeFetchOne() throws Exception { - new KeepResultSetTests(this).testKeepRSWithUpdateOnChangeFetchOne(); - } - - @Test - public void testKeepRSWithUpdateOnChangeDelete() throws Exception { - new KeepResultSetTests(this).testKeepRSWithUpdateOnChangeDelete(); - } - @Test public void testKeepStatement() throws Exception { new StatementTests(this).testKeepStatement(); diff --git a/jOOQ/src/main/java/org/jooq/Cursor.java b/jOOQ/src/main/java/org/jooq/Cursor.java index 0e260ff9ff..cba3916d59 100644 --- a/jOOQ/src/main/java/org/jooq/Cursor.java +++ b/jOOQ/src/main/java/org/jooq/Cursor.java @@ -275,15 +275,6 @@ public interface Cursor extends Iterable { */ Result fetchInto(Table table) throws DataAccessException, MappingException; - /** - * Whether this Cursor closes itself after fetching all data. - *

- * By default, a Cursor will close itself after fetching all - * data. This behaviour can be overridden by - * {@link ResultQuery#keepResultSet(KeepResultSetMode)}, though. - */ - boolean closesAfterFetch(); - /** * Explicitly close the underlying {@link PreparedStatement} and * {@link ResultSet}. diff --git a/jOOQ/src/main/java/org/jooq/KeepResultSetMode.java b/jOOQ/src/main/java/org/jooq/KeepResultSetMode.java deleted file mode 100644 index 054709e5d1..0000000000 --- a/jOOQ/src/main/java/org/jooq/KeepResultSetMode.java +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com - * All rights reserved. - * - * This software is licensed to you under the Apache License, Version 2.0 - * (the "License"); You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * . Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * . Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * . Neither the name "jOOQ" nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -package org.jooq; - -import java.sql.ResultSet; - -/** - * A {@link ResultQuery}'s execution mode with respect to keeping open JDBC - * {@link ResultSet} references after fetching. - *

- * This mode type is used with - * {@link ResultQuery#keepResultSet(KeepResultSetMode)} to indicate how to deal - * with JDBC {@link ResultSet} references after fetching them into jOOQ - * {@link Result} objects. - *

- * See the various modes for details. - * - * @author Lukas Eder - */ -public enum KeepResultSetMode { - - /** - * Close the JDBC {@link ResultSet} after consuming it (this is the - * default). - *

- * If not explicitly overridden by - * {@link ResultQuery#resultSetConcurrency(int)} or - * {@link ResultQuery#resultSetType(int)}, this will apply - * {@link ResultSet#CONCUR_READ_ONLY} and - * {@link ResultSet#TYPE_FORWARD_ONLY}. - */ - CLOSE_AFTER_FETCH, - - /** - * Keep the JDBC {@link ResultSet} after consuming it. - *

- * If not explicitly overridden by - * {@link ResultQuery#resultSetConcurrency(int)} or - * {@link ResultQuery#resultSetType(int)}, this will apply - * {@link ResultSet#CONCUR_READ_ONLY} and - * {@link ResultSet#TYPE_SCROLL_SENSITIVE} (allowing for calls to - * {@link Record#refresh()} and {@link Result#refresh()}). - *

- * Client code must assure that the {@link ResultSet} is closed explicitly - * to free database resources. Closing can be done through any of these - * methods: - *

    - *
  • {@link ResultSet#close()}
  • - *
  • {@link Result#close()}
  • - *
  • {@link Cursor#close()}
  • - *
- */ - KEEP_AFTER_FETCH, - - /** - * Keep the JDBC {@link ResultSet} after consuming it, updating the - * ResultSet at every change of a {@link Record}. - *

- * If not explicitly overridden by - * {@link ResultQuery#resultSetConcurrency(int)} or - * {@link ResultQuery#resultSetType(int)}, this will apply - * {@link ResultSet#CONCUR_UPDATABLE} and - * {@link ResultSet#TYPE_SCROLL_SENSITIVE}. - *

- * TODO: More details here - *

- * Client code must assure that the {@link ResultSet} is closed explicitly - * to free database resources. Closing can be done through any of these - * methods: - *

    - *
  • {@link ResultSet#close()}
  • - *
  • {@link Result#close()}
  • - *
  • {@link Cursor#close()}
  • - *
- */ - UPDATE_ON_CHANGE, - - /** - * Keep the JDBC {@link ResultSet} after consuming it, updating the - * ResultSet at every call to {@link Record#store()}, or - * {@link Result#store()} (This is not yet supported). - *

- * If not explicitly overridden by - * {@link ResultQuery#resultSetConcurrency(int)} or - * {@link ResultQuery#resultSetType(int)}, this will apply - * {@link ResultSet#CONCUR_UPDATABLE} and - * {@link ResultSet#TYPE_SCROLL_SENSITIVE}. - *

- * TODO: More details here - *

- * Client code must assure that the {@link ResultSet} is closed explicitly - * to free database resources. Closing can be done through any of these - * methods: - *

    - *
  • {@link ResultSet#close()}
  • - *
  • {@link Result#close()}
  • - *
  • {@link Cursor#close()}
  • - *
- */ - UPDATE_ON_STORE -} diff --git a/jOOQ/src/main/java/org/jooq/Record.java b/jOOQ/src/main/java/org/jooq/Record.java index 88821d687b..695dd81ffd 100644 --- a/jOOQ/src/main/java/org/jooq/Record.java +++ b/jOOQ/src/main/java/org/jooq/Record.java @@ -48,7 +48,6 @@ import java.util.Map; import javax.persistence.Column; -import org.jooq.exception.DataAccessException; import org.jooq.exception.DataTypeException; import org.jooq.exception.MappingException; import org.jooq.tools.Convert; @@ -1038,108 +1037,4 @@ public interface Record extends Attachable, Comparable { @Override int compareTo(Record record); - // ------------------------------------------------------------------------- - // Methods related to the underlying ResultSet (if applicable) - // ------------------------------------------------------------------------- - - /** - * Refresh this record from the database. - *

- * A successful refresh results in the following: - *

    - *
  • {@link #valuesRow()} will have been restored to the respective values - * from the database
  • - *
  • {@link #original()} will match this record
  • - *
  • {@link #changed()} will be false
  • - *
- *

- * Refreshing can trigger any of the following actions: - *

    - *
  • Re-reading the underlying {@link #resultSet()}, if that - * ResultSet is available.
  • - *
  • Executing a new SELECT statement, if this is an - * {@link UpdatableRecord}.
  • - *
  • Failing, otherwise
  • - *
- *

- * This is the same as calling record.refresh(record.fields()) - * - * @throws DataAccessException This exception is thrown if - *

    - *
  • the underlying {@link #resultSet()} is in - * {@link ResultSet#TYPE_FORWARD_ONLY} mode, such that - * refreshing is not possible.
  • something went wrong - * executing the refresh SELECT statement, if this - * is an {@link UpdatableRecord}.
  • the record does not - * exist anymore in the database
  • - *
- * @see UpdatableRecord#refresh() - * @see ResultQuery#keepResultSet(KeepResultSetMode) - */ - void refresh() throws DataAccessException; - - /** - * Refresh parts of this record from the database. - *

- * A successful refresh results in the following: - *

    - *
  • {@link #valuesRow()} will have been restored to the respective values - * from the database
  • - *
  • {@link #original()} will match this record
  • - *
  • {@link #changed()} will be false
  • - *
- *

- * Refreshing can trigger any of the following actions: - *

    - *
  • Re-reading the underlying {@link #resultSet()}, if that - * ResultSet is available.
  • - *
  • Executing a new SELECT statement, if this is an - * {@link UpdatableRecord}.
  • - *
  • Failing, otherwise
  • - *
- *

- * This is the same as calling record.refresh(record.fields()) - * - * @throws DataAccessException This exception is thrown if - *

    - *
  • the underlying {@link #resultSet()} is in - * {@link ResultSet#TYPE_FORWARD_ONLY} mode, such that - * refreshing is not possible.
  • something went wrong - * executing the refresh SELECT statement, if this - * is an {@link UpdatableRecord}.
  • the record does not - * exist anymore in the database
  • - *
- * @see UpdatableRecord#refresh() - * @see ResultQuery#keepResultSet(KeepResultSetMode) - */ - void refresh(Field... fields) throws DataAccessException; - - /** - * Close the underlying JDBC {@link ResultSet}, if applicable. - *

- * If this Record was created using - * {@link ResultQuery#keepResultSet(KeepResultSetMode)}, then it closes the - * underlying JDBC {@link ResultSet}. Otherwise, this method has no effect. - *

- * Note, this will close the ResultSet for all records that - * were fetched from the same ResultQuery. - * - * @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 - * Record 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/Result.java b/jOOQ/src/main/java/org/jooq/Result.java index 2360d0bdaa..2180a8a2d2 100644 --- a/jOOQ/src/main/java/org/jooq/Result.java +++ b/jOOQ/src/main/java/org/jooq/Result.java @@ -41,7 +41,6 @@ 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; @@ -1082,33 +1081,4 @@ public interface Result extends List, Attachable { * @see String#intern() */ Result intern(String... fieldNames); - - // ------------------------------------------------------------------------- - // Methods related to the underlying ResultSet (if applicable) - // ------------------------------------------------------------------------- - - /** - * 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/ResultQuery.java b/jOOQ/src/main/java/org/jooq/ResultQuery.java index 25e3122ff5..c920437a8b 100644 --- a/jOOQ/src/main/java/org/jooq/ResultQuery.java +++ b/jOOQ/src/main/java/org/jooq/ResultQuery.java @@ -991,18 +991,6 @@ public interface ResultQuery extends Query { @Override ResultQuery keepStatement(boolean keepStatement); - /** - * Indicate how to deal with the JDBC {@link ResultSet} when fetching data - * into jOOQ {@link Result} or {@link Cursor} objects. - *

- * TODO: More info here. - *

- * Note: If JDBC ResultSet references are kept - * open after fetching data through jOOQ, you must explicitly close them - * using either {@link Result#close()}, or {@link Cursor#close()} - */ - ResultQuery keepResultSet(KeepResultSetMode mode); - /** * Specify the maximum number of rows returned by the underlying * {@link Statement}. diff --git a/jOOQ/src/main/java/org/jooq/UpdatableRecord.java b/jOOQ/src/main/java/org/jooq/UpdatableRecord.java index a23ab7600a..b5d372950a 100644 --- a/jOOQ/src/main/java/org/jooq/UpdatableRecord.java +++ b/jOOQ/src/main/java/org/jooq/UpdatableRecord.java @@ -301,15 +301,63 @@ public interface UpdatableRecord> extends TableReco int delete() throws DataAccessException, DataChangedException; /** - * {@inheritDoc} + * Refresh this record from the database. + *

+ * A successful refresh results in the following: + *

    + *
  • {@link #valuesRow()} will have been restored to the respective values + * from the database
  • + *
  • {@link #original()} will match this record
  • + *
  • {@link #changed()} will be false
  • + *
+ *

+ * Refreshing can trigger any of the following actions: + *

    + *
  • Executing a new SELECT statement, if this is an + * {@link UpdatableRecord}.
  • + *
  • Failing, otherwise
  • + *
+ *

+ * This is the same as calling record.refresh(record.fields()) + * + * @throws DataAccessException This exception is thrown if + *

    + *
  • something went wrong executing the refresh SELECT + * statement, if this is an {@link UpdatableRecord}. + *
  • the record does not exist anymore in the database + *
  • + *
*/ - @Override void refresh() throws DataAccessException; /** - * {@inheritDoc} + * Refresh parts of this record from the database. + *

+ * A successful refresh results in the following: + *

    + *
  • {@link #valuesRow()} will have been restored to the respective values + * from the database
  • + *
  • {@link #original()} will match this record
  • + *
  • {@link #changed()} will be false
  • + *
+ *

+ * Refreshing can trigger any of the following actions: + *

    + *
  • Executing a new SELECT statement, if this is an + * {@link UpdatableRecord}.
  • + *
  • Failing, otherwise
  • + *
+ *

+ * This is the same as calling record.refresh(record.fields()) + * + * @throws DataAccessException This exception is thrown if + *

    + *
  • something went wrong + * executing the refresh SELECT statement, if this + * is an {@link UpdatableRecord}.
  • the record does not + * exist anymore in the database
  • + *
*/ - @Override void refresh(Field... fields) throws DataAccessException; /** diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java index 4c469b731c..248edc2e04 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java @@ -37,17 +37,14 @@ package org.jooq.impl; import static java.util.Arrays.asList; -import static org.jooq.KeepResultSetMode.UPDATE_ON_CHANGE; import static org.jooq.impl.Utils.getAnnotatedGetter; import static org.jooq.impl.Utils.getAnnotatedMembers; import static org.jooq.impl.Utils.getMatchingGetter; import static org.jooq.impl.Utils.getMatchingMembers; import static org.jooq.impl.Utils.hasColumnAnnotations; -import static org.jooq.impl.Utils.translate; import java.lang.reflect.Method; import java.sql.ResultSet; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; @@ -57,16 +54,13 @@ import java.util.Map; import org.jooq.Attachable; import org.jooq.Converter; import org.jooq.Field; -import org.jooq.KeepResultSetMode; import org.jooq.Record; import org.jooq.RecordMapper; import org.jooq.Result; import org.jooq.Table; import org.jooq.UniqueKey; -import org.jooq.exception.DataAccessException; import org.jooq.exception.InvalidResultException; import org.jooq.exception.MappingException; -import org.jooq.impl.CursorImpl.CursorResultSet; import org.jooq.tools.Convert; /** @@ -84,9 +78,6 @@ abstract class AbstractRecord extends AbstractStore implements Record { final RowImpl fields; final Value[] values; - transient KeepResultSetMode keepResultSetMode; - transient CursorResultSet rs; - transient int rsIndex; AbstractRecord(Collection> fields) { this(new RowImpl(fields)); @@ -276,53 +267,26 @@ abstract class AbstractRecord extends AbstractStore implements Record { @Override public final void setValue(Field field, T value) { Value val = getValue0(field); + UniqueKey key = getPrimaryKey(); - // [#1846] Execute this first to fail early, when UPDATE_ON_CHANGE fails - if (rs != null && keepResultSetMode == UPDATE_ON_CHANGE) { - int index = fieldsRow().indexOf(field); - int columnIndex = index + 1; - - try { - if (rs.getRow() != rsIndex) { - rs.absolute(rsIndex); - } - - // [#1846] TODO: Add more typesafety here - rs.updateObject(columnIndex, value); - - // [#1846] TODO: Update only in case of KeepResultSetMode.UPDATE_ON_CHANGE - rs.updateRow(); - } - catch (SQLException e) { - throw translate("Error when updating ResultSet", e); - } - - setValue(index, new Value(value)); + // Normal fields' changed flag is always set to true + if (key == null || !key.getFields().contains(field)) { + val.setValue(value); } - // [#1846] In all other cases, correctly handle changed flags + // The primary key's changed flag might've been set previously + else if (val.isChanged()) { + val.setValue(value); + } + + // [#979] If the primary key is being changed, all other fields' flags + // need to be set to true for in case this record is stored again, an + // INSERT statement will thus be issued else { - UniqueKey key = getPrimaryKey(); + val.setValue(value, true); - // Normal fields' changed flag is always set to true - if (key == null || !key.getFields().contains(field)) { - val.setValue(value); - } - - // The primary key's changed flag might've been set previously - else if (val.isChanged()) { - val.setValue(value); - } - - // [#979] If the primary key is being changed, all other fields' flags - // need to be set to true for in case this record is stored again, an - // INSERT statement will thus be issued - else { - val.setValue(value, true); - - if (val.isChanged()) { - changed(true); - } + if (val.isChanged()) { + changed(true); } } } @@ -553,7 +517,7 @@ abstract class AbstractRecord extends AbstractStore implements Record { @Override public final ResultSet intoResultSet() { - ResultImpl result = new ResultImpl(configuration(), rs, fields.fields.fields); + ResultImpl result = new ResultImpl(configuration(), fields.fields.fields); result.add(this); return result.intoResultSet(); } @@ -690,68 +654,13 @@ abstract class AbstractRecord extends AbstractStore implements Record { } } - // ------------------------------------------------------------------------- - // XXX: Methods related to the underlying ResultSet (if applicable) - // ------------------------------------------------------------------------- - - @Override - public final void refresh() { - refresh(fields.fields.fields); - } - - /** - * {@inheritDoc} - *

- * Subclasses may override this - */ - @Override - public void refresh(Field... f) { - checkRsAvailable("Cannot refresh record. No ResultSet available"); - - try { - - // [#2265] TODO: This code is prototypical. fetchLazy() is not - // the best way to fetch a record - rs.absolute(rsIndex - 1); - AbstractRecord record = (AbstractRecord) create().fetchLazy(rs).fetchOne(); - setValues(f, record); - } - catch (SQLException e) { - throw translate("Cannot refresh record", e); - } - } - - private final void checkRsAvailable(String message) { - if (rs == null) { - throw new DataAccessException(message); - } - } - - @Override - public final void close() { - try { - if (rs != null) { - rs.close(); - rs = null; - } - } - catch (SQLException e) { - throw translate("Cannot close ResultSet", e); - } - } - - @Override - public final ResultSet resultSet() { - return rs; - } - // ------------------------------------------------------------------------ // XXX: Object and Comparable API // ------------------------------------------------------------------------ @Override public String toString() { - Result result = new ResultImpl(configuration(), null, fields.fields.fields); + Result result = new ResultImpl(configuration(), 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 d15781de9c..4c019ea645 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java @@ -35,15 +35,10 @@ */ package org.jooq.impl; -import static java.sql.ResultSet.CONCUR_READ_ONLY; import static java.sql.ResultSet.CONCUR_UPDATABLE; import static java.sql.ResultSet.TYPE_SCROLL_SENSITIVE; import static java.util.Arrays.asList; import static java.util.concurrent.Executors.newSingleThreadExecutor; -import static org.jooq.KeepResultSetMode.CLOSE_AFTER_FETCH; -import static org.jooq.KeepResultSetMode.KEEP_AFTER_FETCH; -import static org.jooq.KeepResultSetMode.UPDATE_ON_CHANGE; -import static org.jooq.KeepResultSetMode.UPDATE_ON_STORE; import static org.jooq.SQLDialect.ASE; import static org.jooq.SQLDialect.CUBRID; import static org.jooq.SQLDialect.SQLSERVER; @@ -67,7 +62,6 @@ import org.jooq.ExecuteContext; import org.jooq.ExecuteListener; import org.jooq.Field; import org.jooq.FutureResult; -import org.jooq.KeepResultSetMode; import org.jooq.Record; import org.jooq.RecordHandler; import org.jooq.RecordMapper; @@ -92,7 +86,6 @@ abstract class AbstractResultQuery extends AbstractQuery imple private static final JooqLogger log = JooqLogger.getLogger(AbstractResultQuery.class); private int maxRows; - private KeepResultSetMode keepResultSetMode; private int resultSetConcurrency; private int resultSetType; private int resultSetHoldability; @@ -141,15 +134,6 @@ abstract class AbstractResultQuery extends AbstractQuery imple return (ResultQuery) super.keepStatement(k); } - @Override - public final ResultQuery keepResultSet(KeepResultSetMode mode) { - if (mode == UPDATE_ON_STORE) - throw new UnsupportedOperationException("UPDATE_ON_STORE is not yet supported"); - - this.keepResultSetMode = mode; - return this; - } - @Override public final ResultQuery maxRows(int rows) { this.maxRows = rows; @@ -224,17 +208,6 @@ abstract class AbstractResultQuery extends AbstractQuery imple } } - // [#1846] When scrollable Results are fetched - else if (keepResultSetMode == KEEP_AFTER_FETCH) { - ctx.statement(ctx.connection().prepareStatement(ctx.sql(), TYPE_SCROLL_SENSITIVE, CONCUR_READ_ONLY)); - } - - // [#1846] When scrollable and updatable Results are fetched - else if (keepResultSetMode == UPDATE_ON_CHANGE || - keepResultSetMode == UPDATE_ON_STORE) { - ctx.statement(ctx.connection().prepareStatement(ctx.sql(), TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE)); - } - // [#1296] These dialects do not implement FOR UPDATE. But the same // effect can be achieved using ResultSet.CONCUR_UPDATABLE else if (isForUpdate() && asList(CUBRID, SQLSERVER).contains(ctx.configuration().dialect().family())) { @@ -284,7 +257,7 @@ abstract class AbstractResultQuery extends AbstractQuery imple if (!many) { if (ctx.resultSet() != null) { Field[] fields = getFields(ctx.resultSet().getMetaData()); - cursor = new CursorImpl(ctx, listener, fields, internIndexes(fields), keepStatement(), keepResultSet(), keepResultSetMode, getRecordType()); + cursor = new CursorImpl(ctx, listener, fields, internIndexes(fields), keepStatement(), keepResultSet(), getRecordType()); if (!lazy) { result = cursor.fetch(); @@ -292,7 +265,7 @@ abstract class AbstractResultQuery extends AbstractQuery imple } } else { - result = new ResultImpl(ctx.configuration(), null); + result = new ResultImpl(ctx.configuration()); } } @@ -305,7 +278,7 @@ abstract class AbstractResultQuery extends AbstractQuery imple anyResults = true; Field[] fields = new MetaDataFieldProvider(ctx.configuration(), ctx.resultSet().getMetaData()).getFields(); - Cursor c = new CursorImpl(ctx, listener, fields, internIndexes(fields), true, false, CLOSE_AFTER_FETCH); + Cursor c = new CursorImpl(ctx, listener, fields, internIndexes(fields), true, false); results.add(c.fetch()); if (ctx.statement().getMoreResults()) { @@ -328,10 +301,7 @@ abstract class AbstractResultQuery extends AbstractQuery imple @Override protected final boolean keepResultSet() { - return lazy - || keepResultSetMode == KEEP_AFTER_FETCH - || keepResultSetMode == UPDATE_ON_CHANGE - || keepResultSetMode == UPDATE_ON_STORE; + return lazy; } /** @@ -496,9 +466,7 @@ abstract class AbstractResultQuery extends AbstractQuery imple return c.fetchOne(); } finally { - if (c.closesAfterFetch()) { - c.close(); - } + c.close(); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java index 0f2e75fbb7..59cac4f142 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java @@ -35,7 +35,6 @@ */ package org.jooq.impl; -import static org.jooq.KeepResultSetMode.CLOSE_AFTER_FETCH; import static org.jooq.impl.Utils.fieldArray; import static org.jooq.util.sqlite.SQLiteDSL.rowid; @@ -143,7 +142,7 @@ abstract class AbstractStoreQuery extends AbstractQuery implem @Override public final Result getReturnedRecords() { if (returned == null) { - returned = new ResultImpl(configuration(), null, returning); + returned = new ResultImpl(configuration(), returning); } return returned; @@ -345,7 +344,7 @@ abstract class AbstractStoreQuery extends AbstractQuery implem ExecuteListener listener2 = new ExecuteListeners(ctx2); ctx2.resultSet(rs); - returned = new CursorImpl(ctx2, listener2, fieldArray(returning), null, false, true, CLOSE_AFTER_FETCH).fetch().into(getInto()); + returned = new CursorImpl(ctx2, listener2, fieldArray(returning), null, false, true).fetch().into(getInto()); return result; } } diff --git a/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java b/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java index a2775d94de..4bf356f469 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java @@ -36,7 +36,6 @@ package org.jooq.impl; import static java.lang.Boolean.TRUE; -import static org.jooq.KeepResultSetMode.CLOSE_AFTER_FETCH; import static org.jooq.impl.Utils.DATA_LOCK_ROWS_FOR_UPDATE; import java.io.InputStream; @@ -67,7 +66,6 @@ import org.jooq.Cursor; import org.jooq.ExecuteContext; import org.jooq.ExecuteListener; import org.jooq.Field; -import org.jooq.KeepResultSetMode; import org.jooq.Record; import org.jooq.RecordHandler; import org.jooq.RecordMapper; @@ -90,7 +88,6 @@ class CursorImpl implements Cursor { private final Field[] fields; private final boolean[] intern; private final boolean keepResultSet; - private final KeepResultSetMode keepResultSetMode; private final boolean keepStatement; private final Class type; private boolean isClosed; @@ -100,18 +97,17 @@ class CursorImpl implements Cursor { private transient Iterator iterator; @SuppressWarnings("unchecked") - CursorImpl(ExecuteContext ctx, ExecuteListener listener, Field[] fields, int[] internIndexes, boolean keepStatement, boolean keepResultSet, KeepResultSetMode keepResultSetMode) { - this(ctx, listener, fields, internIndexes, keepStatement, keepResultSet, keepResultSetMode, (Class) RecordImpl.class); + CursorImpl(ExecuteContext ctx, ExecuteListener listener, Field[] fields, int[] internIndexes, boolean keepStatement, boolean keepResultSet) { + this(ctx, listener, fields, internIndexes, keepStatement, keepResultSet, (Class) RecordImpl.class); } - CursorImpl(ExecuteContext ctx, ExecuteListener listener, Field[] fields, int[] internIndexes, boolean keepStatement, boolean keepResultSet, KeepResultSetMode keepResultSetMode, Class type) { + CursorImpl(ExecuteContext ctx, ExecuteListener listener, Field[] fields, int[] internIndexes, boolean keepStatement, boolean keepResultSet, Class type) { this.ctx = ctx; this.listener = (listener != null ? listener : new ExecuteListeners(ctx)); this.fields = fields; this.type = type; this.keepStatement = keepStatement; this.keepResultSet = keepResultSet; - this.keepResultSetMode = keepResultSetMode; this.rs = new CursorResultSet(); this.intern = new boolean[fields.length]; @@ -122,11 +118,6 @@ class CursorImpl implements Cursor { } } - @Override - public final boolean closesAfterFetch() { - return keepResultSetMode == null || keepResultSetMode == CLOSE_AFTER_FETCH; - } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public final Row fieldsRow() { @@ -190,7 +181,7 @@ class CursorImpl implements Cursor { // Before listener.resultStart(ctx) iterator(); - ResultImpl result = new ResultImpl(ctx.configuration(), closesAfterFetch() ? null : rs, fields); + ResultImpl result = new ResultImpl(ctx.configuration(), fields); R record = null; ctx.result(result); @@ -1402,14 +1393,6 @@ class CursorImpl implements Cursor { record = (AbstractRecord) Utils.newRecord(type, fields, ctx.configuration()); - // [#1846] Add a reference to the Cursor's ResultSet if - // Updatable ResultSets are requested - if (!closesAfterFetch()) { - record.keepResultSetMode = keepResultSetMode; - record.rs = rs; - record.rsIndex = rsIndex; - } - ctx.record(record); listener.recordStart(ctx); @@ -1434,9 +1417,7 @@ class CursorImpl implements Cursor { // [#1868] [#2373] [#2385] This calls through to Utils.safeClose() // if necessary, lazy-terminating the ExecuteListener lifecycle if // the result is not eager-fetched. - // [#1846] When fetching updatable Results, do not close the - // Cursor's ResultSet! - if (record == null && closesAfterFetch()) { + if (record == null) { CursorImpl.this.close(); } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index f15df43d15..93a11441a0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -36,7 +36,6 @@ package org.jooq.impl; -import static org.jooq.KeepResultSetMode.CLOSE_AFTER_FETCH; import static org.jooq.conf.ParamType.INLINED; import static org.jooq.conf.ParamType.NAMED; import static org.jooq.impl.DSL.field; @@ -515,7 +514,7 @@ public class DefaultDSLContext implements DSLContext, Serializable { ExecuteListener listener = new ExecuteListeners(ctx); ctx.resultSet(rs); - return new CursorImpl(ctx, listener, fields, null, false, true, CLOSE_AFTER_FETCH); + return new CursorImpl(ctx, listener, fields, null, false, true); } @Override @@ -585,7 +584,7 @@ public class DefaultDSLContext implements DSLContext, Serializable { @Override public Result fetchFromStringData(List data) { if (data.size() == 0) { - return new ResultImpl(configuration, null); + return new ResultImpl(configuration); } else { List> fields = new ArrayList>(); @@ -594,7 +593,7 @@ public class DefaultDSLContext implements DSLContext, Serializable { fields.add(fieldByName(String.class, name)); } - Result result = new ResultImpl(configuration, null, fields); + Result result = new ResultImpl(configuration, fields); if (data.size() > 1) { for (String[] values : data.subList(1, data.size())) { @@ -1456,7 +1455,7 @@ public class DefaultDSLContext implements DSLContext, Serializable { @Override public Result newResult(Table table) { - return new ResultImpl(configuration, null, table.fields()); + return new ResultImpl(configuration, 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 62fd065499..636be55f9e 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(), null, key.getFields()); + return new ResultImpl(new DefaultConfiguration(), 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(), null, getFields()); + return new ResultImpl(new DefaultConfiguration(), 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 b5138e874b..a276cc8673 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java @@ -38,14 +38,12 @@ 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; @@ -97,22 +95,20 @@ class ResultImpl implements Result, AttachableInternal { private static final long serialVersionUID = 6416154375799578362L; private Configuration configuration; - private transient ResultSet rs; private final Fields fields; private final List records; - ResultImpl(Configuration configuration, ResultSet rs, Collection> fields) { - this(configuration, rs, new Fields(fields)); + ResultImpl(Configuration configuration, Collection> fields) { + this(configuration, new Fields(fields)); } - ResultImpl(Configuration configuration, ResultSet rs, Field... fields) { - this(configuration, rs, new Fields(fields)); + ResultImpl(Configuration configuration, Field... fields) { + this(configuration, new Fields(fields)); } - ResultImpl(Configuration configuration, ResultSet rs, Fields fields) { + ResultImpl(Configuration configuration, Fields fields) { this.configuration = configuration; this.fields = fields; - this.rs = rs; this.records = new ArrayList(); } @@ -863,7 +859,7 @@ class ResultImpl implements Result, AttachableInternal { Result result = map.get(val); if (result == null) { - result = new ResultImpl(configuration, rs, fields); + result = new ResultImpl(configuration, fields); map.put(val, result); } @@ -915,7 +911,7 @@ class ResultImpl implements Result, AttachableInternal { Result result = map.get(key); if (result == null) { - result = new ResultImpl(configuration(), rs, this.fields); + result = new ResultImpl(configuration(), this.fields); map.put(key, result); } @@ -1059,7 +1055,7 @@ class ResultImpl implements Result, AttachableInternal { @Override public final Result into(Table table) { - Result list = new ResultImpl(configuration(), rs, table.fields()); + Result list = new ResultImpl(configuration(), table.fields()); for (R record : this) { list.add(record.into(table)); @@ -1192,30 +1188,6 @@ 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; - } - } - } - } - 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> */ diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java index 5d61123e05..dd280987ee 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java @@ -56,7 +56,6 @@ import org.jooq.ForeignKey; import org.jooq.FutureResult; import org.jooq.GroupField; import org.jooq.JoinType; -import org.jooq.KeepResultSetMode; import org.jooq.Operator; import org.jooq.Param; import org.jooq.QueryPart; @@ -969,11 +968,6 @@ class SelectImpl extends AbstractDelegatingQuery> im return getDelegate().maxRows(rows); } - @Override - public ResultQuery keepResultSet(KeepResultSetMode mode) { - return getDelegate().keepResultSet(mode); - } - @Override public final ResultQuery resultSetConcurrency(int resultSetConcurrency) { return getDelegate().resultSetConcurrency(resultSetConcurrency); diff --git a/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java b/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java index 7dc295179e..701e3c00bc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java @@ -334,31 +334,24 @@ public class UpdatableRecordImpl> extends TableReco } } + @Override + public final void refresh() { + refresh(fields.fields.fields); + } + @Override public final void refresh(Field... f) { - if (rs != null) { - super.refresh(f); + SelectQuery select = create().selectQuery(); + select.addSelect(f); + select.addFrom(getTable()); + Utils.addConditions(select, this, getPrimaryKey().getFieldsArray()); + + if (select.execute() == 1) { + AbstractRecord record = (AbstractRecord) select.getResult().get(0); + setValues(f, record); } else { - - // [#2265] Even if rs was previously closed, re-fetch a new ResultSet - // and assign it to this record, if requested. - SelectQuery select = create().selectQuery(); - select.addSelect(f); - select.addFrom(getTable()); - select.keepResultSet(keepResultSetMode); - Utils.addConditions(select, this, getPrimaryKey().getFieldsArray()); - - if (select.execute() == 1) { - AbstractRecord record = (AbstractRecord) select.getResult().get(0); - setValues(f, record); - - rs = record.rs; - rsIndex = record.rsIndex; - } - else { - throw new InvalidResultException("Exactly one row expected for refresh. Record does not exist in database."); - } + throw new InvalidResultException("Exactly one row expected for refresh. Record does not exist in database."); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/Utils.java b/jOOQ/src/main/java/org/jooq/impl/Utils.java index 61f36f9164..0b78378235 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Utils.java +++ b/jOOQ/src/main/java/org/jooq/impl/Utils.java @@ -754,9 +754,7 @@ final class Utils { return record; } finally { - if (cursor.closesAfterFetch()) { - cursor.close(); - } + cursor.close(); } }