On 18 Jan 2019, at 23:05, Lukas Eder wrote: > I'm not sure why you're calling Select.union() instead of > SelectUnionStep.union()... > > <https://www.jooq.org/javadoc/latest/org/jooq/SelectUnionStep.html>
Basically - I have a list/iterable of table names, or `Instant`'s in some
cases, and a mapping function which generates a Jooq select based on that value
( we're unioning over an optimized set of partitioned tables ).
After fighting generics back and forth I have the following that works:
```java
public static <A, T extends Record, S extends SelectOrderByStep<T>>
S reduce2(Iterable<A> iterable, Function<A, S> selectMapper,
BiFunction<S, S, SelectOrderByStep<T>> accumulator) {
requireNonNull(iterable, "iterable must not be null");
Iterator<A> iterator = iterable.iterator();
if (!iterator.hasNext()) {
throw new IllegalStateException("iterable must not be empty");
}
if (!iterator.hasNext()) {
return selectMapper.apply(iterator.next());
} else {
S unioned = selectMapper.apply(iterator.next());
while (iterator.hasNext()) {
A next = iterator.next();
S apply = selectMapper.apply(next);
unioned = (S) accumulator.apply(unioned, apply);
}
return unioned;
}
}
```
An unfortunate downsides here tho is having to cast to `(S)` to trick the
compiler/type-erasure that things are ok - along with a usage call of:
```java
Select<Record> select = JooqUtil.reduce2(tables, table ->
DSL.select().from(table), SelectJoinStep::unionAll)
.limit(1);
```
In the original implementation this method was provide, with an exposed
`unionSelect` and `unionAllSelects` which supplied a method reference to
`Select::union` - which, due to that version returning `Select` threw me into
the quagmire I was in due to the fixing of specific Jooq sub-class types. A
`BinaryOperator` was originally used, but switching to a BiFunction over a
newly introduced `S` which is bound to the particular query Type, and returns a
fixed `SelectOrderStep<T>`, along with forcing the caller to provide the
appropriate `*::union` method reference seems to solve this.
Update: This led me to discovering that this also works:
```java
public static <A, T extends Record, S extends SelectOrderByStep<T>> S
unionAllSelects2(Iterable<A> iterable, final Function<A, S> selectMapper) {
return reduce2(iterable, selectMapper, S::unionAll);
}
```
Turns out you _can_ declare a method reference against a generically bound
type, which means I can make my `reduce2` private again, and I should be able
to remain source compatible among my modules, if not binary compatible.
I wonder if there's a cleaner way tho....
---
"The ease with which a change can be implemented has no relevance at all to
whether it is the right change for the (Java) Platform for all time." —
Mark Reinhold.
Mark Derricutt
http://www.theoryinpractice.net
http://www.chaliceofblood.net
http://plus.google.com/+MarkDerricutt
http://twitter.com/talios
http://facebook.com/mderricutt
--
You received this message because you are subscribed to the Google Groups "jOOQ
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
signature.asc
Description: OpenPGP digital signature
