com.kenshoo.pl.entity.internal.fetch.QueryBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of persistence-layer Show documentation
Show all versions of persistence-layer Show documentation
A Java persistence layer based on JOOQ for high performance and business flow support.
package com.kenshoo.pl.entity.internal.fetch;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.kenshoo.jooq.*;
import com.kenshoo.pl.entity.*;
import org.jooq.*;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import static org.jooq.impl.DSL.trueCondition;
import static org.jooq.lambda.function.Functions.not;
public class QueryBuilder> {
private final QueryExtender DONT_EXTEND_WITH_IDS = this::dontExtend;
private DSLContext dslContext;
private List> selectedFields;
private DataTable startingTable;
private List paths = Collections.emptyList();
private Set oneToOneTableRelations = Collections.emptySet();
private Condition condition = trueCondition();
private Partitioner partitioner = this::addPartitionToCondition;
private QueryExtender queryExtender = DONT_EXTEND_WITH_IDS;
public QueryBuilder(DSLContext dslContext) {
this.dslContext = dslContext;
}
public QueryBuilder selecting(List> selectedFields) {
this.selectedFields = selectedFields;
return this;
}
public QueryBuilder from(DataTable primaryTable) {
this.startingTable = primaryTable;
return this;
}
public QueryBuilder innerJoin(List paths) {
this.paths = paths;
return this;
}
public QueryBuilder innerJoin(TreeEdge path) {
this.paths = Lists.newArrayList(path);
return this;
}
public QueryBuilder leftJoin(Set oneToOneTableRelations) {
this.oneToOneTableRelations = oneToOneTableRelations;
return this;
}
public QueryBuilder whereIdsIn(Collection extends Identifier extends EntityType>>> ids) {
if (queryExtender != DONT_EXTEND_WITH_IDS) {
throw new IllegalStateException("We currently support only a single query extension");
}
this.queryExtender = query -> addIdCondition(query, (Collection)ids);
return this;
}
public QueryBuilder withCondition(Condition condition) {
this.condition = condition;
return this;
}
public QueryBuilder withoutPartitions() {
this.partitioner = NO_PARTITION;
return this;
}
public QueryExtension> build() {
final SelectJoinStep query = dslContext.select(selectedFields).from(startingTable);
final Set joinedTables = Sets.newHashSet(startingTable);
paths.forEach(edge -> joinTables(query, joinedTables, edge));
joinSecondaryTables(query, joinedTables, oneToOneTableRelations);
condition = partitioner.transform(startingTable, condition);
query.where(condition);
return queryExtender.transform(query);
}
static void joinTables(SelectJoinStep query, Set alreadyJoinedTables, TreeEdge edgeInThePath) {
// The joins must be composed in the order of traversal, so we have to "unwind" the path traveled from the root
// Using a stack for that
LinkedList joins = new LinkedList<>();
joins.push(edgeInThePath);
// Push onto the stack until we reach a table already joined (or the starting table)
while (!alreadyJoinedTables.contains(edgeInThePath.source.table)) {
edgeInThePath = edgeInThePath.source.parent;
joins.push(edgeInThePath);
}
// Perform the joins
for (TreeEdge join : joins) {
DataTable rhs = join.target.table;
query.join(rhs).on(getJoinCondition(join.source.table, join.target.table));
alreadyJoinedTables.add(rhs);
}
}
static void joinSecondaryTables(SelectJoinStep query, Set extends Table> alreadyJoinedTables, Set targetOneToOneRelations) {
targetOneToOneRelations.stream()
.filter(not(secondaryTableIn(alreadyJoinedTables)))
.forEach(addLeftJoinTo(query));
}
private static Condition getJoinCondition(Table fromTable, Table toTable) {
List> foreignKeys = toTable.getReferencesTo(fromTable);
if (foreignKeys.isEmpty()) {
foreignKeys = fromTable.getReferencesTo(toTable);
}
if (foreignKeys.isEmpty()) {
return null;
}
Condition joinCondition = trueCondition();
ForeignKey foreignKey = foreignKeys.get(0);
org.jooq.UniqueKey key = foreignKey.getKey();
List> otherTableFields = key.getFields();
for (int i = 0; i < foreignKey.getFields().size(); i++) {
TableField tableField = foreignKey.getFields().get(i);
//noinspection unchecked
joinCondition = joinCondition.and(tableField.eq((TableField) otherTableFields.get(i)));
}
return joinCondition;
}
private Condition addPartitionToCondition(DataTable table, final Condition inputJooqCondition) {
return table.getVirtualPartition().stream()
.map(fv -> (FieldAndValue
© 2015 - 2025 Weber Informatics LLC | Privacy Policy