com.kenshoo.pl.entity.internal.EntitiesFetcher 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;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.kenshoo.jooq.DataTable;
import com.kenshoo.jooq.QueryExtension;
import com.kenshoo.jooq.TempTableHelper;
import com.kenshoo.jooq.TempTableResource;
import com.kenshoo.pl.data.ImpersonatorTable;
import com.kenshoo.pl.entity.UniqueKey;
import com.kenshoo.pl.entity.*;
import com.kenshoo.pl.entity.internal.fetch.*;
import org.jooq.*;
import org.jooq.lambda.Seq;
import java.util.*;
import java.util.function.Consumer;
import static com.kenshoo.pl.entity.Feature.FetchMany;
import static org.jooq.lambda.Seq.seq;
public class EntitiesFetcher {
private final DSLContext dslContext;
private final FeatureSet features;
private final OldEntityFetcher oldEntityFetcher;
public EntitiesFetcher(DSLContext dslContext) {
this(dslContext, FeatureSet.EMPTY);
}
public EntitiesFetcher(DSLContext dslContext, FeatureSet features) {
this.dslContext = dslContext;
this.features = features;
this.oldEntityFetcher = new OldEntityFetcher(dslContext);
}
public > Map, Entity> fetchEntitiesByIds(final Collection extends Identifier> ids,
final EntityField, ?>... fieldsToFetchArgs) {
return fetchEntitiesByIds(ids, ImmutableList.copyOf(fieldsToFetchArgs));
}
public > Map, Entity> fetchEntitiesByIds(final Collection extends Identifier> ids,
final Collection extends EntityField, ?>> fieldsToFetch) {
if (!features.isEnabled(FetchMany)) {
return oldEntityFetcher.fetchEntitiesByIds(ids, fieldsToFetch);
}
if (ids.isEmpty()) {
return Collections.emptyMap();
}
final UniqueKey uniqueKey = ids.iterator().next().getUniqueKey();
final AliasedKey aliasedKey = new AliasedKey<>(uniqueKey);
return fetchEntities(uniqueKey.getEntityType().getPrimaryTable(), aliasedKey, fieldsToFetch, query -> query.whereIdsIn(ids));
}
public List fetch(final EntityType> entityType,
final PLCondition plCondition,
final EntityField, ?>... fieldsToFetch) {
return oldEntityFetcher.fetch(entityType, plCondition, fieldsToFetch);
}
public List fetch(final EntityType> entityType,
final Collection extends Identifier>> ids,
final PLCondition plCondition,
final EntityField, ?>... fieldsToFetch) {
return oldEntityFetcher.fetch(entityType, ids, plCondition, fieldsToFetch);
}
public > Map, Entity> fetchEntitiesByForeignKeys(E entityType, UniqueKey foreignUniqueKey, Collection extends Identifier> keys, Collection> fieldsToFetch) {
if (!features.isEnabled(FetchMany)) {
return oldEntityFetcher.fetchEntitiesByForeignKeys(entityType, foreignUniqueKey, keys, fieldsToFetch);
}
try (final TempTableResource foreignKeysTable = createForeignKeysTable(entityType.getPrimaryTable(), foreignUniqueKey, keys)) {
final AliasedKey aliasedKey = new AliasedKey<>(foreignUniqueKey, foreignKeysTable);
final DataTable startingTable = foreignKeysTable.getTable();
return fetchEntities(startingTable, aliasedKey, fieldsToFetch, noMoreConditions());
}
}
private > Map, Entity> fetchEntities(
final DataTable startingTable,
final AliasedKey aliasedKey,
final Collection extends EntityField, ?>> fieldsToFetch,
Consumer> queryModifier
) {
final ExecutionPlan executionPlan = new ExecutionPlan(startingTable, fieldsToFetch);
final ExecutionPlan.OneToOnePlan oneToOnePlan = executionPlan.getOneToOnePlan();
final QueryBuilder mainQueryBuilder = new QueryBuilder(dslContext).selecting(selectFieldsOf(oneToOnePlan.getFields(), aliasedKey))
.from(startingTable)
.innerJoin(oneToOnePlan.getPaths())
.leftJoin(oneToOnePlan.getSecondaryTableRelations());
queryModifier.accept(mainQueryBuilder);
final Map, Entity> entities = fetchMainEntities(aliasedKey, oneToOnePlan, mainQueryBuilder);
executionPlan.getManyToOnePlans().forEach(plan -> {
final QueryBuilder subQueryBuilder = new QueryBuilder(dslContext).selecting(selectFieldsOf(plan.getFields(), aliasedKey))
.from(startingTable)
.innerJoin(plan.getPath());
queryModifier.accept(subQueryBuilder);
fetchAndPopulateSubEntities(aliasedKey, entities, plan, subQueryBuilder);
});
return entities;
}
public , PE extends PartialEntity, ID extends Identifier> Map fetchPartialEntities(E entityType, Collection keys, final Class entityIface) {
return oldEntityFetcher.fetchPartialEntities(entityType, keys, entityIface);
}
public , PE extends PartialEntity> List fetchByCondition(E entityType, Condition condition, final Class entityIface) {
return oldEntityFetcher.fetchByCondition(entityType, condition, entityIface);
}
private , SUB extends EntityType> void fetchAndPopulateSubEntities(AliasedKey aliasedKey, Map, Entity> entities, ExecutionPlan.ManyToOnePlan plan, QueryBuilder queryBuilder) {
try (QueryExtension> queryExtender = queryBuilder.build()) {
Map, List>> multiValuesMap = fetchMultiValuesMap(queryExtender.getQuery(), aliasedKey, plan.getFields());
multiValuesMap.forEach((Identifier id, List> multiValues) -> {
final SUB subEntityType = entityTypeOf(plan.getFields());
((EntityImpl) entities.get(id)).add(subEntityType, multiValues);
});
}
}
private > Map, Entity> fetchMainEntities(AliasedKey aliasedKey, ExecutionPlan.OneToOnePlan oneToOnePlan, QueryBuilder queryBuilder) {
try (QueryExtension> queryExtender = queryBuilder.build()) {
return fetchEntitiesMap(queryExtender.getQuery(), aliasedKey, oneToOnePlan.getFields());
}
}
private > Map, Entity> fetchEntitiesMap(ResultQuery query, AliasedKey aliasedKey, List extends EntityField, ?>> fields) {
return query.fetchMap(record -> RecordReader.createKey(record, aliasedKey), record -> RecordReader.createEntity(record, fields));
}
private , SUB extends EntityType> Map, List>> fetchMultiValuesMap(ResultQuery query, AliasedKey aliasedKey, List extends EntityField> fields) {
final Map, List>> multiValuesMap = new HashMap<>();
query.fetchInto(record -> {
Identifier key = RecordReader.createKey(record, aliasedKey);
multiValuesMap.computeIfAbsent(key, k -> Lists.newArrayList());
multiValuesMap.get(key).add(RecordReader.createFieldsValueMap(record, fields));
});
return multiValuesMap;
}
public > TempTableResource createForeignKeysTable(final DataTable primaryTable, final UniqueKey foreignUniqueKey, final Collection extends Identifier> keys) {
ImpersonatorTable impersonatorTable = new ImpersonatorTable(primaryTable);
foreignUniqueKey.getTableFields().forEach(impersonatorTable::createField);
return TempTableHelper.tempInMemoryTable(dslContext, impersonatorTable, batchBindStep -> {
for (Identifier key : keys) {
EntityField[] keyFields = foreignUniqueKey.getFields();
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy