[jOOQ/jOOQ#9288] Offer Result.intoMap(), intoGroups(), intoSet()
functionality as Collector
This commit is contained in:
parent
39f57b928d
commit
b50ec7169f
82
jOOQ/src/main/java/org/jooq/Mappable.java
Normal file
82
jOOQ/src/main/java/org/jooq/Mappable.java
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.jooq.impl.DefaultRecordMapper;
|
||||
|
||||
/**
|
||||
* A type producing records that can be mapped.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface Mappable<R extends Record> {
|
||||
|
||||
/**
|
||||
* Create a record mapper that extracts a value by field index.
|
||||
*/
|
||||
RecordMapper<R, ?> mapper(int fieldIndex);
|
||||
|
||||
/**
|
||||
* Create a record mapper that extracts a value by field name.
|
||||
*/
|
||||
RecordMapper<R, ?> mapper(String fieldName);
|
||||
|
||||
/**
|
||||
* Create a record mapper that extracts a value by field name.
|
||||
*/
|
||||
RecordMapper<R, ?> mapper(Name fieldName);
|
||||
|
||||
/**
|
||||
* Create a record mapper that extracts a value by field reference.
|
||||
*/
|
||||
<T> RecordMapper<R, T> mapper(Field<T> field);
|
||||
|
||||
/**
|
||||
* Create a record mapper that maps records to a new
|
||||
* {@link RecordQualifier#getRecordType()}.
|
||||
*/
|
||||
<S extends Record> RecordMapper<R, S> mapper(Table<S> table);
|
||||
|
||||
/**
|
||||
* Create a record mapper that maps records to a {@link Class} using the
|
||||
* configured {@link Configuration#recordMapperProvider()} (the
|
||||
* {@link DefaultRecordMapper}, by default).
|
||||
*/
|
||||
<E> RecordMapper<R, E> mapper(Configuration configuration, Class<? extends E> type);
|
||||
|
||||
}
|
||||
@ -37,6 +37,8 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import org.jooq.impl.DefaultRecordMapper;
|
||||
|
||||
/**
|
||||
* A record type for {@link Table}, {@link Cursor}, {@link Result} and other
|
||||
* objects.
|
||||
@ -51,7 +53,7 @@ package org.jooq;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface RecordType<R extends Record> extends Fields {
|
||||
public interface RecordType<R extends Record> extends Fields, Mappable<R> {
|
||||
|
||||
/**
|
||||
* Get the degree of this record type.
|
||||
|
||||
@ -37,6 +37,19 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jooq.exception.InvalidResultException;
|
||||
import org.jooq.impl.Internal;
|
||||
|
||||
/**
|
||||
* Common utilities related to {@link Record} types and constructing
|
||||
* {@link RecordMapper}.
|
||||
@ -58,6 +71,328 @@ package org.jooq;
|
||||
*/
|
||||
public final class Records {
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record1} resulting from a
|
||||
* single column {@link ResultQuery} into a {@link List} of that column's
|
||||
* type.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* List<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toList());
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following, but allows for omitting repeating the
|
||||
* <code>BOOK.TITLE</code> column:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* List<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetch(BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <E, R extends Record1<E>> Collector<R, ?, List<E>> toList() {
|
||||
return Collectors.mapping(Record1::value1, Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record} resulting from a
|
||||
* {@link ResultQuery} into a {@link List} of a mapped type.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* List<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toList(r -> r.get(BOOK.TITLE)));
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* List<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetch(BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <E, R extends Record> Collector<R, ?, List<E>> toList(Function<? super R, ? extends E> function) {
|
||||
return Collectors.mapping(function, Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record1} resulting from a
|
||||
* single column {@link ResultQuery} into a {@link Set} of that column's
|
||||
* type.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Set<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toSet());
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following, but allows for omitting repeating the
|
||||
* <code>BOOK.TITLE</code> column:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* List<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchSet(BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <E, R extends Record1<E>> Collector<R, ?, Set<E>> toSet() {
|
||||
return toSet(Record1::value1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record} resulting from a
|
||||
* {@link ResultQuery} into a {@link Set} of a mapped type.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Set<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toSet(r -> r.get(BOOK.TITLE)));
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* List<String> titles =
|
||||
* ctx.select(BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchSet(BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <E, R extends Record> Collector<R, ?, Set<E>> toSet(Function<? super R, ? extends E> function) {
|
||||
return Collectors.mapping(function, Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record2} resulting from a
|
||||
* 2-column {@link ResultQuery} into a {@link Map} using the first column as
|
||||
* key and the second column as value.
|
||||
* <p>
|
||||
* Collection throws {@link InvalidResultException} if a key is encountered
|
||||
* more than once.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, String> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toMap());
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following, but allows for omitting repeating the
|
||||
* <code>BOOK.ID</code> and <code>BOOK.TITLE</code> columns:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, String> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchMap(BOOK.ID, BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <K, V, R extends Record2<K, V>> Collector<R, ?, Map<K, V>> toMap() {
|
||||
return toMap(Record2::value1, Record2::value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record} resulting from a
|
||||
* {@link ResultQuery} into a {@link Map} using the result of the argument
|
||||
* {@link RecordMapper} as key and the record itself as value.
|
||||
* <p>
|
||||
* Collection throws {@link InvalidResultException} if a key is encountered
|
||||
* more than once.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, Record2<Integer, String>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toMap(r -> r.get(BOOK.ID)));
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, Record2<Integer, String>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchMap(BOOK.ID);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <K, R extends Record> Collector<R, ?, Map<K, R>> toMap(Function<? super R, ? extends K> keyMapper) {
|
||||
return toMap(keyMapper, r -> r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record} resulting from a
|
||||
* {@link ResultQuery} into a {@link Map} using the result of the argument
|
||||
* {@link RecordMapper} as key and the result of another argument
|
||||
* {@link RecordMapper} as value.
|
||||
* <p>
|
||||
* Collection throws {@link InvalidResultException} if a key is encountered
|
||||
* more than once.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, String> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toMap(r -> r.get(BOOK.ID), r -> r.get(BOOK.TITLE)));
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, String> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchMap(BOOK.ID, BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <K, V, R extends Record> Collector<R, ?, Map<K, V>> toMap(
|
||||
Function<? super R, ? extends K> keyMapper,
|
||||
Function<? super R, ? extends V> valueMapper
|
||||
) {
|
||||
return Collectors.toMap(
|
||||
keyMapper,
|
||||
valueMapper,
|
||||
(k1, k2) -> {
|
||||
throw new InvalidResultException("Key " + k1 + " is not unique in Result");
|
||||
},
|
||||
LinkedHashMap::new
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record2} resulting from a
|
||||
* 2-column {@link ResultQuery} into a {@link Map} using the first column as
|
||||
* key collecting values of the second column into a list of values.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, List<String>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toGroups());
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following, but allows for omitting repeating the
|
||||
* <code>BOOK.ID</code> and <code>BOOK.TITLE</code> columns:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, List<String>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchGroups(BOOK.ID, BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <K, V, R extends Record2<K, V>> Collector<R, ?, Map<K, List<V>>> toGroups() {
|
||||
return toGroups(Record2::value1, Record2::value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record} resulting from a
|
||||
* {@link ResultQuery} into a {@link Map} using the result of the argument
|
||||
* {@link RecordMapper} as key collecting the records themselves into a list
|
||||
* of values.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, List<Record2<Integer, String>>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toGroups(r -> r.get(BOOK.ID)));
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, List<Record2<Integer, String>>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchGroups(BOOK.ID);
|
||||
* </pre></code>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final <K, R extends Record> Collector<R, ?, Map<K, Result<R>>> toGroups(Function<? super R, ? extends K> keyMapper) {
|
||||
return Collectors.groupingBy(
|
||||
keyMapper,
|
||||
LinkedHashMap::new,
|
||||
Collector.<R, Result<R>[], Result<R>>of(
|
||||
() -> new Result[1],
|
||||
(x, r) -> {
|
||||
if (x[0] == null)
|
||||
x[0] = Internal.result(r);
|
||||
|
||||
x[0].add(r);
|
||||
},
|
||||
(r1, r2) -> {
|
||||
r1[0].addAll(r2[0]);
|
||||
return r1;
|
||||
},
|
||||
r -> r[0]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collector that can collect {@link Record} resulting from a
|
||||
* {@link ResultQuery} into a {@link Map} using the result of the argument
|
||||
* {@link RecordMapper} as key collecting the result of another argument
|
||||
* {@link RecordMapper} into a list of values.
|
||||
* <p>
|
||||
* For example:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, List<String>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .collect(toGroups(r -> r.get(BOOK.ID), r -> r.get(BOOK.TITLE)));
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* This is the same as the following:
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* Map<Integer, List<String>> books =
|
||||
* ctx.select(BOOK.ID, BOOK.TITLE)
|
||||
* .from(BOOK)
|
||||
* .fetchGroups(BOOK.ID, BOOK.TITLE);
|
||||
* </pre></code>
|
||||
*/
|
||||
public static final <K, V, R extends Record> Collector<R, ?, Map<K, List<V>>> toGroups(
|
||||
Function<? super R, ? extends K> keyMapper,
|
||||
Function<? super R, ? extends V> valueMapper
|
||||
) {
|
||||
return Collectors.groupingBy(
|
||||
keyMapper,
|
||||
LinkedHashMap::new,
|
||||
Collectors.mapping(
|
||||
valueMapper,
|
||||
Collectors.toList()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -43,6 +43,8 @@ import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.exception.DataTypeException;
|
||||
@ -310,6 +312,14 @@ public interface Result<R extends Record> extends Fields, List<R>, Attachable, F
|
||||
*/
|
||||
boolean isNotEmpty();
|
||||
|
||||
/**
|
||||
* Collect all records of this result.
|
||||
* <p>
|
||||
* This is the same as calling {@link Stream#collect(Collector)} on
|
||||
* {@link #stream()}.
|
||||
*/
|
||||
<X, A> X collect(Collector<? super R, A, X> collector);
|
||||
|
||||
/**
|
||||
* Return the generated result as a list of name/value maps.
|
||||
*
|
||||
|
||||
@ -804,7 +804,7 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
|
||||
@Override
|
||||
public final <E> E into(Class<? extends E> type) {
|
||||
return (E) Tools.configuration(this).recordMapperProvider().provide((FieldsImpl) fields.fields, type).map(this);
|
||||
return (E) ((FieldsImpl) fields.fields).mapper(Tools.configuration(this), type).map(this);
|
||||
}
|
||||
|
||||
// [#10191] Java and Kotlin can produce overloads for this method despite
|
||||
|
||||
@ -111,8 +111,7 @@ public abstract class DAOImpl<R extends UpdatableRecord<R>, P, T> implements DAO
|
||||
* using Spring. It is not exposed in the public API.
|
||||
*/
|
||||
public /* non-final */ void setConfiguration(Configuration configuration) {
|
||||
this.configuration = Tools.configuration(configuration);
|
||||
this.mapper = this.configuration.recordMapperProvider().provide(table.recordType(), type);
|
||||
this.mapper = table.recordType().mapper(this.configuration = Tools.configuration(configuration), type);
|
||||
}
|
||||
|
||||
public final DSLContext ctx() {
|
||||
|
||||
@ -377,8 +377,7 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
}
|
||||
|
||||
if (Stream.class.isAssignableFrom(type)) {
|
||||
RecordMapper<R, Object[]> local = configuration.recordMapperProvider().provide(rowType, Object[].class);
|
||||
delegate = r -> (E) Stream.of(local.map(r));
|
||||
delegate = r -> (E) Stream.of(rowType.mapper(configuration, Object[].class).map(r));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -837,14 +836,14 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
nestedMappingInfo.recordDelegate = newRecord(true, recordType(nestedMappingInfo.row.size()), nestedMappingInfo.row, configuration);
|
||||
|
||||
for (java.lang.reflect.Field member : getMatchingMembers(configuration, type, prefix, true))
|
||||
nestedMappingInfo.mappers.add(configuration
|
||||
.recordMapperProvider()
|
||||
.provide((RecordType<AbstractRecord>) nestedMappingInfo.row.fields, member.getType()));
|
||||
nestedMappingInfo.mappers.add(
|
||||
nestedMappingInfo.row.fields.mapper(configuration, member.getType())
|
||||
);
|
||||
|
||||
for (Method method : getMatchingSetters(configuration, type, prefix, true))
|
||||
nestedMappingInfo.mappers.add(configuration
|
||||
.recordMapperProvider()
|
||||
.provide((RecordType<AbstractRecord>) nestedMappingInfo.row.fields, method.getParameterTypes()[0]));
|
||||
nestedMappingInfo.mappers.add(
|
||||
nestedMappingInfo.row.fields.mapper(configuration, method.getParameterTypes()[0])
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1110,9 +1109,9 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
if (nestedMappedFields[i] != null) {
|
||||
nestedMappingInfo[i].row = row0(nestedMappedFields[i].toArray(EMPTY_FIELD));
|
||||
nestedMappingInfo[i].recordDelegate = newRecord(true, recordType(nestedMappingInfo[i].row.size()), nestedMappingInfo[i].row, configuration);
|
||||
nestedMappingInfo[i].mappers.add(configuration
|
||||
.recordMapperProvider()
|
||||
.provide((RecordType<AbstractRecord>) nestedMappingInfo[i].row.fields, parameterTypes[propertyIndexes[i] != null ? propertyIndexes[i] : i]));
|
||||
nestedMappingInfo[i].mappers.add(
|
||||
nestedMappingInfo[i].row.fields.mapper(configuration, parameterTypes[propertyIndexes[i] != null ? propertyIndexes[i] : i])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
71
jOOQ/src/main/java/org/jooq/impl/DelayedRecordMapper.java
Normal file
71
jOOQ/src/main/java/org/jooq/impl/DelayedRecordMapper.java
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 java.util.function.Function;
|
||||
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.jooq.RecordType;
|
||||
|
||||
/**
|
||||
* A {@link RecordMapper} implementation offering access to a delegate record
|
||||
* mapper whose initialisation is delayed until the first record, e.g. for
|
||||
* {@link ResultQuery} implementations whose {@link RecordType} is unknown prior
|
||||
* to execution.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class DelayedRecordMapper<R extends Record, E> implements RecordMapper<R, E> {
|
||||
|
||||
final Function<RecordType<R>, RecordMapper<R, E>> init;
|
||||
RecordMapper<R, E> delegate;
|
||||
|
||||
DelayedRecordMapper(Function<RecordType<R>, RecordMapper<R, E>> init) {
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final E map(R record) {
|
||||
if (delegate == null)
|
||||
delegate = init.apply((RecordType<R>) ((AbstractRecord) record).fields.fields);
|
||||
|
||||
return delegate.map(record);
|
||||
}
|
||||
}
|
||||
@ -50,11 +50,13 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.jooq.RecordType;
|
||||
import org.jooq.Row;
|
||||
import org.jooq.SelectField;
|
||||
@ -91,6 +93,36 @@ final class FieldsImpl<R extends Record> extends AbstractQueryPart implements Re
|
||||
return fields.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RecordMapper<R, ?> mapper(int fieldIndex) {
|
||||
return r -> r.get(fieldIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RecordMapper<R, ?> mapper(String fieldName) {
|
||||
return mapper(field(fieldName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RecordMapper<R, ?> mapper(Name fieldName) {
|
||||
return mapper(field(fieldName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> RecordMapper<R, T> mapper(Field<T> field) {
|
||||
return (RecordMapper<R, T>) mapper(indexOrFail(fieldsRow(), field));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <S extends Record> RecordMapper<R, S> mapper(Table<S> table) {
|
||||
return r -> r.into(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> RecordMapper<R, E> mapper(Configuration configuration, Class<? extends E> type) {
|
||||
return configuration.recordMapperProvider().provide(this, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <T> Field<T> field(Field<T> field) {
|
||||
|
||||
@ -43,6 +43,7 @@ import static org.jooq.impl.ExpressionOperator.MULTIPLY;
|
||||
import static org.jooq.impl.ExpressionOperator.SUBTRACT;
|
||||
import static org.jooq.impl.Tools.nullSafe;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jooq.Binding;
|
||||
@ -61,6 +62,7 @@ import org.jooq.ParamMode;
|
||||
import org.jooq.Parameter;
|
||||
// ...
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Row;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Sequence;
|
||||
@ -443,6 +445,10 @@ public final class Internal {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* JDK agnostic abstraction over {@link Class#arrayType()} and
|
||||
* {@link Array#newInstance(Class, int)}.
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "unused" })
|
||||
public static final <T> Class<T[]> arrayType(Class<T> type) {
|
||||
|
||||
@ -450,6 +456,13 @@ public final class Internal {
|
||||
|
||||
|
||||
|
||||
return (Class<T[]>) java.lang.reflect.Array.newInstance(type, 0).getClass();
|
||||
return (Class<T[]>) Array.newInstance(type, 0).getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty result from a {@link Record} using its row type.
|
||||
*/
|
||||
public static final <R extends Record> Result<R> result(R record) {
|
||||
return new ResultImpl<>(Tools.configuration(record), ((AbstractRecord) record).fields);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,15 +38,17 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Records.toGroups;
|
||||
import static org.jooq.Records.toList;
|
||||
import static org.jooq.Records.toMap;
|
||||
import static org.jooq.Records.toSet;
|
||||
import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
import static org.jooq.impl.Tools.converterOrFail;
|
||||
import static org.jooq.impl.Tools.indexOrFail;
|
||||
import static org.jooq.impl.Tools.map;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@ -57,6 +59,7 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
@ -88,6 +91,7 @@ import org.jooq.Record8;
|
||||
import org.jooq.Record9;
|
||||
import org.jooq.RecordHandler;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.jooq.Records;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.TXTFormat;
|
||||
import org.jooq.Table;
|
||||
@ -147,6 +151,11 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
// XXX: Result API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final <X, A> X collect(Collector<? super R, A, X> collector) {
|
||||
return stream().collect(collector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isEmpty() {
|
||||
return records.isEmpty();
|
||||
@ -174,62 +183,70 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <T> List<T> getValues(Field<T> field) {
|
||||
return (List<T>) getValues(indexOrFail(fieldsRow(), field));
|
||||
return collect(toList(recordType().mapper(field)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> List<U> getValues(Field<?> field, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return getValues(indexOrFail(fieldsRow(), field), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T, U> List<U> getValues(Field<T> field, Converter<? super T, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return Convert.convert(getValues(field), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<?> getValues(int fieldIndex) {
|
||||
return Tools.map(this, r -> r.get(fieldIndex));
|
||||
return collect(toList(recordType().mapper(fieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> List<U> getValues(int fieldIndex, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
Converter converter = converterOrFail(this, field(safeIndex(fieldIndex)).getType(), (Class) type);
|
||||
return Tools.map(this, r -> (U) converter.from(r.get(fieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> List<U> getValues(int fieldIndex, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return Convert.convert(getValues(fieldIndex), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<?> getValues(String fieldName) {
|
||||
return getValues(field(fieldName));
|
||||
return collect(toList(recordType().mapper(fieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> List<U> getValues(String fieldName, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return getValues(indexOrFail(fieldsRow(), fieldName), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> List<U> getValues(String fieldName, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return Convert.convert(getValues(fieldName), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<?> getValues(Name fieldName) {
|
||||
return getValues(field(fieldName));
|
||||
return collect(toList(recordType().mapper(fieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> List<U> getValues(Name fieldName, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return getValues(indexOrFail(fieldsRow(), fieldName), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> List<U> getValues(Name fieldName, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return Convert.convert(getValues(fieldName), converter);
|
||||
}
|
||||
|
||||
@ -244,65 +261,42 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <K> Map<K, R> intoMap(Field<K> key) {
|
||||
return intoMap0(indexOrFail(fieldsRow(), key));
|
||||
return collect(toMap(recordType().mapper(key)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, R> intoMap(int keyFieldIndex) {
|
||||
return intoMap0(keyFieldIndex);
|
||||
return collect(toMap(recordType().mapper(keyFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, R> intoMap(String keyFieldName) {
|
||||
return intoMap(field(keyFieldName));
|
||||
return collect(toMap(recordType().mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, R> intoMap(Name keyFieldName) {
|
||||
return intoMap(field(keyFieldName));
|
||||
}
|
||||
|
||||
private final <K> Map<K, R> intoMap0(int kIndex) {
|
||||
Map<K, R> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
if (map.put((K) record.get(kIndex), record) != null)
|
||||
throw new InvalidResultException("Key " + record.get(kIndex) + " is not unique in Result for " + this);
|
||||
|
||||
return map;
|
||||
return collect(toMap(recordType().mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, V> intoMap(Field<K> key, Field<V> value) {
|
||||
int kIndex = indexOrFail(fieldsRow(), key);
|
||||
int vIndex = indexOrFail(fieldsRow(), value);
|
||||
|
||||
return intoMap0(kIndex, vIndex);
|
||||
return collect(toMap(recordType().mapper(key), recordType().mapper(value)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, ?> intoMap(int keyFieldIndex, int valueFieldIndex) {
|
||||
return intoMap0(keyFieldIndex, valueFieldIndex);
|
||||
return collect(toMap(recordType().mapper(keyFieldIndex), recordType().mapper(valueFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, ?> intoMap(String keyFieldName, String valueFieldName) {
|
||||
return intoMap(field(keyFieldName), field(valueFieldName));
|
||||
return collect(toMap(recordType().mapper(keyFieldName), recordType().mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, ?> intoMap(Name keyFieldName, Name valueFieldName) {
|
||||
return intoMap(field(keyFieldName), field(valueFieldName));
|
||||
}
|
||||
|
||||
private final <K, V> Map<K, V> intoMap0(int kIndex, int vIndex) {
|
||||
Map<K, V> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
if (map.put((K) record.get(kIndex), (V) record.get(vIndex)) != null)
|
||||
throw new InvalidResultException("Key " + record.get(kIndex) + " is not unique in Result for " + this);
|
||||
|
||||
return map;
|
||||
return collect(toMap(recordType().mapper(keyFieldName), recordType().mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -393,7 +387,7 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <E> Map<List<?>, E> intoMap(Field<?>[] keys, Class<? extends E> type) {
|
||||
return intoMap(keys, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return intoMap(keys, recordType().mapper(Tools.configuration(this), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -430,262 +424,172 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <K> Map<K, R> intoMap(Class<? extends K> keyType) {
|
||||
return intoMap(Tools.configuration(this).recordMapperProvider().provide(recordType(), keyType));
|
||||
return collect(toMap(recordType().mapper(Tools.configuration(this), keyType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, V> intoMap(Class<? extends K> keyType, Class<? extends V> valueType) {
|
||||
return intoMap(
|
||||
Tools.configuration(this).recordMapperProvider().provide(recordType(), keyType),
|
||||
Tools.configuration(this).recordMapperProvider().provide(recordType(), valueType)
|
||||
);
|
||||
return collect(toMap(recordType().mapper(Tools.configuration(this), keyType), recordType().mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, V> intoMap(Class<? extends K> keyType, RecordMapper<? super R, V> valueMapper) {
|
||||
return intoMap(Tools.configuration(this).recordMapperProvider().provide(recordType(), keyType), valueMapper);
|
||||
return collect(toMap(recordType().mapper(Tools.configuration(this), keyType), valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K> Map<K, R> intoMap(RecordMapper<? super R, K> keyMapper) {
|
||||
Map<K, R> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this) {
|
||||
K key = keyMapper.map(record);
|
||||
|
||||
if (map.put(key, record) != null)
|
||||
throw new InvalidResultException("Key list " + key + " is not unique in Result for " + this);
|
||||
}
|
||||
|
||||
return map;
|
||||
return collect(toMap(keyMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, V> intoMap(RecordMapper<? super R, K> keyMapper, Class<V> valueType) {
|
||||
return intoMap(keyMapper, Tools.configuration(this).recordMapperProvider().provide(recordType(), valueType));
|
||||
return collect(toMap(keyMapper, recordType().mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, V> intoMap(RecordMapper<? super R, K> keyMapper, RecordMapper<? super R, V> valueMapper) {
|
||||
Map<K, V> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this) {
|
||||
K key = keyMapper.map(record);
|
||||
V value = valueMapper.map(record);
|
||||
|
||||
if (map.put(key, value) != null)
|
||||
throw new InvalidResultException("Key list " + key + " is not unique in Result for " + this);
|
||||
}
|
||||
|
||||
return map;
|
||||
return collect(toMap(keyMapper, valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <S extends Record> Map<S, R> intoMap(Table<S> table) {
|
||||
Map<S, R> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this) {
|
||||
S key = record.into(table);
|
||||
|
||||
if (map.put(key, record) != null)
|
||||
throw new InvalidResultException("Key list " + key + " is not unique in Result for " + this);
|
||||
}
|
||||
|
||||
return map;
|
||||
return collect(toMap(recordType().mapper(table)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <S extends Record, T extends Record> Map<S, T> intoMap(Table<S> keyTable, Table<T> valueTable) {
|
||||
Map<S, T> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this) {
|
||||
S key = record.into(keyTable);
|
||||
T value = record.into(valueTable);
|
||||
|
||||
if (map.put(key, value) != null)
|
||||
throw new InvalidResultException("Key list " + key + " is not unique in Result for " + this);
|
||||
}
|
||||
|
||||
return map;
|
||||
return collect(toMap(recordType().mapper(keyTable), recordType().mapper(valueTable)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E, S extends Record> Map<S, E> intoMap(Table<S> table, Class<? extends E> type) {
|
||||
return intoMap(table, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toMap(recordType().mapper(table), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E, S extends Record> Map<S, E> intoMap(Table<S> table, RecordMapper<? super R, E> mapper) {
|
||||
Map<S, E> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this) {
|
||||
S key = record.into(table);
|
||||
|
||||
if (map.put(key, mapper.map(record)) != null)
|
||||
throw new InvalidResultException("Key list " + key + " is not unique in Result for " + this);
|
||||
}
|
||||
|
||||
return map;
|
||||
return collect(toMap(recordType().mapper(table), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, E> intoMap(int keyFieldIndex, Class<? extends E> type) {
|
||||
return intoMap(keyFieldIndex, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toMap(recordType().mapper(keyFieldIndex), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, E> intoMap(String keyFieldName, Class<? extends E> type) {
|
||||
return intoMap(keyFieldName, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toMap(recordType().mapper(keyFieldName), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, E> intoMap(Name keyFieldName, Class<? extends E> type) {
|
||||
return intoMap(keyFieldName, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toMap(recordType().mapper(keyFieldName), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, E> Map<K, E> intoMap(Field<K> key, Class<? extends E> type) {
|
||||
return intoMap(key, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toMap(recordType().mapper(key), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, E> intoMap(int keyFieldIndex, RecordMapper<? super R, E> mapper) {
|
||||
return intoMap0(keyFieldIndex, mapper);
|
||||
return collect(toMap(recordType().mapper(keyFieldIndex), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, E> intoMap(String keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return intoMap(field(keyFieldName), mapper);
|
||||
return collect(toMap(recordType().mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, E> intoMap(Name keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return intoMap(field(keyFieldName), mapper);
|
||||
return collect(toMap(recordType().mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, E> Map<K, E> intoMap(Field<K> key, RecordMapper<? super R, E> mapper) {
|
||||
return intoMap0(indexOrFail(fieldsRow(), key), mapper);
|
||||
}
|
||||
|
||||
private final <K, E> Map<K, E> intoMap0(int kIndex, RecordMapper<? super R, E> mapper) {
|
||||
Map<K, E> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
if (map.put((K) record.get(kIndex), mapper.map(record)) != null)
|
||||
throw new InvalidResultException("Key " + record.get(kIndex) + " is not unique in Result for " + this);
|
||||
|
||||
return map;
|
||||
return collect(toMap(recordType().mapper(key), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K> Map<K, Result<R>> intoGroups(Field<K> key) {
|
||||
return intoGroups0(indexOrFail(fieldsRow(), key));
|
||||
return collect(toGroups(recordType().mapper(key)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, Result<R>> intoGroups(int keyFieldIndex) {
|
||||
return intoGroups0(keyFieldIndex);
|
||||
return collect(toGroups(recordType().mapper(keyFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, Result<R>> intoGroups(String keyFieldName) {
|
||||
return intoGroups(field(keyFieldName));
|
||||
return collect(toGroups(recordType().mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, Result<R>> intoGroups(Name keyFieldName) {
|
||||
return intoGroups(field(keyFieldName));
|
||||
}
|
||||
|
||||
private final <K> Map<K, Result<R>> intoGroups0(int keyFieldIndex) {
|
||||
Map<K, Result<R>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent((K) record.get(keyFieldIndex), v -> new ResultImpl<>(configuration, fields)).add(record);
|
||||
|
||||
return map;
|
||||
return collect(toGroups(recordType().mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, List<V>> intoGroups(Field<K> key, Field<V> value) {
|
||||
int kIndex = indexOrFail(fieldsRow(), key);
|
||||
int vIndex = indexOrFail(fieldsRow(), value);
|
||||
|
||||
return intoGroups0(kIndex, vIndex);
|
||||
return collect(toGroups(recordType().mapper(key), recordType().mapper(value)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, List<?>> intoGroups(int keyFieldIndex, int valueFieldIndex) {
|
||||
return (Map) intoGroups0(keyFieldIndex, valueFieldIndex);
|
||||
return (Map) collect(toGroups(recordType().mapper(keyFieldIndex), recordType().mapper(valueFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, List<?>> intoGroups(String keyFieldName, String valueFieldName) {
|
||||
return (Map) intoGroups(field(keyFieldName), field(valueFieldName));
|
||||
return (Map) collect(toGroups(recordType().mapper(keyFieldName), recordType().mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<?, List<?>> intoGroups(Name keyFieldName, Name valueFieldName) {
|
||||
return (Map) intoGroups(field(keyFieldName), field(valueFieldName));
|
||||
}
|
||||
|
||||
private final <K, V> Map<K, List<V>> intoGroups0(int kIndex, int vIndex) {
|
||||
Map<K, List<V>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent((K) record.get(kIndex), k -> new ArrayList<>()).add((V) record.get(vIndex));
|
||||
|
||||
return map;
|
||||
return (Map) collect(toGroups(recordType().mapper(keyFieldName), recordType().mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, List<E>> intoGroups(int keyFieldIndex, Class<? extends E> type) {
|
||||
return intoGroups(keyFieldIndex, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toGroups(recordType().mapper(keyFieldIndex), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, List<E>> intoGroups(String keyFieldName, Class<? extends E> type) {
|
||||
return intoGroups(keyFieldName, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toGroups(recordType().mapper(keyFieldName), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, List<E>> intoGroups(Name keyFieldName, Class<? extends E> type) {
|
||||
return intoGroups(keyFieldName, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toGroups(recordType().mapper(keyFieldName), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, E> Map<K, List<E>> intoGroups(Field<K> key, Class<? extends E> type) {
|
||||
return intoGroups(key, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toGroups(recordType().mapper(key), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, E> Map<K, List<E>> intoGroups(Field<K> key, RecordMapper<? super R, E> mapper) {
|
||||
return intoGroups0(indexOrFail(fieldsRow(), key), mapper);
|
||||
return collect(toGroups(recordType().mapper(key), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, List<E>> intoGroups(int keyFieldIndex, RecordMapper<? super R, E> mapper) {
|
||||
return intoGroups0(keyFieldIndex, mapper);
|
||||
return collect(toGroups(recordType().mapper(keyFieldIndex), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, List<E>> intoGroups(String keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return intoGroups(field(keyFieldName), mapper);
|
||||
return collect(toGroups(recordType().mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<?, List<E>> intoGroups(Name keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return intoGroups(field(keyFieldName), mapper);
|
||||
}
|
||||
|
||||
private final <K, E> Map<K, List<E>> intoGroups0(int keyFieldIndex, RecordMapper<? super R, E> mapper) {
|
||||
Map<K, List<E>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent((K) record.get(keyFieldIndex), k -> new ArrayList<>()).add(mapper.map(record));
|
||||
|
||||
return map;
|
||||
return collect(toGroups(recordType().mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -714,7 +618,7 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
for (Field<?> field : keysRow.fields.fields)
|
||||
Tools.copyValue(key, field, record, field);
|
||||
|
||||
map.computeIfAbsent(key, k -> new ResultImpl<>(configuration(), this.fields)).add(record);
|
||||
map.computeIfAbsent(key, k -> new ResultImpl<>(Tools.configuration(this), this.fields)).add(record);
|
||||
}
|
||||
|
||||
return map;
|
||||
@ -751,7 +655,7 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
for (Field<?> field : valuesRow.fields.fields)
|
||||
Tools.copyValue(value, field, record, field);
|
||||
|
||||
map.computeIfAbsent(key, k -> new ResultImpl<>(configuration(), valuesRow)).add(value);
|
||||
map.computeIfAbsent(key, k -> new ResultImpl<>(Tools.configuration(this), valuesRow)).add(value);
|
||||
}
|
||||
|
||||
return map;
|
||||
@ -759,22 +663,22 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <E> Map<Record, List<E>> intoGroups(int[] keyFieldIndexes, Class<? extends E> type) {
|
||||
return intoGroups(keyFieldIndexes, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return intoGroups(keyFieldIndexes, recordType().mapper(Tools.configuration(this), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<Record, List<E>> intoGroups(String[] keyFieldNames, Class<? extends E> type) {
|
||||
return intoGroups(keyFieldNames, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return intoGroups(keyFieldNames, recordType().mapper(Tools.configuration(this), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<Record, List<E>> intoGroups(Name[] keyFieldNames, Class<? extends E> type) {
|
||||
return intoGroups(keyFieldNames, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return intoGroups(keyFieldNames, recordType().mapper(Tools.configuration(this), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E> Map<Record, List<E>> intoGroups(Field<?>[] keys, Class<? extends E> type) {
|
||||
return intoGroups(keys, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return intoGroups(keys, recordType().mapper(Tools.configuration(this), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -811,80 +715,58 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <K> Map<K, Result<R>> intoGroups(Class<? extends K> keyType) {
|
||||
return intoGroups(Tools.configuration(this).recordMapperProvider().provide(recordType(), keyType));
|
||||
return collect(toGroups(recordType().mapper(Tools.configuration(this), keyType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, List<V>> intoGroups(Class<? extends K> keyType, Class<? extends V> valueType) {
|
||||
return intoGroups(
|
||||
Tools.configuration(this).recordMapperProvider().provide(recordType(), keyType),
|
||||
Tools.configuration(this).recordMapperProvider().provide(recordType(), valueType)
|
||||
);
|
||||
return collect(toGroups(recordType().mapper(Tools.configuration(this), keyType), recordType().mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, List<V>> intoGroups(Class<? extends K> keyType, RecordMapper<? super R, V> valueMapper) {
|
||||
return intoGroups(Tools.configuration(this).recordMapperProvider().provide(recordType(), keyType), valueMapper);
|
||||
return collect(toGroups(recordType().mapper(Tools.configuration(this), keyType), valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K> Map<K, Result<R>> intoGroups(RecordMapper<? super R, K> keyMapper) {
|
||||
Map<K, Result<R>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent(keyMapper.map(record), k -> new ResultImpl<>(configuration(), fields)).add(record);
|
||||
|
||||
return map;
|
||||
return collect(toGroups(keyMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, List<V>> intoGroups(RecordMapper<? super R, K> keyMapper, Class<V> valueType) {
|
||||
return intoGroups(keyMapper, Tools.configuration(this).recordMapperProvider().provide(recordType(), valueType));
|
||||
return collect(toGroups(keyMapper, recordType().mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <K, V> Map<K, List<V>> intoGroups(RecordMapper<? super R, K> keyMapper, RecordMapper<? super R, V> valueMapper) {
|
||||
Map<K, List<V>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent(keyMapper.map(record), k -> new ArrayList<>()).add(valueMapper.map(record));
|
||||
|
||||
return map;
|
||||
return collect(toGroups(keyMapper, valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <S extends Record> Map<S, Result<R>> intoGroups(Table<S> table) {
|
||||
Map<S, Result<R>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent(record.into(table), k -> new ResultImpl<>(configuration(), this.fields)).add(record);
|
||||
|
||||
return map;
|
||||
return collect(toGroups(recordType().mapper(table)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <S extends Record, T extends Record> Map<S, Result<T>> intoGroups(Table<S> keyTable, Table<T> valueTable) {
|
||||
// [#9288] TODO: Can't use collect(toGroups(recordType().mapper(keyTable), recordType().mapper(valueTable))) yet
|
||||
Map<S, Result<T>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent(record.into(keyTable), k -> DSL.using(configuration()).newResult(valueTable)).add(record.into(valueTable));
|
||||
map.computeIfAbsent(record.into(keyTable), k -> DSL.using(Tools.configuration(this)).newResult(valueTable)).add(record.into(valueTable));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E, S extends Record> Map<S, List<E>> intoGroups(Table<S> table, Class<? extends E> type) {
|
||||
return intoGroups(table, Tools.configuration(this).recordMapperProvider().provide(recordType(), type));
|
||||
return collect(toGroups(recordType().mapper(table), recordType().mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E, S extends Record> Map<S, List<E>> intoGroups(Table<S> table, RecordMapper<? super R, E> mapper) {
|
||||
Map<S, List<E>> map = new LinkedHashMap<>();
|
||||
|
||||
for (R record : this)
|
||||
map.computeIfAbsent(record.into(table), k -> new ArrayList<>()).add(mapper.map(record));
|
||||
|
||||
return map;
|
||||
return collect(toGroups(recordType().mapper(table), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -960,71 +842,74 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <E> Set<E> intoSet(RecordMapper<? super R, E> mapper) {
|
||||
Set<E> result = new LinkedHashSet<>();
|
||||
|
||||
for (R record : this)
|
||||
result.add(mapper.map(record));
|
||||
|
||||
return result;
|
||||
return collect(toSet(mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Set<?> intoSet(int fieldIndex) {
|
||||
return new LinkedHashSet<>(getValues(fieldIndex));
|
||||
return collect(toSet(recordType().mapper(fieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> Set<U> intoSet(int fieldIndex, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(fieldIndex, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> Set<U> intoSet(int fieldIndex, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(fieldIndex, converter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Set<?> intoSet(String fieldName) {
|
||||
return new LinkedHashSet<>(getValues(fieldName));
|
||||
return collect(toSet(recordType().mapper(fieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> Set<U> intoSet(String fieldName, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(fieldName, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> Set<U> intoSet(String fieldName, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(fieldName, converter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Set<?> intoSet(Name fieldName) {
|
||||
return new LinkedHashSet<>(getValues(fieldName));
|
||||
return collect(toSet(recordType().mapper(fieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> Set<U> intoSet(Name fieldName, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(fieldName, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> Set<U> intoSet(Name fieldName, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(fieldName, converter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> Set<T> intoSet(Field<T> field) {
|
||||
return new LinkedHashSet<>(getValues(field));
|
||||
return collect(toSet(recordType().mapper(field)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <U> Set<U> intoSet(Field<?> field, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(field, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T, U> Set<U> intoSet(Field<T> field, Converter<? super T, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return new LinkedHashSet<>(getValues(field, converter));
|
||||
}
|
||||
|
||||
@ -1154,13 +1039,12 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
|
||||
@Override
|
||||
public final <E> List<E> into(Class<? extends E> type) {
|
||||
RecordMapper<R, E> mapper = Tools.configuration(this).recordMapperProvider().provide(recordType(), type);
|
||||
return Tools.map(this, mapper::map);
|
||||
return Tools.map(this, recordType().mapper(Tools.configuration(this), type)::map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <Z extends Record> Result<Z> into(Table<Z> table) {
|
||||
Result<Z> list = new ResultImpl<>(configuration(), (AbstractRow) table.fieldsRow());
|
||||
Result<Z> list = new ResultImpl<>(Tools.configuration(this), (AbstractRow) table.fieldsRow());
|
||||
|
||||
for (R record : this)
|
||||
list.add(record.into(table));
|
||||
|
||||
@ -37,6 +37,9 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Records.toGroups;
|
||||
import static org.jooq.Records.toMap;
|
||||
import static org.jooq.Records.toSet;
|
||||
import static org.jooq.impl.Tools.blocking;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
@ -52,13 +55,14 @@ import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.Executor;
|
||||
// ...
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.Cursor;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Mappable;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.Record;
|
||||
@ -86,6 +90,7 @@ import org.jooq.Record8;
|
||||
import org.jooq.Record9;
|
||||
import org.jooq.RecordHandler;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.jooq.Records;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.ResultQuery;
|
||||
import org.jooq.Results;
|
||||
@ -105,7 +110,7 @@ import io.r2dbc.spi.ConnectionFactory;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQuery<R> {
|
||||
interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQuery<R>, Mappable<R> {
|
||||
|
||||
@Override
|
||||
default ResultQuery<Record> coerce(Field<?>... fields) {
|
||||
@ -782,82 +787,82 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
|
||||
|
||||
@Override
|
||||
default <K> Map<K, R> fetchMap(Field<K> key) {
|
||||
return fetch().intoMap(key);
|
||||
return collect(toMap(mapper(key)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, R> fetchMap(int keyFieldIndex) {
|
||||
return fetch().intoMap(keyFieldIndex);
|
||||
return collect(toMap(mapper(keyFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, R> fetchMap(String keyFieldName) {
|
||||
return fetch().intoMap(keyFieldName);
|
||||
return collect(toMap(mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, R> fetchMap(Name keyFieldName) {
|
||||
return fetch().intoMap(keyFieldName);
|
||||
return collect(toMap(mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, V> fetchMap(Field<K> key, Field<V> value) {
|
||||
return fetch().intoMap(key, value);
|
||||
return collect(toMap(mapper(key), mapper(value)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, ?> fetchMap(int keyFieldIndex, int valueFieldIndex) {
|
||||
return fetch().intoMap(keyFieldIndex, valueFieldIndex);
|
||||
return collect(toMap(mapper(keyFieldIndex), mapper(valueFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, ?> fetchMap(String keyFieldName, String valueFieldName) {
|
||||
return fetch().intoMap(keyFieldName, valueFieldName);
|
||||
return collect(toMap(mapper(keyFieldName), mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, ?> fetchMap(Name keyFieldName, Name valueFieldName) {
|
||||
return fetch().intoMap(keyFieldName, valueFieldName);
|
||||
return collect(toMap(mapper(keyFieldName), mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
|
||||
return fetch().intoMap(key, type);
|
||||
return collect(toMap(mapper(key), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, E> fetchMap(int keyFieldIndex, Class<? extends E> type) {
|
||||
return fetch().intoMap(keyFieldIndex, type);
|
||||
return collect(toMap(mapper(keyFieldIndex), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, E> fetchMap(String keyFieldName, Class<? extends E> type) {
|
||||
return fetch().intoMap(keyFieldName, type);
|
||||
return collect(toMap(mapper(keyFieldName), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, E> fetchMap(Name keyFieldName, Class<? extends E> type) {
|
||||
return fetch().intoMap(keyFieldName, type);
|
||||
return collect(toMap(mapper(keyFieldName), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, E> Map<K, E> fetchMap(Field<K> key, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoMap(key, mapper);
|
||||
return collect(toMap(mapper(key), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, E> fetchMap(int keyFieldIndex, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoMap(keyFieldIndex, mapper);
|
||||
return collect(toMap(mapper(keyFieldIndex), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, E> fetchMap(String keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoMap(keyFieldName, mapper);
|
||||
return collect(toMap(mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, E> fetchMap(Name keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoMap(keyFieldName, mapper);
|
||||
return collect(toMap(mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -942,52 +947,52 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
|
||||
|
||||
@Override
|
||||
default <K> Map<K, R> fetchMap(Class<? extends K> keyType) {
|
||||
return fetch().intoMap(keyType);
|
||||
return collect(toMap(mapper(Tools.configuration(this), keyType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, V> fetchMap(Class<? extends K> keyType, Class<? extends V> valueType) {
|
||||
return fetch().intoMap(keyType, valueType);
|
||||
return collect(toMap(mapper(Tools.configuration(this), keyType), mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, V> fetchMap(Class<? extends K> keyType, RecordMapper<? super R, V> valueMapper) {
|
||||
return fetch().intoMap(keyType, valueMapper);
|
||||
return collect(toMap(mapper(Tools.configuration(this), keyType), valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K> Map<K, R> fetchMap(RecordMapper<? super R, K> keyMapper) {
|
||||
return fetch().intoMap(keyMapper);
|
||||
return collect(toMap(keyMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, V> fetchMap(RecordMapper<? super R, K> keyMapper, Class<V> valueType) {
|
||||
return fetch().intoMap(keyMapper, valueType);
|
||||
return collect(toMap(keyMapper, mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, V> fetchMap(RecordMapper<? super R, K> keyMapper, RecordMapper<? super R, V> valueMapper) {
|
||||
return fetch().intoMap(keyMapper, valueMapper);
|
||||
return collect(toMap(keyMapper, valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <S extends Record> Map<S, R> fetchMap(Table<S> table) {
|
||||
return fetch().intoMap(table);
|
||||
return collect(toMap(mapper(table)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <S extends Record, T extends Record> Map<S, T> fetchMap(Table<S> keyTable, Table<T> valueTable) {
|
||||
return fetch().intoMap(keyTable, valueTable);
|
||||
return collect(toMap(mapper(keyTable), mapper(valueTable)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E, S extends Record> Map<S, E> fetchMap(Table<S> table, Class<? extends E> type) {
|
||||
return fetch().intoMap(table, type);
|
||||
return collect(toMap(mapper(table), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E, S extends Record> Map<S, E> fetchMap(Table<S> table, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoMap(table, mapper);
|
||||
return collect(toMap(mapper(table), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -997,82 +1002,82 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
|
||||
|
||||
@Override
|
||||
default <K> Map<K, Result<R>> fetchGroups(Field<K> key) {
|
||||
return fetch().intoGroups(key);
|
||||
return collect(toGroups(mapper(key)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, Result<R>> fetchGroups(int keyFieldIndex) {
|
||||
return fetch().intoGroups(keyFieldIndex);
|
||||
return collect(toGroups(mapper(keyFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, Result<R>> fetchGroups(String keyFieldName) {
|
||||
return fetch().intoGroups(keyFieldName);
|
||||
return collect(toGroups(mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, Result<R>> fetchGroups(Name keyFieldName) {
|
||||
return fetch().intoGroups(keyFieldName);
|
||||
return collect(toGroups(mapper(keyFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, List<V>> fetchGroups(Field<K> key, Field<V> value) {
|
||||
return fetch().intoGroups(key, value);
|
||||
return collect(toGroups(mapper(key), mapper(value)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, List<?>> fetchGroups(int keyFieldIndex, int valueFieldIndex) {
|
||||
return fetch().intoGroups(keyFieldIndex, valueFieldIndex);
|
||||
return (Map) collect(toGroups(mapper(keyFieldIndex), mapper(valueFieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, List<?>> fetchGroups(String keyFieldName, String valueFieldName) {
|
||||
return fetch().intoGroups(keyFieldName, valueFieldName);
|
||||
return (Map) collect(toGroups(mapper(keyFieldName), mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Map<?, List<?>> fetchGroups(Name keyFieldName, Name valueFieldName) {
|
||||
return fetch().intoGroups(keyFieldName, valueFieldName);
|
||||
return (Map) collect(toGroups(mapper(keyFieldName), mapper(valueFieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, E> Map<K, List<E>> fetchGroups(Field<K> key, Class<? extends E> type) {
|
||||
return fetch().intoGroups(key, type);
|
||||
return collect(toGroups(mapper(key), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, List<E>> fetchGroups(int keyFieldIndex, Class<? extends E> type) {
|
||||
return fetch().intoGroups(keyFieldIndex, type);
|
||||
return collect(toGroups(mapper(keyFieldIndex), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, List<E>> fetchGroups(String keyFieldName, Class<? extends E> type) {
|
||||
return fetch().intoGroups(keyFieldName, type);
|
||||
return collect(toGroups(mapper(keyFieldName), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, List<E>> fetchGroups(Name keyFieldName, Class<? extends E> type) {
|
||||
return fetch().intoGroups(keyFieldName, type);
|
||||
return collect(toGroups(mapper(keyFieldName), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, E> Map<K, List<E>> fetchGroups(Field<K> key, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoGroups(key, mapper);
|
||||
return collect(toGroups(mapper(key), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, List<E>> fetchGroups(int keyFieldIndex, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoGroups(keyFieldIndex, mapper);
|
||||
return collect(toGroups(mapper(keyFieldIndex), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, List<E>> fetchGroups(String keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoGroups(keyFieldName, mapper);
|
||||
return collect(toGroups(mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> Map<?, List<E>> fetchGroups(Name keyFieldName, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoGroups(keyFieldName, mapper);
|
||||
return collect(toGroups(mapper(keyFieldName), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1157,52 +1162,53 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
|
||||
|
||||
@Override
|
||||
default <K> Map<K, Result<R>> fetchGroups(Class<? extends K> keyType) {
|
||||
return fetch().intoGroups(keyType);
|
||||
return collect(toGroups(mapper(Tools.configuration(this), keyType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, List<V>> fetchGroups(Class<? extends K> keyType, Class<? extends V> valueType) {
|
||||
return fetch().intoGroups(keyType, valueType);
|
||||
return collect(toGroups(mapper(Tools.configuration(this), keyType), mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, List<V>> fetchGroups(Class<? extends K> keyType, RecordMapper<? super R, V> valueMapper) {
|
||||
return fetch().intoGroups(keyType, valueMapper);
|
||||
return collect(toGroups(mapper(Tools.configuration(this), keyType), valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K> Map<K, Result<R>> fetchGroups(RecordMapper<? super R, K> keyMapper) {
|
||||
return fetch().intoGroups(keyMapper);
|
||||
return collect(toGroups(keyMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, List<V>> fetchGroups(RecordMapper<? super R, K> keyMapper, Class<V> valueType) {
|
||||
return fetch().intoGroups(keyMapper, valueType);
|
||||
return collect(toGroups(keyMapper, mapper(Tools.configuration(this), valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <K, V> Map<K, List<V>> fetchGroups(RecordMapper<? super R, K> keyMapper, RecordMapper<? super R, V> valueMapper) {
|
||||
return fetch().intoGroups(keyMapper, valueMapper);
|
||||
return collect(toGroups(keyMapper, valueMapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <S extends Record> Map<S, Result<R>> fetchGroups(Table<S> table) {
|
||||
return fetch().intoGroups(table);
|
||||
return collect(toGroups(mapper(table)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <S extends Record, T extends Record> Map<S, Result<T>> fetchGroups(Table<S> keyTable, Table<T> valueTable) {
|
||||
// [#9288] TODO: Can't use collect(toGroups(recordType().mapper(keyTable), recordType().mapper(valueTable))) yet
|
||||
return fetch().intoGroups(keyTable, valueTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, Class<? extends E> type) {
|
||||
return fetch().intoGroups(table, type);
|
||||
return collect(toGroups(mapper(table), mapper(Tools.configuration(this), type)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoGroups(table, mapper);
|
||||
return collect(toGroups(mapper(table), mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1293,66 +1299,74 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
|
||||
|
||||
@Override
|
||||
default <E> Set<E> fetchSet(RecordMapper<? super R, E> mapper) {
|
||||
return fetch().intoSet(mapper);
|
||||
return collect(toSet(mapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Set<?> fetchSet(int fieldIndex) {
|
||||
return fetch().intoSet(fieldIndex);
|
||||
return collect(toSet(mapper(fieldIndex)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <U> Set<U> fetchSet(int fieldIndex, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(fieldIndex, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <U> Set<U> fetchSet(int fieldIndex, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(fieldIndex, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
default Set<?> fetchSet(String fieldName) {
|
||||
return fetch().intoSet(fieldName);
|
||||
return collect(toSet(mapper(fieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <U> Set<U> fetchSet(String fieldName, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(fieldName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <U> Set<U> fetchSet(String fieldName, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(fieldName, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
default Set<?> fetchSet(Name fieldName) {
|
||||
return fetch().intoSet(fieldName);
|
||||
return collect(toSet(mapper(fieldName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <U> Set<U> fetchSet(Name fieldName, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(fieldName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <U> Set<U> fetchSet(Name fieldName, Converter<?, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(fieldName, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <T> Set<T> fetchSet(Field<T> field) {
|
||||
return fetch().intoSet(field);
|
||||
return collect(toSet(mapper(field)));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <U> Set<U> fetchSet(Field<?> field, Class<? extends U> type) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(field, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <T, U> Set<U> fetchSet(Field<T> field, Converter<? super T, ? extends U> converter) {
|
||||
// [#9288] TODO: Refactor this
|
||||
return fetch().intoSet(field, converter);
|
||||
}
|
||||
@Override
|
||||
@ -1387,4 +1401,35 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
default RecordMapper<R, ?> mapper(int fieldIndex) {
|
||||
return new DelayedRecordMapper<>(t -> t.mapper(fieldIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
default RecordMapper<R, ?> mapper(String fieldName) {
|
||||
return new DelayedRecordMapper<>(t -> t.mapper(fieldName));
|
||||
}
|
||||
|
||||
@Override
|
||||
default RecordMapper<R, ?> mapper(Name fieldName) {
|
||||
return new DelayedRecordMapper<>(t -> t.mapper(fieldName));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <T> RecordMapper<R, T> mapper(Field<T> field) {
|
||||
return new DelayedRecordMapper<>(t -> t.mapper(field));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <S extends Record> RecordMapper<R, S> mapper(Table<S> table) {
|
||||
return new DelayedRecordMapper<>(t -> t.mapper(table));
|
||||
}
|
||||
|
||||
@Override
|
||||
default <E> RecordMapper<R, E> mapper(Configuration configuration, Class<? extends E> type) {
|
||||
return new DelayedRecordMapper<>(t -> t.mapper(configuration, type));
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,6 @@ import static org.jooq.impl.CacheType.REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DERBY;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.FIREBIRD;
|
||||
@ -247,6 +246,7 @@ import org.jooq.EnumType;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.ExecuteListener;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Fields;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONB;
|
||||
@ -262,7 +262,6 @@ import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.RecordQualifier;
|
||||
import org.jooq.RecordType;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.RenderContext.CastMode;
|
||||
import org.jooq.Result;
|
||||
@ -1687,11 +1686,11 @@ final class Tools {
|
||||
return map(values, (v, i) -> field(v, types[i]), Field[]::new);
|
||||
}
|
||||
|
||||
static final IllegalArgumentException indexFail(Row row, Field<?> field) {
|
||||
static final IllegalArgumentException indexFail(Fields row, Field<?> field) {
|
||||
return new IllegalArgumentException("Field (" + field + ") is not contained in Row " + row);
|
||||
}
|
||||
|
||||
static final int indexOrFail(Row row, Field<?> field) {
|
||||
static final int indexOrFail(Fields row, Field<?> field) {
|
||||
int result = row.indexOf(field);
|
||||
|
||||
if (result < 0)
|
||||
@ -1700,11 +1699,11 @@ final class Tools {
|
||||
return result;
|
||||
}
|
||||
|
||||
static final IllegalArgumentException indexFail(Row row, String fieldName) {
|
||||
static final IllegalArgumentException indexFail(Fields row, String fieldName) {
|
||||
throw new IllegalArgumentException("Field (" + fieldName + ") is not contained in Row " + row);
|
||||
}
|
||||
|
||||
static final int indexOrFail(Row row, String fieldName) {
|
||||
static final int indexOrFail(Fields row, String fieldName) {
|
||||
int result = row.indexOf(fieldName);
|
||||
|
||||
if (result < 0)
|
||||
@ -1713,11 +1712,11 @@ final class Tools {
|
||||
return result;
|
||||
}
|
||||
|
||||
static final IllegalArgumentException indexFail(Row row, Name fieldName) {
|
||||
static final IllegalArgumentException indexFail(Fields row, Name fieldName) {
|
||||
throw new IllegalArgumentException("Field (" + fieldName + ") is not contained in Row " + row);
|
||||
}
|
||||
|
||||
static final int indexOrFail(Row row, Name fieldName) {
|
||||
static final int indexOrFail(Fields row, Name fieldName) {
|
||||
int result = row.indexOf(fieldName);
|
||||
|
||||
if (result < 0)
|
||||
@ -1726,45 +1725,6 @@ final class Tools {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method that fails with an exception if
|
||||
* {@link RecordType#indexOf(Field)} doesn't return any index.
|
||||
*/
|
||||
static final int indexOrFail(RecordType<?> row, Field<?> field) {
|
||||
int result = row.indexOf(field);
|
||||
|
||||
if (result < 0)
|
||||
throw new IllegalArgumentException("Field (" + field + ") is not contained in RecordType " + row);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method that fails with an exception if
|
||||
* {@link RecordType#indexOf(String)} doesn't return any index.
|
||||
*/
|
||||
static final int indexOrFail(RecordType<?> row, String fieldName) {
|
||||
int result = row.indexOf(fieldName);
|
||||
|
||||
if (result < 0)
|
||||
throw new IllegalArgumentException("Field (" + fieldName + ") is not contained in RecordType " + row);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method that fails with an exception if
|
||||
* {@link RecordType#indexOf(Name)} doesn't return any index.
|
||||
*/
|
||||
static final int indexOrFail(RecordType<?> row, Name fieldName) {
|
||||
int result = row.indexOf(fieldName);
|
||||
|
||||
if (result < 0)
|
||||
throw new IllegalArgumentException("Field (" + fieldName + ") is not contained in RecordType " + row);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final <T> List<T> newListWithCapacity(Iterable<?> it) {
|
||||
return it instanceof Collection ? new ArrayList<>(((Collection<?>) it).size()) : new ArrayList<>();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user