/*
* 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.
*
* 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: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
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.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.POSTGRES;
// ...
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.Tools.blocking;
import static org.jooq.impl.Tools.consumeResultSets;
import static org.jooq.impl.Tools.executeStatementAndGetFirstResultSet;
import static org.jooq.impl.Tools.DataKey.DATA_LOCK_ROWS_FOR_UPDATE;
import java.lang.reflect.Array;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.stream.Stream;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.Cursor;
import org.jooq.DSLContext;
import org.jooq.ExecuteContext;
import org.jooq.ExecuteListener;
import org.jooq.Field;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.RecordHandler;
import org.jooq.RecordMapper;
import org.jooq.Result;
import org.jooq.ResultQuery;
import org.jooq.Results;
import org.jooq.Table;
import org.jooq.conf.SettingsTools;
import org.jooq.tools.Convert;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.jdbc.MockResultSet;
/**
* A query that returns a {@link Result}
*
* @author Lukas Eder
*/
abstract class AbstractResultQuery<R extends Record> extends AbstractQuery implements ResultQuery<R> {
/**
* Generated UID
*/
private static final long serialVersionUID = -5588344253566055707L;
private static final JooqLogger log = JooqLogger.getLogger(AbstractResultQuery.class);
private int maxRows;
private int fetchSize;
private int resultSetConcurrency;
private int resultSetType;
private int resultSetHoldability;
private transient boolean lazy;
private transient boolean many;
private transient Cursor<R> cursor;
private Result<R> result;
private ResultsImpl results;
// Some temp variables for String interning
private final Intern intern = new Intern();
AbstractResultQuery(Configuration configuration) {
super(configuration);
}
/**
* Get a list of fields provided a result set.
*/
protected abstract Field<?>[] getFields(ResultSetMetaData rs) throws SQLException;
@SuppressWarnings("unchecked")
@Override
public final ResultQuery<R> bind(String param, Object value) {
return (ResultQuery<R>) super.bind(param, value);
}
@SuppressWarnings("unchecked")
@Override
public final ResultQuery<R> bind(int index, Object value) {
return (ResultQuery<R>) super.bind(index, value);
}
@SuppressWarnings("unchecked")
@Override
public final ResultQuery<R> queryTimeout(int timeout) {
return (ResultQuery<R>) super.queryTimeout(timeout);
}
@SuppressWarnings("unchecked")
@Override
public final ResultQuery<R> keepStatement(boolean k) {
return (ResultQuery<R>) super.keepStatement(k);
}
@Override
public final ResultQuery<R> maxRows(int rows) {
this.maxRows = rows;
return this;
}
@Override
public final ResultQuery<R> fetchSize(int rows) {
this.fetchSize = rows;
return this;
}
@Override
public final ResultQuery<R> resultSetConcurrency(int concurrency) {
this.resultSetConcurrency = concurrency;
return this;
}
@Override
public final ResultQuery<R> resultSetType(int type) {
this.resultSetType = type;
return this;
}
@Override
public final ResultQuery<R> resultSetHoldability(int holdability) {
this.resultSetHoldability = holdability;
return this;
}
@Override
public final ResultQuery<R> intern(Field<?>... fields) {
intern.internFields = fields;
return this;
}
@Override
public final ResultQuery<R> intern(int... fieldIndexes) {
intern.internIndexes = fieldIndexes;
return this;
}
@Override
public final ResultQuery<R> intern(String... fieldNameStrings) {
intern.internNameStrings = fieldNameStrings;
return this;
}
@Override
public final ResultQuery<R> intern(Name... fieldNames) {
intern.internNames = fieldNames;
return this;
}
@Override
protected final void prepare(ExecuteContext ctx) throws SQLException {
// [#1846] [#2265] [#2299] Users may explicitly specify how ResultSets
// created by jOOQ behave. This will override any other default behaviour
if (resultSetConcurrency != 0 || resultSetType != 0 || resultSetHoldability != 0) {
int type = resultSetType != 0 ? resultSetType : ResultSet.TYPE_FORWARD_ONLY;
int concurrency = resultSetConcurrency != 0 ? resultSetConcurrency : ResultSet.CONCUR_READ_ONLY;
// Sybase doesn't support holdability. Avoid setting it!
if (resultSetHoldability == 0) {
ctx.statement(ctx.connection().prepareStatement(ctx.sql(), type, concurrency));
}
else {
ctx.statement(ctx.connection().prepareStatement(ctx.sql(), type, concurrency, resultSetHoldability));
}
}
// [#1296] These dialects do not implement FOR UPDATE. But the same
// effect can be achieved using ResultSet.CONCUR_UPDATABLE
else if (isForUpdate() && asList(CUBRID).contains(ctx.configuration().dialect().family())) {
ctx.data(DATA_LOCK_ROWS_FOR_UPDATE, true);
ctx.statement(ctx.connection().prepareStatement(ctx.sql(), TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE));
}
// Regular behaviour
else {
ctx.statement(ctx.connection().prepareStatement(ctx.sql()));
}
// [#1263] [#4753] Allow for negative fetch sizes to support some non-standard
// MySQL feature, where Integer.MIN_VALUE is used
int f = SettingsTools.getFetchSize(fetchSize, ctx.settings());
if (f != 0) {
if (log.isDebugEnabled())
log.debug("Setting fetch size", f);
ctx.statement().setFetchSize(f);
}
// [#1854] [#4753] Set the max number of rows for this result query
int m = SettingsTools.getMaxRows(maxRows, ctx.settings());
if (m != 0) {
ctx.statement().setMaxRows(m);
}
}
@Override
protected final int execute(ExecuteContext ctx, ExecuteListener listener) throws SQLException {
listener.executeStart(ctx);
// [#4511] [#4753] PostgreSQL doesn't like fetchSize with autoCommit == true
int f = SettingsTools.getFetchSize(fetchSize, ctx.settings());
if (ctx.family() == POSTGRES && f != 0 && ctx.connection().getAutoCommit())
log.info("Fetch Size", "A fetch size of " + f + " was set on a auto-commit PostgreSQL connection, which is not recommended. See http://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor");
executeStatementAndGetFirstResultSet(ctx);
listener.executeEnd(ctx);
// Fetch a single result set
if (!many) {
// [#5617] This may happen when using plain SQL API or a MockConnection and expecting a result set where
// there is none. The cursor / result is patched into the ctx only for single result sets, where
// access to the cursor / result is possible.
// [#5818] It may also happen in case we're fetching from a batch and the first result is an update count,
// not a result set.
if (ctx.resultSet() == null) {
DSLContext dsl = DSL.using(ctx.configuration());
Field<Integer> c = field(name("UPDATE_COUNT"), int.class);
Result<Record1<Integer>> r = dsl.newResult(c);
r.add(dsl.newRecord(c).values(ctx.rows()));
ctx.resultSet(new MockResultSet(r));
}
Field<?>[] fields = getFields(ctx.resultSet().getMetaData());
cursor = new CursorImpl<R>(ctx, listener, fields, intern.internIndexes(fields), keepStatement(), keepResultSet(), getRecordType(), SettingsTools.getMaxRows(maxRows, ctx.settings()));
if (!lazy) {
result = cursor.fetch();
cursor = null;
}
}
// Fetch several result sets
else {
results = new ResultsImpl(ctx.configuration());
consumeResultSets(ctx, listener, results, intern);
}
return result != null ? result.size() : 0;
}
@Override
protected final boolean keepResultSet() {
return lazy;
}
/**
* Subclasses should indicate whether they want an updatable {@link ResultSet}
*/
abstract boolean isForUpdate();
@Override
public final Result<R> fetch() {
execute();
return result;
}
@Override
public final ResultSet fetchResultSet() {
return fetchLazy().resultSet();
}
@Override
public final Iterator<R> iterator() {
return fetch().iterator();
}
@Override
public final CompletionStage<Result<R>> fetchAsync() {
return fetchAsync(Tools.configuration(this).executorProvider().provide());
}
@Override
public final CompletionStage<Result<R>> fetchAsync(Executor executor) {
return ExecutorProviderCompletionStage.of(CompletableFuture.supplyAsync(blocking(this::fetch), executor), () -> executor);
}
@Override
public final Stream<R> fetchStream() {
return fetchLazy().stream();
}
@Override
public final <E> Stream<E> fetchStreamInto(Class<? extends E> type) {
return fetchStream().map(r -> r.into(type));
}
@Override
public final <Z extends Record> Stream<Z> fetchStreamInto(Table<Z> table) {
return fetchStream().map(r -> r.into(table));
}
@Override
public final Stream<R> stream() {
return fetchLazy().stream();
}
@Override
public final Cursor<R> fetchLazy() {
return fetchLazy(fetchSize);
}
@Override
@Deprecated
public final Cursor<R> fetchLazy(int size) {
final int previousFetchSize = fetchSize;
// [#3515] TODO: Avoid modifying a Query's per-execution state
lazy = true;
fetchSize = size;
try {
execute();
}
finally {
lazy = false;
fetchSize = previousFetchSize;
}
return cursor;
}
@Override
public final Results fetchMany() {
// [#3515] TODO: Avoid modifying a Query's per-execution state
many = true;
try {
execute();
}
finally {
many = false;
}
return results;
}
@Override
public final <T> List<T> fetch(Field<T> field) {
return fetch().getValues(field);
}
@Override
public final <T> List<T> fetch(Field<?> field, Class<? extends T> type) {
return fetch().getValues(field, type);
}
@Override
public final <T, U> List<U> fetch(Field<T> field, Converter<? super T, ? extends U> converter) {
return fetch().getValues(field, converter);
}
@Override
public final List<?> fetch(int fieldIndex) {
return fetch().getValues(fieldIndex);
}
@Override
public final <T> List<T> fetch(int fieldIndex, Class<? extends T> type) {
return fetch().getValues(fieldIndex, type);
}
@Override
public final <U> List<U> fetch(int fieldIndex, Converter<?, ? extends U> converter) {
return fetch().getValues(fieldIndex, converter);
}
@Override
public final List<?> fetch(String fieldName) {
return fetch().getValues(fieldName);
}
@Override
public final <T> List<T> fetch(String fieldName, Class<? extends T> type) {
return fetch().getValues(fieldName, type);
}
@Override
public final <U> List<U> fetch(String fieldName, Converter<?, ? extends U> converter) {
return fetch().getValues(fieldName, converter);
}
@Override
public final List<?> fetch(Name fieldName) {
return fetch().getValues(fieldName);
}
@Override
public final <T> List<T> fetch(Name fieldName, Class<? extends T> type) {
return fetch().getValues(fieldName, type);
}
@Override
public final <U> List<U> fetch(Name fieldName, Converter<?, ? extends U> converter) {
return fetch().getValues(fieldName, converter);
}
@Override
public final <T> T fetchOne(Field<T> field) {
R record = fetchOne();
return record == null ? null : record.get(field);
}
@Override
public final <T> T fetchOne(Field<?> field, Class<? extends T> type) {
return Convert.convert(fetchOne(field), type);
}
@Override
public final <T, U> U fetchOne(Field<T> field, Converter<? super T, ? extends U> converter) {
return Convert.convert(fetchOne(field), converter);
}
@Override
public final Object fetchOne(int fieldIndex) {
R record = fetchOne();
return record == null ? null : record.get(fieldIndex);
}
@Override
public final <T> T fetchOne(int fieldIndex, Class<? extends T> type) {
return Convert.convert(fetchOne(fieldIndex), type);
}
@Override
public final <U> U fetchOne(int fieldIndex, Converter<?, ? extends U> converter) {
return Convert.convert(fetchOne(fieldIndex), converter);
}
@Override
public final Object fetchOne(String fieldName) {
R record = fetchOne();
return record == null ? null : record.get(fieldName);
}
@Override
public final <T> T fetchOne(String fieldName, Class<? extends T> type) {
return Convert.convert(fetchOne(fieldName), type);
}
@Override
public final <U> U fetchOne(String fieldName, Converter<?, ? extends U> converter) {
return Convert.convert(fetchOne(fieldName), converter);
}
@Override
public final Object fetchOne(Name fieldName) {
R record = fetchOne();
return record == null ? null : record.get(fieldName);
}
@Override
public final <T> T fetchOne(Name fieldName, Class<? extends T> type) {
return Convert.convert(fetchOne(fieldName), type);
}
@Override
public final <U> U fetchOne(Name fieldName, Converter<?, ? extends U> converter) {
return Convert.convert(fetchOne(fieldName), converter);
}
@Override
public final R fetchOne() {
return Tools.fetchOne(fetchLazy());
}
@Override
public final <E> E fetchOne(RecordMapper<? super R, E> mapper) {
R record = fetchOne();
return record == null ? null : mapper.map(record);
}
@Override
public final Map<String, Object> fetchOneMap() {
R record = fetchOne();
return record == null ? null : record.intoMap();
}
@Override
public final Object[] fetchOneArray() {
R record = fetchOne();
return record == null ? null : record.intoArray();
}
@Override
public final <E> E fetchOneInto(Class<? extends E> type) {
R record = fetchOne();
return record == null ? null : record.into(type);
}
@Override
public final <Z extends Record> Z fetchOneInto(Table<Z> table) {
R record = fetchOne();
return record == null ? null : record.into(table);
}
@Override
public final <T> Optional<T> fetchOptional(Field<T> field) {
return Optional.ofNullable(fetchOne(field));
}
@Override
public final <T> Optional<T> fetchOptional(Field<?> field, Class<? extends T> type) {
return Optional.ofNullable(fetchOne(field, type));
}
@Override
public final <T, U> Optional<U> fetchOptional(Field<T> field, Converter<? super T, ? extends U> converter) {
return Optional.ofNullable(fetchOne(field, converter));
}
@Override
public final Optional<?> fetchOptional(int fieldIndex) {
return Optional.ofNullable(fetchOne(fieldIndex));
}
@Override
public final <T> Optional<T> fetchOptional(int fieldIndex, Class<? extends T> type) {
return Optional.ofNullable(fetchOne(fieldIndex, type));
}
@Override
public final <U> Optional<U> fetchOptional(int fieldIndex, Converter<?, ? extends U> converter) {
return Optional.ofNullable(fetchOne(fieldIndex, converter));
}
@Override
public final Optional<?> fetchOptional(String fieldName) {
return Optional.ofNullable(fetchOne(fieldName));
}
@Override
public final <T> Optional<T> fetchOptional(String fieldName, Class<? extends T> type) {
return Optional.ofNullable(fetchOne(fieldName, type));
}
@Override
public final <U> Optional<U> fetchOptional(String fieldName, Converter<?, ? extends U> converter) {
return Optional.ofNullable(fetchOne(fieldName, converter));
}
@Override
public final Optional<?> fetchOptional(Name fieldName) {
return Optional.ofNullable(fetchOne(fieldName));
}
@Override
public final <T> Optional<T> fetchOptional(Name fieldName, Class<? extends T> type) {
return Optional.ofNullable(fetchOne(fieldName, type));
}
@Override
public final <U> Optional<U> fetchOptional(Name fieldName, Converter<?, ? extends U> converter) {
return Optional.ofNullable(fetchOne(fieldName, converter));
}
@Override
public final Optional<R> fetchOptional() {
return Optional.ofNullable(fetchOne());
}
@Override
public final <E> Optional<E> fetchOptional(RecordMapper<? super R, E> mapper) {
return Optional.ofNullable(fetchOne(mapper));
}
@Override
public final Optional<Map<String, Object>> fetchOptionalMap() {
return Optional.ofNullable(fetchOneMap());
}
@Override
public final Optional<Object[]> fetchOptionalArray() {
return Optional.ofNullable(fetchOneArray());
}
@Override
public final <E> Optional<E> fetchOptionalInto(Class<? extends E> type) {
return Optional.ofNullable(fetchOneInto(type));
}
@Override
public final <Z extends Record> Optional<Z> fetchOptionalInto(Table<Z> table) {
return Optional.ofNullable(fetchOneInto(table));
}
@Override
public final <T> T fetchAny(Field<T> field) {
R record = fetchAny();
return record == null ? null : record.get(field);
}
@Override
public final <T> T fetchAny(Field<?> field, Class<? extends T> type) {
return Convert.convert(fetchAny(field), type);
}
@Override
public final <T, U> U fetchAny(Field<T> field, Converter<? super T, ? extends U> converter) {
return Convert.convert(fetchAny(field), converter);
}
@Override
public final Object fetchAny(int fieldIndex) {
R record = fetchAny();
return record == null ? null : record.get(fieldIndex);
}
@Override
public final <T> T fetchAny(int fieldIndex, Class<? extends T> type) {
return Convert.convert(fetchAny(fieldIndex), type);
}
@Override
public final <U> U fetchAny(int fieldIndex, Converter<?, ? extends U> converter) {
return Convert.convert(fetchAny(fieldIndex), converter);
}
@Override
public final Object fetchAny(String fieldName) {
R record = fetchAny();
return record == null ? null : record.get(fieldName);
}
@Override
public final <T> T fetchAny(String fieldName, Class<? extends T> type) {
return Convert.convert(fetchAny(fieldName), type);
}
@Override
public final <U> U fetchAny(String fieldName, Converter<?, ? extends U> converter) {
return Convert.convert(fetchAny(fieldName), converter);
}
@Override
public final Object fetchAny(Name fieldName) {
R record = fetchAny();
return record == null ? null : record.get(fieldName);
}
@Override
public final <T> T fetchAny(Name fieldName, Class<? extends T> type) {
return Convert.convert(fetchAny(fieldName), type);
}
@Override
public final <U> U fetchAny(Name fieldName, Converter<?, ? extends U> converter) {
return Convert.convert(fetchAny(fieldName), converter);
}
@Override
public final R fetchAny() {
Cursor<R> c = fetchLazy();
try {
return c.fetchOne();
}
finally {
c.close();
}
}
@Override
public final <E> E fetchAny(RecordMapper<? super R, E> mapper) {
R record = fetchAny();
return record == null ? null : mapper.map(record);
}
@Override
public final Map<String, Object> fetchAnyMap() {
R record = fetchAny();
return record == null ? null : record.intoMap();
}
@Override
public final Object[] fetchAnyArray() {
R record = fetchAny();
return record == null ? null : record.intoArray();
}
@Override
public final <E> E fetchAnyInto(Class<? extends E> type) {
R record = fetchAny();
return record == null ? null : record.into(type);
}
@Override
public final <Z extends Record> Z fetchAnyInto(Table<Z> table) {
R record = fetchAny();
return record == null ? null : record.into(table);
}
@Override
public final <K> Map<K, R> fetchMap(Field<K> key) {
return fetch().intoMap(key);
}
@Override
public final Map<?, R> fetchMap(int keyFieldIndex) {
return fetch().intoMap(keyFieldIndex);
}
@Override
public final Map<?, R> fetchMap(String keyFieldName) {
return fetch().intoMap(keyFieldName);
}
@Override
public final Map<?, R> fetchMap(Name keyFieldName) {
return fetch().intoMap(keyFieldName);
}
@Override
public final <K, V> Map<K, V> fetchMap(Field<K> key, Field<V> value) {
return fetch().intoMap(key, value);
}
@Override
public final Map<?, ?> fetchMap(int keyFieldIndex, int valueFieldIndex) {
return fetch().intoMap(keyFieldIndex, valueFieldIndex);
}
@Override
public final Map<?, ?> fetchMap(String keyFieldName, String valueFieldName) {
return fetch().intoMap(keyFieldName, valueFieldName);
}
@Override
public final Map<?, ?> fetchMap(Name keyFieldName, Name valueFieldName) {
return fetch().intoMap(keyFieldName, valueFieldName);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
return fetch().intoMap(key, type);
}
@Override
public final <E> Map<?, E> fetchMap(int keyFieldIndex, Class<? extends E> type) {
return fetch().intoMap(keyFieldIndex, type);
}
@Override
public final <E> Map<?, E> fetchMap(String keyFieldName, Class<? extends E> type) {
return fetch().intoMap(keyFieldName, type);
}
@Override
public final <E> Map<?, E> fetchMap(Name keyFieldName, Class<? extends E> type) {
return fetch().intoMap(keyFieldName, type);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(key, mapper);
}
@Override
public final <E> Map<?, E> fetchMap(int keyFieldIndex, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(keyFieldIndex, mapper);
}
@Override
public final <E> Map<?, E> fetchMap(String keyFieldName, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(keyFieldName, mapper);
}
@Override
public final <E> Map<?, E> fetchMap(Name keyFieldName, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(keyFieldName, mapper);
}
@Override
public final Map<Record, R> fetchMap(Field<?>[] keys) {
return fetch().intoMap(keys);
}
@Override
public final Map<Record, R> fetchMap(int[] keyFieldIndexes) {
return fetch().intoMap(keyFieldIndexes);
}
@Override
public final Map<Record, R> fetchMap(String[] keyFieldNames) {
return fetch().intoMap(keyFieldNames);
}
@Override
public final Map<Record, R> fetchMap(Name[] keyFieldNames) {
return fetch().intoMap(keyFieldNames);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) {
return fetch().intoMap(keys, type);
}
@Override
public final <E> Map<List<?>, E> fetchMap(int[] keyFieldIndexes, Class<? extends E> type) {
return fetch().intoMap(keyFieldIndexes, type);
}
@Override
public final <E> Map<List<?>, E> fetchMap(String[] keyFieldNames, Class<? extends E> type) {
return fetch().intoMap(keyFieldNames, type);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Name[] keyFieldNames, Class<? extends E> type) {
return fetch().intoMap(keyFieldNames, type);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Field<?>[] keys, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(keys, mapper);
}
@Override
public final <E> Map<List<?>, E> fetchMap(int[] keyFieldIndexes, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(keyFieldIndexes, mapper);
}
@Override
public final <E> Map<List<?>, E> fetchMap(String[] keyFieldNames, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(keyFieldNames, mapper);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Name[] keyFieldNames, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(keyFieldNames, mapper);
}
@Override
public final <K> Map<K, R> fetchMap(Class<? extends K> keyType) {
return fetch().intoMap(keyType);
}
@Override
public final <K, V> Map<K, V> fetchMap(Class<? extends K> keyType, Class<? extends V> valueType) {
return fetch().intoMap(keyType, valueType);
}
@Override
public final <K, V> Map<K, V> fetchMap(Class<? extends K> keyType, RecordMapper<? super R, V> valueMapper) {
return fetch().intoMap(keyType, valueMapper);
}
@Override
public final <K> Map<K, R> fetchMap(RecordMapper<? super R, K> keyMapper) {
return fetch().intoMap(keyMapper);
}
@Override
public final <K, V> Map<K, V> fetchMap(RecordMapper<? super R, K> keyMapper, Class<V> valueType) {
return fetch().intoMap(keyMapper, valueType);
}
@Override
public final <K, V> Map<K, V> fetchMap(RecordMapper<? super R, K> keyMapper, RecordMapper<? super R, V> valueMapper) {
return fetch().intoMap(keyMapper, valueMapper);
}
@Override
public final <S extends Record> Map<S, R> fetchMap(Table<S> table) {
return fetch().intoMap(table);
}
@Override
public final <E, S extends Record> Map<S, E> fetchMap(Table<S> table, Class<? extends E> type) {
return fetch().intoMap(table, type);
}
@Override
public final <E, S extends Record> Map<S, E> fetchMap(Table<S> table, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(table, mapper);
}
@Override
public final List<Map<String, Object>> fetchMaps() {
return fetch().intoMaps();
}
@Override
public final <K> Map<K, Result<R>> fetchGroups(Field<K> key) {
return fetch().intoGroups(key);
}
@Override
public final Map<?, Result<R>> fetchGroups(int keyFieldIndex) {
return fetch().intoGroups(keyFieldIndex);
}
@Override
public final Map<?, Result<R>> fetchGroups(String keyFieldName) {
return fetch().intoGroups(keyFieldName);
}
@Override
public final Map<?, Result<R>> fetchGroups(Name keyFieldName) {
return fetch().intoGroups(keyFieldName);
}
@Override
public final <K, V> Map<K, List<V>> fetchGroups(Field<K> key, Field<V> value) {
return fetch().intoGroups(key, value);
}
@Override
public final Map<?, List<?>> fetchGroups(int keyFieldIndex, int valueFieldIndex) {
return fetch().intoGroups(keyFieldIndex, valueFieldIndex);
}
@Override
public final Map<?, List<?>> fetchGroups(String keyFieldName, String valueFieldName) {
return fetch().intoGroups(keyFieldName, valueFieldName);
}
@Override
public final Map<?, List<?>> fetchGroups(Name keyFieldName, Name valueFieldName) {
return fetch().intoGroups(keyFieldName, valueFieldName);
}
@Override
public final <K, E> Map<K, List<E>> fetchGroups(Field<K> key, Class<? extends E> type) {
return fetch().intoGroups(key, type);
}
@Override
public final <E> Map<?, List<E>> fetchGroups(int keyFieldIndex, Class<? extends E> type) {
return fetch().intoGroups(keyFieldIndex, type);
}
@Override
public final <E> Map<?, List<E>> fetchGroups(String keyFieldName, Class<? extends E> type) {
return fetch().intoGroups(keyFieldName, type);
}
@Override
public final <E> Map<?, List<E>> fetchGroups(Name keyFieldName, Class<? extends E> type) {
return fetch().intoGroups(keyFieldName, type);
}
@Override
public final <K, E> Map<K, List<E>> fetchGroups(Field<K> key, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(key, mapper);
}
@Override
public final <E> Map<?, List<E>> fetchGroups(int keyFieldIndex, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(keyFieldIndex, mapper);
}
@Override
public final <E> Map<?, List<E>> fetchGroups(String keyFieldName, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(keyFieldName, mapper);
}
@Override
public final <E> Map<?, List<E>> fetchGroups(Name keyFieldName, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(keyFieldName, mapper);
}
@Override
public final Map<Record, Result<R>> fetchGroups(Field<?>[] keys) {
return fetch().intoGroups(keys);
}
@Override
public final Map<Record, Result<R>> fetchGroups(int[] keyFieldIndexes) {
return fetch().intoGroups(keyFieldIndexes);
}
@Override
public final Map<Record, Result<R>> fetchGroups(String[] keyFieldNames) {
return fetch().intoGroups(keyFieldNames);
}
@Override
public final Map<Record, Result<R>> fetchGroups(Name[] keyFieldNames) {
return fetch().intoGroups(keyFieldNames);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(Field<?>[] keys, Class<? extends E> type) {
return fetch().intoGroups(keys, type);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(int[] keyFieldIndexes, Class<? extends E> type) {
return fetch().intoGroups(keyFieldIndexes, type);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(String[] keyFieldNames, Class<? extends E> type) {
return fetch().intoGroups(keyFieldNames, type);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(Name[] keyFieldNames, Class<? extends E> type) {
return fetch().intoGroups(keyFieldNames, type);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(int[] keyFieldIndexes, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(keyFieldIndexes, mapper);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(String[] keyFieldNames, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(keyFieldNames, mapper);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(Name[] keyFieldNames, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(keyFieldNames, mapper);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(Field<?>[] keys, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(keys, mapper);
}
@Override
public final <K> Map<K, Result<R>> fetchGroups(Class<? extends K> keyType) {
return fetch().intoGroups(keyType);
}
@Override
public final <K, V> Map<K, List<V>> fetchGroups(Class<? extends K> keyType, Class<? extends V> valueType) {
return fetch().intoGroups(keyType, valueType);
}
@Override
public final <K, V> Map<K, List<V>> fetchGroups(Class<? extends K> keyType, RecordMapper<? super R, V> valueMapper) {
return fetch().intoGroups(keyType, valueMapper);
}
@Override
public final <K> Map<K, Result<R>> fetchGroups(RecordMapper<? super R, K> keyMapper) {
return fetch().intoGroups(keyMapper);
}
@Override
public final <K, V> Map<K, List<V>> fetchGroups(RecordMapper<? super R, K> keyMapper, Class<V> valueType) {
return fetch().intoGroups(keyMapper, valueType);
}
@Override
public final <K, V> Map<K, List<V>> fetchGroups(RecordMapper<? super R, K> keyMapper, RecordMapper<? super R, V> valueMapper) {
return fetch().intoGroups(keyMapper, valueMapper);
}
@Override
public final <S extends Record> Map<S, Result<R>> fetchGroups(Table<S> table) {
return fetch().intoGroups(table);
}
@Override
public final <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, Class<? extends E> type) {
return fetch().intoGroups(table, type);
}
@Override
public final <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(table, mapper);
}
@Override
public final Object[][] fetchArrays() {
return fetch().intoArrays();
}
@SuppressWarnings("unchecked")
@Override
public final R[] fetchArray() {
Result<R> r = fetch();
return r.toArray((R[]) Array.newInstance(getRecordType(), r.size()));
}
@Override
public final Object[] fetchArray(int fieldIndex) {
return fetch().intoArray(fieldIndex);
}
@Override
public final <T> T[] fetchArray(int fieldIndex, Class<? extends T> type) {
return fetch().intoArray(fieldIndex, type);
}
@Override
public final <U> U[] fetchArray(int fieldIndex, Converter<?, ? extends U> converter) {
return fetch().intoArray(fieldIndex, converter);
}
@Override
public final Object[] fetchArray(String fieldName) {
return fetch().intoArray(fieldName);
}
@Override
public final <T> T[] fetchArray(String fieldName, Class<? extends T> type) {
return fetch().intoArray(fieldName, type);
}
@Override
public final <U> U[] fetchArray(String fieldName, Converter<?, ? extends U> converter) {
return fetch().intoArray(fieldName, converter);
}
@Override
public final Object[] fetchArray(Name fieldName) {
return fetch().intoArray(fieldName);
}
@Override
public final <T> T[] fetchArray(Name fieldName, Class<? extends T> type) {
return fetch().intoArray(fieldName, type);
}
@Override
public final <U> U[] fetchArray(Name fieldName, Converter<?, ? extends U> converter) {
return fetch().intoArray(fieldName, converter);
}
@Override
public final <T> T[] fetchArray(Field<T> field) {
return fetch().intoArray(field);
}
@Override
public final <T> T[] fetchArray(Field<?> field, Class<? extends T> type) {
return fetch().intoArray(field, type);
}
@Override
public final <T, U> U[] fetchArray(Field<T> field, Converter<? super T, ? extends U> converter) {
return fetch().intoArray(field, converter);
}
@Override
public final Set<?> fetchSet(int fieldIndex) {
return fetch().intoSet(fieldIndex);
}
@Override
public final <T> Set<T> fetchSet(int fieldIndex, Class<? extends T> type) {
return fetch().intoSet(fieldIndex, type);
}
@Override
public final <U> Set<U> fetchSet(int fieldIndex, Converter<?, ? extends U> converter) {
return fetch().intoSet(fieldIndex, converter);
}
@Override
public final Set<?> fetchSet(String fieldName) {
return fetch().intoSet(fieldName);
}
@Override
public final <T> Set<T> fetchSet(String fieldName, Class<? extends T> type) {
return fetch().intoSet(fieldName, type);
}
@Override
public final <U> Set<U> fetchSet(String fieldName, Converter<?, ? extends U> converter) {
return fetch().intoSet(fieldName, converter);
}
@Override
public final Set<?> fetchSet(Name fieldName) {
return fetch().intoSet(fieldName);
}
@Override
public final <T> Set<T> fetchSet(Name fieldName, Class<? extends T> type) {
return fetch().intoSet(fieldName, type);
}
@Override
public final <U> Set<U> fetchSet(Name fieldName, Converter<?, ? extends U> converter) {
return fetch().intoSet(fieldName, converter);
}
@Override
public final <T> Set<T> fetchSet(Field<T> field) {
return fetch().intoSet(field);
}
@Override
public final <T> Set<T> fetchSet(Field<?> field, Class<? extends T> type) {
return fetch().intoSet(field, type);
}
@Override
public final <T, U> Set<U> fetchSet(Field<T> field, Converter<? super T, ? extends U> converter) {
return fetch().intoSet(field, converter);
}
/**
* Subclasses may override this method
* <p>
* {@inheritDoc}
*/
@Override
public Class<? extends R> getRecordType() {
return null;
}
@Override
public final <T> List<T> fetchInto(Class<? extends T> type) {
return fetch().into(type);
}
@Override
public final <Z extends Record> Result<Z> fetchInto(Table<Z> table) {
return fetch().into(table);
}
@Override
public final <H extends RecordHandler<? super R>> H fetchInto(H handler) {
return fetch().into(handler);
}
@Override
public final <E> List<E> fetch(RecordMapper<? super R, E> mapper) {
return fetch().map(mapper);
}
@Override
@Deprecated
public final org.jooq.FutureResult<R> fetchLater() {
ExecutorService executor = newSingleThreadExecutor();
Future<Result<R>> future = executor.submit(new ResultQueryCallable());
return new FutureResultImpl<R>(future, executor);
}
@Override
@Deprecated
public final org.jooq.FutureResult<R> fetchLater(ExecutorService executor) {
Future<Result<R>> future = executor.submit(new ResultQueryCallable());
return new FutureResultImpl<R>(future);
}
@Override
public final Result<R> getResult() {
return result;
}
/**
* A wrapper for the {@link ResultQuery#fetch()} method
*/
private final class ResultQueryCallable implements Callable<Result<R>> {
@Override
public final Result<R> call() throws Exception {
return fetch();
}
}
}