All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.katharsis.jpa.internal.query.QueryBuilder Maven / Gradle / Ivy

There is a newer version: 3.0.2
Show newest version
package io.katharsis.jpa.internal.query;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.katharsis.jpa.internal.meta.MetaAttribute;
import io.katharsis.jpa.internal.meta.MetaAttributeFinder;
import io.katharsis.jpa.internal.meta.MetaAttributePath;
import io.katharsis.jpa.internal.meta.MetaDataObject;
import io.katharsis.jpa.internal.meta.MetaEntity;
import io.katharsis.jpa.internal.meta.MetaKey;
import io.katharsis.jpa.internal.query.backend.JpaQueryBackend;
import io.katharsis.queryspec.FilterSpec;
import io.katharsis.queryspec.IncludeFieldSpec;

public class QueryBuilder {

	private static final String SORT_COLUMN_ALIAS_PREFIX = "__sort";

	private JpaQueryBackend backend;

	private AbstractJpaQueryImpl query;

	private MetaAttributeFinder attributeFinder;

	public QueryBuilder(AbstractJpaQueryImpl query, JpaQueryBackend backend) {
		this.query = query;
		this.backend = backend;

		final ComputedAttributeRegistryImpl virtualAttrs = query.getComputedAttrs();
		this.attributeFinder = new MetaAttributeFinder() {

			@Override
			public MetaAttribute getAttribute(MetaDataObject meta, String name) {
				MetaComputedAttribute attr = virtualAttrs.get(meta, name);
				if (attr != null) {
					return attr;
				}
				return meta.findAttribute(name, true);
			}
		};
	}

	/**
	 * Adds order expressions to selection if in "auto distinct" mode and
	 * the query performs a join or fetch on a relation. In
	 * this case, attributes from referenced entities inlucded in the sort
	 * clause must be added to the select clause as well.
	 * 
	 * @return number of attributes that were needed to compute a distinct
	 */
	protected int applyDistinct() {
		int numAutoSelections = 0;
		boolean distinct;
		if (query.autoDistinct) {
			// distinct for many join/fetches or manual
			// in case of ViewQuery we may not need this here, but we need to do
			// the selection of order-by columns below
			distinct = query.autoDistinct && !query.autoGroupBy && backend.hasManyRootsFetchesOrJoins();
			if (distinct) {
				// we also need to select sorted attributes (for references)
				numAutoSelections = addOrderExpressionsToSelection();
			}
		}
		else {
			distinct = query.distinct;
		}
		if (distinct) {
			backend.distinct();
		}
		return numAutoSelections;
	}

	public Map applySelectionSpec() {
		MetaDataObject meta = query.getMeta();

		Map selectionBindings = new HashMap<>();

		int index = 1;
		
		List includedFields = query.getIncludedFields();
		for (IncludeFieldSpec includedField : includedFields) {
			MetaAttributePath path = meta.resolvePath(includedField.getAttributePath(), attributeFinder);
			E attr = backend.getAttribute(path);
			
			backend.addSelection(attr, path.toString());
			selectionBindings.put(path.toString(), index++);
		}
		return selectionBindings;
	}

	private int addOrderExpressionsToSelection() {
		int numAutoSelections = 0;
		int prefixIndex = 0;
		List newOrderList = new ArrayList<>();
		for (O order : backend.getOrderList()) {
			E expression = backend.getExpression(order);
			if (backend.containsRelation(expression)) {
				backend.addSelection(expression, SORT_COLUMN_ALIAS_PREFIX + prefixIndex++);
				numAutoSelections++;
			}
			newOrderList.add(order);
		}
		backend.setOrder(newOrderList);
		return numAutoSelections;
	}

	protected void applySortSpec() {
		QuerySortBuilder orderBuilder = new QuerySortBuilder<>(query, backend);
		orderBuilder.applySortSpec();
	}

	protected void applyFilterSpec() {
		QueryFilterBuilder predicateBuilder = new QueryFilterBuilder<>(query.getComputedAttrs(), backend, attributeFinder);

		MetaDataObject meta = query.getMeta();
		List filters = query.getFilterSpecs();
		List

predicates = predicateBuilder.filterSpecListToPredicateArray(meta, backend.getRoot(), filters); if (predicates != null && !predicates.isEmpty()) { backend.addPredicate(backend.and(predicates)); } MetaAttribute parentAttr = query.getParentAttr(); if (parentAttr != null) { MetaEntity parentEntity = parentAttr.getParent().asEntity(); MetaKey primaryKey = parentEntity.getPrimaryKey(); MetaAttribute primaryKeyAttr = primaryKey.getUniqueElement(); backend.addParentPredicate(primaryKeyAttr); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy