package com.codepoetics.octarine.joins;
import com.codepoetics.octarine.functional.tuples.T2;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Stream;
public final class Joiner<L, R, K> {
private final Index<K, L> leftIndex;
private final JoinKey<R, K> primaryKey;
public Joiner(Index<K, L> leftIndex, JoinKey<R, K> primaryKey) {
this.leftIndex = leftIndex;
this.primaryKey = primaryKey;
}
// Many to one
public Stream<T2<L, R>> manyToOne(Collection<? extends R> rights) {
return manyToOne(rights.stream());
}
public Stream<T2<L, R>> manyToOne(Fetcher<K, R> fetcher) {
return manyToOne(fetcher.fetch(leftIndex.keys()));
}
public Stream<T2<L, R>> manyToOne(Stream<? extends R> rights) {
return leftIndex.manyToOne(primaryKey.index(rights));
}
// Strict many to one
public Stream<T2<L, R>> strictManyToOne(Collection<? extends R> rights) {
return strictManyToOne(rights.stream());
}
public Stream<T2<L, R>> strictManyToOne(Fetcher<K, R> fetcher) {
return strictManyToOne(fetcher.fetch(leftIndex.keys()));
}
public Stream<T2<L, R>> strictManyToOne(Stream<? extends R> rights) {
return leftIndex.strictManyToOne(primaryKey.index(rights));
}
// One to many
public Stream<T2<L, Set<R>>> oneToMany(Collection<? extends R> rights) {
return oneToMany(rights.stream());
}
public Stream<T2<L, Set<R>>> oneToMany(Fetcher<K, R> fetcher) {
return oneToMany(fetcher.fetch(leftIndex.keys()));
}
public Stream<T2<L, Set<R>>> oneToMany(Stream<? extends R> rights) {
return leftIndex.oneToMany(primaryKey.index(rights));
}
// Strict one to many
public Stream<T2<L, Set<R>>> strictOneToMany(Collection<? extends R> rights) {
return strictOneToMany(rights.stream());
}
public Stream<T2<L, Set<R>>> strictOneToMany(Fetcher<K, R> fetcher) {
return strictOneToMany(fetcher.fetch(leftIndex.keys()));
}
public Stream<T2<L, Set<R>>> strictOneToMany(Stream<? extends R> rights) {
return leftIndex.strictOneToMany(primaryKey.index(rights));
}
// Strict one to one
public Stream<T2<L, R>> strictOneToOne(Collection<? extends R> rights) {
return strictOneToOne(rights.stream());
}
public Stream<T2<L, R>> strictOneToOne(Fetcher<K, R> fetcher) {
return strictOneToOne(fetcher.fetch(leftIndex.keys()));
}
public Stream<T2<L, R>> strictOneToOne(Stream<? extends R> rights) {
return leftIndex.strictOneToOne(primaryKey.index(rights));
}
}