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

paa.coder.noodleCriteriaBuilder.queryBuilder.SampleQuery Maven / Gradle / Ivy

package paa.coder.noodleCriteriaBuilder.queryBuilder;

import org.hibernate.query.Query;
import org.hibernate.query.criteria.internal.path.SingularAttributePath;
import paa.coder.noodleCriteriaBuilder.NoodleFactory;
import paa.coder.noodleCriteriaBuilder.interfaces.NoodlePredicate;
import paa.coder.noodleCriteriaBuilder.interfaces.NoodleQuery;
import paa.coder.noodleCriteriaBuilder.queryBuilder.expressions.OrderBuilder;
import paa.coder.noodleCriteriaBuilder.queryBuilder.expressions.SelectStore;
import paa.coder.noodleCriteriaBuilder.queryBuilder.specifications.NoodleSpecificationBuilder;

import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class SampleQuery extends NoodleAbstractQuery.Select implements NoodleQuery {

    protected final Class from;
    protected final OrderBuilder orderBuilder;

    public SampleQuery(Class from, NoodleFactory noodleFactory){
        super(noodleFactory);
        this.orderBuilder = new OrderBuilder();
        this.from = from;
    }

    public SampleQuery where(Function fPred){
        super.where(fPred);
        return this;
    }

    public SampleQuery order(Consumer fPred){
        fPred.accept(orderBuilder);
        return this;
    }

    public MultiSelectQuery select(Consumer action){
        MultiSelectQuery m = initMulti();
        m.select(action);
        return m;
    }

    @Override
    public SampleQuery itDistinct(Boolean d){
        super.itDistinct(d);
        return this;
    }

    public MultiSelectQuery having(Function action){
        MultiSelectQuery m = initMulti();
        m.having(action);
        return m;
    }

    public MultiSelectQuery group(Consumer action){
        return group(action, false);
    }

    public MultiSelectQuery group(Consumer action, Boolean addToSelect){
        MultiSelectQuery m = initMulti();
        m.group(action, addToSelect);
        return m;
    }

    private MultiSelectQuery initMulti(){
        return new MultiSelectQuery<>(from, where, noodleFactory,orderBuilder);
    }

    public Stream stream(Integer count, Integer offset){
        TypedQuery query;

        if(!noodleFactory.fetchStore().getOneToManyFetches(from).isEmpty() || !noodleFactory.fetchStore().getManyToOneFetches(from).isEmpty()){
            query = getByIds(count, offset);
        }else{
            query = query();
            Optional.ofNullable(count).ifPresent(i -> {
                query.setMaxResults(i);
                Optional.ofNullable(offset).ifPresent(query::setFirstResult);
            });
        }

        return query.getResultStream();
    }

    public Query query(){
        return noodleFactory.getSession().createQuery(criteriaQuery());
    }

    public CriteriaQuery criteriaQuery(String alias){
        CriteriaBuilder criteriaBuilder = noodleFactory.getSession().getCriteriaBuilder();
        CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(from);
        Root root = criteriaQuery.from(from);
        root.alias(alias);

        noodleFactory.fetchStore().getManyToOneFetches(from).forEach(i -> root.fetch(i, JoinType.INNER));
        noodleFactory.fetchStore().getOneToManyFetches(from).forEach(i -> root.fetch(i, JoinType.INNER));

        criteriaQuery.select(root);
        criteriaQuery.orderBy(orderBuilder.apply(pathFinder(root), criteriaQuery, criteriaBuilder));
        build(root, criteriaQuery, criteriaBuilder);
        return criteriaQuery;
    }

    public Query getByIds(Integer count, Integer offset){

        Query idsQuery = getIdsQuery();
        Optional.ofNullable(count).ifPresent(i -> {
            idsQuery.setMaxResults(i);
            Optional.ofNullable(offset).ifPresent(idsQuery::setFirstResult);
        });
        List ids = idsQuery.getResultList();

        CriteriaQuery queryResult = noodleFactory.getSession().getCriteriaBuilder().createQuery(from);
        Root rootResult = queryResult.from(from);

        noodleFactory.fetchStore().getManyToOneFetches(from).forEach(i -> rootResult.fetch(i,JoinType.LEFT));
        noodleFactory.fetchStore().getOneToManyFetches(from).forEach(i -> rootResult.fetch(i,JoinType.LEFT));

        queryResult.select(rootResult);

        CriteriaBuilder cb = noodleFactory.getSession().getCriteriaBuilder();

        queryResult.orderBy(orderBuilder.apply(pathFinder(rootResult), queryResult, cb));

        Predicate[] predicatesOr = ids.stream().map(i -> {
            Predicate[] predicates = IntStream.range(0, i.getElements().size()).mapToObj(x -> {
                SingularAttributePath tupleElement = (SingularAttributePath) i.getElements().get(x);
                return cb.equal(tupleElement, i.get(x));
            }).toArray(Predicate[]::new);
            if(predicates.length > 0){
                return cb.and(predicates);
            }
            return null;
        }).filter(Objects::nonNull).toArray(Predicate[]::new);

        if(predicatesOr.length > 0){
            queryResult.where(cb.or(predicatesOr));
        }else{
            queryResult.where(cb.notEqual(cb.literal(1), cb.literal(1)));
        }

        return noodleFactory.getSession().createQuery(queryResult);
    }

    public Query getIdsQuery(){
        CriteriaBuilder cb = noodleFactory.getSession().getCriteriaBuilder();
        CriteriaQuery criteriaQuery = cb.createQuery(Tuple.class);

        Root root = criteriaQuery.from(from);
        List> collect = noodleFactory.fetchStore().getIds(from).stream().map(root::get).collect(Collectors.toList());
        criteriaQuery.multiselect(collect);

        build(root, criteriaQuery, cb);
        criteriaQuery.orderBy(orderBuilder.apply(pathFinder(root), criteriaQuery, cb));
        return noodleFactory.getSession().createQuery(criteriaQuery);
    }

    public CriteriaQuery criteriaQuery(){
        return criteriaQuery(null);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy