Skip to content

Commit

Permalink
#2313 Improvements to internals of QueryExecutionModel
Browse files Browse the repository at this point in the history
* Perform lazy instantiation of the parameters map in the builder
* Documentation for all nullable values
* Documentation for methods and classes
  • Loading branch information
homedirectory committed Sep 19, 2024
1 parent 3687815 commit be8ccac
Showing 1 changed file with 88 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
package ua.com.fielden.platform.dao;

import static org.apache.logging.log4j.LogManager.getLogger;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.google.common.collect.ImmutableMap;
import org.apache.logging.log4j.Logger;

import ua.com.fielden.platform.entity.AbstractEntity;
import ua.com.fielden.platform.entity.query.EntityAggregates;
import ua.com.fielden.platform.entity.query.fluent.ValuePreprocessor;
Expand All @@ -17,38 +11,52 @@
import ua.com.fielden.platform.entity.query.model.OrderingModel;
import ua.com.fielden.platform.entity.query.model.QueryModel;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;

import static java.util.Collections.unmodifiableMap;
import static org.apache.logging.log4j.LogManager.getLogger;

public final class QueryExecutionModel<T extends AbstractEntity<?>, Q extends QueryModel<T>> {
private final Q queryModel;
private final OrderingModel orderModel;
private final fetch<T> fetchModel;
private final Map<String, Object> paramValues;
private final @Nullable OrderingModel orderModel;
private final @Nullable fetch<T> fetchModel;
/** Immutable map of parameters for the query. */
private final Map<String, /*@Nullable*/ Object> paramValues;
private final boolean lightweight;
private final ValuePreprocessor valuePreprocessor = new ValuePreprocessor();

private static final ValuePreprocessor valuePreprocessor = new ValuePreprocessor();
private static final Logger logger = getLogger(QueryExecutionModel.class);

protected QueryExecutionModel() {
// Supposedly used for serialisation.
QueryExecutionModel() {
queryModel = null;
orderModel = null;
fetchModel = null;
paramValues = null;
lightweight = false;
}

protected QueryExecutionModel(final Q queryModel, final OrderingModel orderModel, final fetch<T> fetchModel, final Map<String, Object> paramValues, final boolean lightweight) {

/**
* Private constructor that doesn't perform defensive copying.
* <b>Do not increase its visibility!</b>
*/
private QueryExecutionModel(final Q queryModel,
final @Nullable OrderingModel orderModel,
final @Nullable fetch<T> fetchModel,
final Map<String, Object> paramValues,
final boolean lightweight)
{
this.queryModel = queryModel;
this.orderModel = orderModel;
this.fetchModel = fetchModel;
this.paramValues = new HashMap<>();
this.paramValues.putAll(paramValues);
this.paramValues = paramValues;
this.lightweight = lightweight;
}

private QueryExecutionModel(final Builder<T, Q> builder) {
queryModel = builder.queryModel;
orderModel = builder.orderModel;
fetchModel = builder.fetchModel;
paramValues = preprocessParamValues(builder.paramValues);
lightweight = builder.lightweight;
this(builder.queryModel, builder.orderModel, builder.fetchModel, preprocessParamValues(builder.parameters()), builder.lightweight);
logger.debug(this);
}

Expand All @@ -74,12 +82,15 @@ public String toString() {
.toString();
}

private Map<String, Object> preprocessParamValues(final Map<String, Object> paramValues) {
final Map<String, Object> result = new HashMap<>();
for (final Map.Entry<String, Object> entry : paramValues.entrySet()) {
result.put(entry.getKey(), valuePreprocessor.apply(entry.getValue()));
private static Map<String, Object> preprocessParamValues(final Map<String, Object> paramValues) {
if (paramValues.isEmpty()) {
return ImmutableMap.of();
}
else {
final var result = new HashMap<String, Object>(paramValues.size(), 1);
paramValues.forEach((key, value) -> result.put(key, valuePreprocessor.apply(value)));
return unmodifiableMap(result);
}
return result;
}

public Q getQueryModel() {
Expand All @@ -95,7 +106,7 @@ public fetch<T> getFetchModel() {
}

public Map<String, Object> getParamValues() {
return Collections.unmodifiableMap(paramValues);
return paramValues;
}

public boolean isLightweight() {
Expand All @@ -113,12 +124,25 @@ public static Builder<EntityAggregates, AggregatedResultQueryModel> from(final A
public QueryExecutionModel<T, Q> lightweight() {
return new QueryExecutionModel<>(this.queryModel, this.orderModel, this.fetchModel, this.paramValues, true);
}


/**
* Builds a {@link QueryExecutionModel}.
* <p>
* This builder is <b>mutable</b> and must not be modified after {@link #model()} has been called.
*/
public static class Builder<T extends AbstractEntity<?>, Q extends QueryModel<T>> {
private Q queryModel;
private OrderingModel orderModel;
private fetch<T> fetchModel;
private Map<String, Object> paramValues = new HashMap<>();

private final Q queryModel;
private @Nullable OrderingModel orderModel;
private @Nullable fetch<T> fetchModel;

/** Don't access directly!
* @see #addParam(String, Object)
* @see #addParams(Map)
* @see #parameters()
*/
private @Nullable Map<String, Object> paramValues;

private boolean lightweight = false;

private Builder(final EntityResultQueryModel<T> queryModel) {
Expand All @@ -129,6 +153,31 @@ private Builder(final AggregatedResultQueryModel queryModel) {
this.queryModel = (Q) queryModel;
}

private void addParam(final String name, final Object value) {
if (paramValues == null) {
paramValues = new HashMap<>(5);
}
paramValues.put(name, value);
}

private void addParams(final Map<String, /*@Nullable*/ Object> params) {
if (paramValues == null) {
paramValues = new HashMap<>(params);
}
else {
paramValues.putAll(params);
}
}

Map<String, Object> parameters() {
return paramValues == null ? ImmutableMap.of() : unmodifiableMap(paramValues);
}

/**
* Builds a QEM and returns it.
* <p>
* This is a terminal method, and this builder must not be modified after it has been called.
*/
public QueryExecutionModel<T, Q> model() {
return new QueryExecutionModel<>(this);
}
Expand All @@ -144,12 +193,15 @@ public Builder<T, Q> with(final fetch<T> val) {
}

public Builder<T, Q> with(final Map<String, Object> val) {
paramValues.putAll(val);
addParams(val);
return this;
}

public Builder<T, Q> with(final String name, final Object value) {
paramValues.put(name, value);
/**
* Adds a parameter for the query.
*/
public Builder<T, Q> with(final String name, final @Nullable Object value) {
addParam(name, value);
return this;
}

Expand Down Expand Up @@ -214,4 +266,4 @@ public boolean equals(final Object obj) {
}
return true;
}
}
}

0 comments on commit be8ccac

Please sign in to comment.