[jOOQ/jOOQ#11901] Implement more optimal ResultQuery.forEach() method

This commit is contained in:
Lukas Eder 2021-05-19 14:37:45 +02:00
parent 9cb8781445
commit 2d7c136222
2 changed files with 26 additions and 14 deletions

View File

@ -189,19 +189,6 @@ public interface ResultQuery<R extends Record> extends Query, Iterable<R>, Publi
@Override
Iterator<R> iterator() throws DataAccessException;
/**
* Execute the query using {@link #fetch()} and pass all results to a
* consumer.
* <p>
* This is essentially the same as {@link #fetch()}.
* <p>
* {@inheritDoc}
*/
@Override
default void forEach(Consumer<? super R> action) {
Iterable.super.forEach(action);
}
/**
* Execute the query using {@link #fetch()} and return the generated result
* as an {@link Spliterator}.

View File

@ -63,6 +63,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -313,7 +314,21 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
// [#11895] Don't use the Stream.of(1).flatMap(i -> fetchLazy().stream())
// trick, because flatMap() will consume the entire result set
return fetchLazy().stream();
AtomicReference<Cursor<R>> r = new AtomicReference<>();
// [#11895] Don't use the Stream.of(1).flatMap(i -> fetchLazy().stream())
// trick, because flatMap() will consume the entire result set
return StreamSupport.stream(
() -> {
Cursor<R> c = fetchLazy();
r.set(c);
return c.spliterator();
},
Spliterator.IMMUTABLE | Spliterator.NONNULL | Spliterator.ORDERED,
false
).onClose(() -> {
safeClose(r.get());
});
}
@Override
@ -1398,6 +1413,16 @@ interface ResultQueryTrait<R extends Record> extends QueryPartInternal, ResultQu
return handler;
}
@Override
default void forEach(Consumer<? super R> action) {
if (fetchIntermediateResult(Tools.configuration(this))) {
fetch().forEach(action);
}
else try (Cursor<R> c = fetchLazy()) {
c.forEach(action);
}
}
@Override
default <E> List<E> fetch(RecordMapper<? super R, E> mapper) {
return collect(mapping(mapper, toList()));