All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jooq.Cursor Maven / Gradle / Ivy

There is a newer version: 3.19.15
Show newest version
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Other licenses:
 * -----------------------------------------------------------------------------
 * Commercial licenses for this work are available. These replace the above
 * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
 * database integrations.
 *
 * For more information, please visit: https://www.jooq.org/legal/licensing
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package org.jooq;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Stream;

import org.jooq.conf.Settings;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.MappingException;
import org.jooq.impl.DefaultRecordMapper;

import org.jetbrains.annotations.Blocking;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Cursors allow for lazy, sequential access to an underlying JDBC
 * {@link ResultSet}. Unlike {@link Result}, data can only be accessed
 * sequentially, using an {@link Iterator}, or the cursor's {@link #hasNext()}
 * and {@link #fetch()} methods.
 * 

* Client code must close this {@link Cursor} in order to close the underlying * {@link PreparedStatement} and {@link ResultSet} *

* The cursor can be consumed in two ways: *

    *
  • Record by record: Such methods can be recognised by the term "Next" in * the method name, e.g. {@link #fetchNext(int)}.
  • *
  • Completely in one go: Such methods do not have the term "Next" in their * method names, e.g. {@link #fetch()}.
  • *
*

* Note: Unlike usual implementations of {@link Iterable}, a Cursor * can only provide one {@link Iterator}! * * @param The cursor's record type * @author Lukas Eder */ @Blocking public interface Cursor extends Fields, Iterable, Formattable, AutoCloseable { /** * Get this cursor's row type. */ @NotNull RecordType recordType(); /** * Check whether this cursor has a next record. *

* This will conveniently close the Cursor, after the last * Record was fetched. * * @throws DataAccessException if something went wrong executing the query */ boolean hasNext() throws DataAccessException; /** * Fetch all remaining records as a result. *

* This will conveniently close the Cursor, after the last * Record was fetched. *

* The result and its contained records are attached to the original * {@link Configuration} by default. Use {@link Settings#isAttachRecords()} * to override this behaviour. * * @throws DataAccessException if something went wrong executing the query */ @NotNull Result fetch() throws DataAccessException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNext(int)} instead. */ @NotNull @Deprecated(forRemoval = true, since = "3.10") Result fetch(int number) throws DataAccessException; /** * Fetch the next couple of records from the cursor. *

* This will conveniently close the Cursor, after the last * Record was fetched. *

* The result and its contained records are attached to the original * {@link Configuration} by default. Use {@link Settings#isAttachRecords()} * to override this behaviour. * * @param number The number of records to fetch. If this is 0 * or negative an empty list is returned, the cursor is * untouched. If this is greater than the number of remaining * records, then all remaining records are returned. * @throws DataAccessException if something went wrong executing the query */ @NotNull Result fetchNext(int number) throws DataAccessException; /** * Fetch results into a custom handler callback. *

* The resulting records are attached to the original {@link Configuration} * by default. Use {@link Settings#isAttachRecords()} to override this * behaviour. * * @param handler The handler callback * @return Convenience result, returning the parameter handler itself * @throws DataAccessException if something went wrong executing the query * @deprecated - 3.15.0 - [#11902] - Use {@link Iterable#forEach(Consumer)} * based methods, instead. */ @Deprecated(forRemoval = true, since = "3.15") @NotNull > H fetchInto(H handler) throws DataAccessException; /** * Fetch results into a custom mapper callback. * * @param mapper The mapper callback * @return The custom mapped records * @throws DataAccessException if something went wrong executing the query */ @NotNull List fetch(RecordMapper mapper) throws DataAccessException; /** * Map resulting records onto a custom type. *

* This is the same as calling fetch().into(type). See * {@link Record#into(Class)} for more details * * @param The generic entity type. * @param type The entity type. * @see Record#into(Class) * @see Result#into(Class) * @throws DataAccessException if something went wrong executing the query * @throws MappingException wrapping any reflection or data type conversion * exception that might have occurred while mapping records * @see DefaultRecordMapper */ @NotNull List fetchInto(Class type) throws DataAccessException, MappingException; /** * Map resulting records onto a custom record. *

* This is the same as calling fetch().into(table). See * {@link Record#into(Class)} for more details *

* The result and its contained records are attached to the original * {@link Configuration} by default. Use {@link Settings#isAttachRecords()} * to override this behaviour. * * @param The generic table record type. * @param table The table type. * @see Record#into(Class) * @see Result#into(Class) * @throws DataAccessException if something went wrong executing the query * @throws MappingException wrapping any reflection or data type conversion * exception that might have occurred while mapping records */ @NotNull Result fetchInto(Table table) throws DataAccessException, MappingException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNext()} instead. */ @Nullable @Deprecated(forRemoval = true, since = "3.10") R fetchOne() throws DataAccessException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNextInto(RecordHandler)} instead. * @deprecated - 3.15.0 - [#11902] - Use {@link Iterable#forEach(Consumer)} * based methods, instead. */ @NotNull @Deprecated(forRemoval = true, since = "3.10") > H fetchOneInto(H handler) throws DataAccessException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNext(RecordMapper)} instead. */ @Nullable @Deprecated(forRemoval = true, since = "3.10") E fetchOne(RecordMapper mapper) throws DataAccessException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNextInto(Table)} instead. */ @Nullable @Deprecated(forRemoval = true, since = "3.10") Z fetchOneInto(Table table) throws DataAccessException, MappingException; /** * Fetch the next record from the cursor. *

* This will conveniently close the Cursor, after the last * Record was fetched. *

* The resulting record is attached to the original {@link Configuration} by * default. Use {@link Settings#isAttachRecords()} to override this * behaviour. * * @return The next record from the cursor, or null if there is * no next record. * @throws DataAccessException if something went wrong executing the query */ @Nullable R fetchNext() throws DataAccessException; /** * Fetch the next record into a custom handler callback. *

* This will conveniently close the Cursor, after the last * Record was fetched. *

* The resulting record is attached to the original {@link Configuration} by * default. Use {@link Settings#isAttachRecords()} to override this * behaviour. * * @param handler The handler callback * @return Convenience result, returning the parameter handler itself * @throws DataAccessException if something went wrong executing the query * @deprecated - 3.15.0 - [#11902] - Use {@link Iterable#forEach(Consumer)} * based methods, instead. */ @Deprecated(forRemoval = true, since = "3.15") @NotNull > H fetchNextInto(H handler) throws DataAccessException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNextInto(Class)} instead. */ @Nullable @Deprecated(forRemoval = true, since = "3.10") E fetchOneInto(Class type) throws DataAccessException, MappingException; /** * Map the next resulting record onto a custom type. *

* This is the same as calling fetchOne().into(type). See * {@link Record#into(Class)} for more details * * @param The generic entity type. * @param type The entity type. * @see Record#into(Class) * @see Result#into(Class) * @throws DataAccessException if something went wrong executing the query * @throws MappingException wrapping any reflection or data type conversion * exception that might have occurred while mapping records * @see DefaultRecordMapper */ @Nullable E fetchNextInto(Class type) throws DataAccessException, MappingException; /** * Fetch the next record into a custom mapper callback. *

* This will conveniently close the Cursor, after the last * Record was fetched. * * @param mapper The mapper callback * @return The custom mapped record * @throws DataAccessException if something went wrong executing the query */ @Nullable E fetchNext(RecordMapper mapper) throws DataAccessException; /** * Map the next resulting record onto a custom record. *

* This is the same as calling fetchOne().into(table). See * {@link Record#into(Class)} for more details *

* The resulting record is attached to the original {@link Configuration} by * default. Use {@link Settings#isAttachRecords()} to override this * behaviour. * * @param The generic table record type. * @param table The table type. * @see Record#into(Class) * @see Result#into(Class) * @throws DataAccessException if something went wrong executing the query * @throws MappingException wrapping any reflection or data type conversion * exception that might have occurred while mapping records */ @Nullable Z fetchNextInto(Table table) throws DataAccessException, MappingException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNextOptional()} instead. */ @NotNull @Deprecated(forRemoval = true, since = "3.10") Optional fetchOptional() throws DataAccessException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNextOptionalInto(Class)} instead. */ @NotNull @Deprecated(forRemoval = true, since = "3.10") Optional fetchOptionalInto(Class type) throws DataAccessException, MappingException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNextOptional(RecordMapper)} instead. */ @NotNull @Deprecated(forRemoval = true, since = "3.10") Optional fetchOptional(RecordMapper mapper) throws DataAccessException; /** * @deprecated - 3.10 - [#6363] - Use {@link #fetchNextOptionalInto(Table)} instead. */ @NotNull @Deprecated(forRemoval = true, since = "3.10") Optional fetchOptionalInto(Table table) throws DataAccessException, MappingException; /** * Fetch the next record from the cursor. *

* This will conveniently close the Cursor, after the last * Record was fetched. *

* The resulting record is attached to the original {@link Configuration} by * default. Use {@link Settings#isAttachRecords()} to override this * behaviour. * * @return The next record from the cursor * @throws DataAccessException if something went wrong executing the query */ @NotNull Optional fetchNextOptional() throws DataAccessException; /** * Map the next resulting record onto a custom type. *

* This is the same as calling fetchOne().into(type). See * {@link Record#into(Class)} for more details * * @param The generic entity type. * @param type The entity type. * @see Record#into(Class) * @see Result#into(Class) * @throws DataAccessException if something went wrong executing the query * @throws MappingException wrapping any reflection or data type conversion * exception that might have occurred while mapping records * @see DefaultRecordMapper */ @NotNull Optional fetchNextOptionalInto(Class type) throws DataAccessException, MappingException; /** * Fetch the next record into a custom mapper callback. *

* This will conveniently close the Cursor, after the last * Record was fetched. * * @param mapper The mapper callback * @return The custom mapped record * @throws DataAccessException if something went wrong executing the query */ @NotNull Optional fetchNextOptional(RecordMapper mapper) throws DataAccessException; /** * Map the next resulting record onto a custom record. *

* This is the same as calling fetchOne().into(table). See * {@link Record#into(Class)} for more details *

* The resulting record is attached to the original {@link Configuration} by * default. Use {@link Settings#isAttachRecords()} to override this * behaviour. * * @param The generic table record type. * @param table The table type. * @see Record#into(Class) * @see Result#into(Class) * @throws DataAccessException if something went wrong executing the query * @throws MappingException wrapping any reflection or data type conversion * exception that might have occurred while mapping records */ @NotNull Optional fetchNextOptionalInto(Table table) throws DataAccessException, MappingException; /** * Turn this Cursor into a {@link Stream}. * * @throws DataAccessException if something went wrong executing the query */ @NotNull Stream stream() throws DataAccessException; /** * Reduce the execution results of this query using a {@link Collector}. *

* This works in the same way as calling the following code: * *

     * 
     * cursor.stream().collect(collector);
     * 
     * 
* * @param collector The collector that collects all records and accumulates * them into a result type. * @return The result of the collection. * @throws DataAccessException if something went wrong executing the query */ X collect(Collector collector) throws DataAccessException; /** * Explicitly close the underlying {@link PreparedStatement} and * {@link ResultSet}. *

* If you fetch all records from the underlying {@link ResultSet}, jOOQ * Cursor implementations will close themselves for you. * Calling close() again will have no effect. * * @throws DataAccessException if something went wrong executing the query */ @Override void close() throws DataAccessException; /** * Check whether this Cursor has been explicitly or * "conveniently" closed. *

* Explicit closing can be achieved by calling {@link #close()} from client * code. "Convenient" closing is done by any of the other methods, when the * last record was fetched. */ boolean isClosed(); /** * Get the Cursor's underlying {@link ResultSet}. *

* This will return a {@link ResultSet} wrapping the JDBC driver's * ResultSet. Closing this ResultSet may close the * producing {@link Statement} or {@link PreparedStatement}, depending on * your setting for {@link ResultQuery#keepStatement(boolean)}. *

* Modifying this ResultSet will affect this * Cursor. * * @return The underlying ResultSet. May be null, * for instance when the Cursor is closed. */ @Nullable ResultSet resultSet(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy