org.jooq.Cursor Maven / Gradle / Ivy
/**
* Copyright (c) 2009-2014, Data Geekery GmbH (http://www.datageekery.com)
* All rights reserved.
*
* This work is dual-licensed
* - under the Apache Software License 2.0 (the "ASL")
* - under the jOOQ License and Maintenance Agreement (the "jOOQ License")
* =============================================================================
* You may choose which license applies to you:
*
* - If you're using this work with Open Source databases, you may choose
* either ASL or jOOQ License.
* - If you're using this work with at least one commercial database, you must
* choose jOOQ License
*
* For more information, please visit http://www.jooq.org/licenses
*
* Apache Software License 2.0:
* -----------------------------------------------------------------------------
* 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
*
* http://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.
*
* jOOQ License and Maintenance Agreement:
* -----------------------------------------------------------------------------
* Data Geekery grants the Customer the non-exclusive, timely limited and
* non-transferable license to install and use the Software under the terms of
* the jOOQ License and Maintenance Agreement.
*
* This library is distributed with a LIMITED WARRANTY. See the jOOQ License
* and Maintenance Agreement for more details: http://www.jooq.org/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 org.jooq.conf.Settings;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.MappingException;
import org.jooq.impl.DefaultRecordMapper;
/**
* 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}
*
* Note: Unlike usual implementations of {@link Iterable}, a Cursor
* can only provide one {@link Iterator}!
*
* @param The cursor's record type
* @author Lukas Eder
*/
public interface Cursor extends Iterable {
/**
* Get this cursor's row type.
*/
RecordType recordType();
/**
* Get this cursor's fields as a {@link Row}.
*/
Row fieldsRow();
/**
* Get a specific field from this Cursor.
*
* @see Row#field(Field)
*/
Field field(Field field);
/**
* Get a specific field from this Cursor.
*
* @see Row#field(String)
*/
Field> field(String name);
/**
* Get a specific field from this Cursor.
*
* @see Row#field(int)
*/
Field> field(int index);
/**
* Get all fields from this Cursor.
*
* @see Row#fields()
*/
Field>[] fields();
/**
* 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
*/
Result fetch() 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
*/
Result fetch(int number) throws DataAccessException;
/**
* 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
*/
R fetchOne() 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
*/
> H fetchOneInto(H handler) 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
*/
> H fetchInto(H handler) throws DataAccessException;
/**
* 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
*/
E fetchOne(RecordMapper super R, E> mapper) 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
*/
List fetch(RecordMapper super R, E> mapper) 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
*/
E fetchOneInto(Class extends E> type) throws DataAccessException, MappingException;
/**
* 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
*/
List fetchInto(Class extends E> type) throws DataAccessException, MappingException;
/**
* 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
*/
Z fetchOneInto(Table table) 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
*/
Result fetchInto(Table table) throws DataAccessException, MappingException;
/**
* 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
*/
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.
*/
ResultSet resultSet();
}