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

com.blazebit.persistence.impl.WindowBuilderImpl Maven / Gradle / Ivy

/*
 * Copyright 2014 - 2020 Blazebit.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.blazebit.persistence.impl;

import com.blazebit.persistence.CaseWhenStarterBuilder;
import com.blazebit.persistence.FullQueryBuilder;
import com.blazebit.persistence.MultipleSubqueryInitiator;
import com.blazebit.persistence.RestrictionBuilder;
import com.blazebit.persistence.SimpleCaseWhenStarterBuilder;
import com.blazebit.persistence.SubqueryBuilder;
import com.blazebit.persistence.SubqueryInitiator;
import com.blazebit.persistence.WhereBuilder;
import com.blazebit.persistence.WhereOrBuilder;
import com.blazebit.persistence.WindowBuilder;
import com.blazebit.persistence.WindowFrameBetweenBuilder;
import com.blazebit.persistence.WindowFrameBuilder;
import com.blazebit.persistence.WindowFrameExclusionBuilder;
import com.blazebit.persistence.impl.builder.predicate.WhereOrBuilderImpl;
import com.blazebit.persistence.parser.expression.Expression;
import com.blazebit.persistence.parser.expression.ExpressionFactory;
import com.blazebit.persistence.parser.expression.OrderByItem;
import com.blazebit.persistence.parser.expression.WindowDefinition;
import com.blazebit.persistence.parser.expression.WindowFrameExclusionType;
import com.blazebit.persistence.parser.expression.WindowFrameMode;
import com.blazebit.persistence.parser.expression.WindowFramePositionType;
import com.blazebit.persistence.parser.predicate.Predicate;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Christian Beikov
 * @since 1.4.0
 */
public class WindowBuilderImpl extends PredicateManager> implements WindowBuilder, WhereBuilder>, WindowFrameBuilder, WindowFrameExclusionBuilder, WindowFrameBetweenBuilder {

    private final WindowManager windowManager;
    private final T result;
    private final String name;

    private final List partitionExpressions = new ArrayList<>();
    private final List orderByExpressions = new ArrayList<>();

    private String baseWindowName;
    private WindowFrameMode frameMode;
    private WindowFramePositionType frameStartType;
    private Expression frameStartExpression;
    private WindowFramePositionType frameEndType;
    private Expression frameEndExpression;
    private WindowFrameExclusionType frameExclusionType;

    public WindowBuilderImpl(ResolvingQueryGenerator queryGenerator, ParameterManager parameterManager, SubqueryInitiatorFactory subqueryInitFactory, ExpressionFactory expressionFactory, WindowManager windowManager, T result, String name) {
        super(queryGenerator, parameterManager, subqueryInitFactory, expressionFactory);
        this.windowManager = windowManager;
        this.result = result;
        this.name = name;
    }

    @Override
    public ClauseType getClauseType() {
        return ClauseType.WINDOW;
    }

    @Override
    protected String getClauseName() {
        return "WINDOW";
    }

    @Override
    public  & WindowBuilder> X filter() {
        return (X) this;
    }

    @Override
    public WindowBuilder partitionBy(String... partitionExpressions) {
        for (String partitionExpression : partitionExpressions) {
            Expression expr = expressionFactory.createSimpleExpression(partitionExpression, false);
            parameterManager.collectParameterRegistrations(expr, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
            this.partitionExpressions.add(expr);
        }

        return this;
    }

    @Override
    public WindowBuilder partitionBy(String partitionExpression) {
        Expression expr = expressionFactory.createSimpleExpression(partitionExpression, false);
        parameterManager.collectParameterRegistrations(expr, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
        partitionExpressions.add(expr);
        return this;
    }

    @Override
    public WindowFrameBuilder rows() {
        this.frameMode = WindowFrameMode.ROWS;
        return this;
    }

    @Override
    public WindowFrameBuilder range() {
        this.frameMode = WindowFrameMode.RANGE;
        return this;
    }

    @Override
    public WindowFrameBuilder groups() {
        this.frameMode = WindowFrameMode.GROUPS;
        return this;
    }

    public WindowBuilder orderBy(String expression, boolean ascending) {
        return orderBy(expression, ascending, false);
    }

    @Override
    public WindowBuilder orderBy(String expression, boolean ascending, boolean nullFirst) {
        Expression expr = expressionFactory.createSimpleExpression(expression, false);
        parameterManager.collectParameterRegistrations(expr, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
        orderByExpressions.add(new OrderByItem(ascending, nullFirst, expr));
        return this;
    }

    @Override
    public WindowBuilder orderByAsc(String expression) {
        return orderBy(expression, true, false);
    }

    @Override
    public WindowBuilder orderByAsc(String expression, boolean nullFirst) {
        return orderBy(expression, true, nullFirst);
    }

    @Override
    public WindowBuilder orderByDesc(String expression) {
        return orderBy(expression, false, false);
    }

    @Override
    public WindowBuilder orderByDesc(String expression, boolean nullFirst) {
        return orderBy(expression, false, nullFirst);
    }

    @Override
    public WindowFrameBetweenBuilder betweenUnboundedPreceding() {
        this.frameStartType = WindowFramePositionType.UNBOUNDED_PRECEDING;
        return this;
    }

    @Override
    public WindowFrameBetweenBuilder betweenPreceding(String expression) {
        this.frameStartExpression = expressionFactory.createSimpleExpression(expression, false);
        parameterManager.collectParameterRegistrations(frameStartExpression, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
        this.frameStartType = WindowFramePositionType.BOUNDED_PRECEDING;
        return this;
    }

    @Override
    public WindowFrameBetweenBuilder betweenFollowing(String expression) {
        this.frameStartExpression = expressionFactory.createSimpleExpression(expression, false);
        parameterManager.collectParameterRegistrations(frameStartExpression, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
        this.frameStartType = WindowFramePositionType.BOUNDED_FOLLOWING;
        return this;
    }

    @Override
    public WindowFrameBetweenBuilder betweenCurrentRow() {
        this.frameStartType = WindowFramePositionType.CURRENT_ROW;
        return this;
    }

    @Override
    public WindowFrameExclusionBuilder unboundedPreceding() {
        this.frameStartType = WindowFramePositionType.UNBOUNDED_PRECEDING;
        return this;
    }

    @Override
    public WindowFrameExclusionBuilder preceding(String expression) {
        this.frameStartExpression = expressionFactory.createSimpleExpression(expression, false);
        parameterManager.collectParameterRegistrations(frameStartExpression, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
        this.frameStartType = WindowFramePositionType.BOUNDED_PRECEDING;
        return this;
    }

    @Override
    public WindowFrameExclusionBuilder currentRow() {
        this.frameStartType = WindowFramePositionType.CURRENT_ROW;
        return this;
    }

    @Override
    public WindowFrameExclusionBuilder andUnboundedFollowing() {
        this.frameEndType = WindowFramePositionType.UNBOUNDED_FOLLOWING;
        return this;
    }

    @Override
    public WindowFrameExclusionBuilder andPreceding(String expression) {
        this.frameEndExpression = expressionFactory.createSimpleExpression(expression, false);
        parameterManager.collectParameterRegistrations(frameEndExpression, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
        this.frameEndType = WindowFramePositionType.BOUNDED_PRECEDING;
        return this;
    }

    @Override
    public WindowFrameExclusionBuilder andFollowing(String expression) {
        this.frameEndExpression = expressionFactory.createSimpleExpression(expression, false);
        parameterManager.collectParameterRegistrations(frameEndExpression, ClauseType.WINDOW, subqueryInitFactory.getQueryBuilder());
        this.frameEndType = WindowFramePositionType.BOUNDED_FOLLOWING;
        return this;
    }

    @Override
    public WindowFrameExclusionBuilder andCurrentRow() {
        this.frameEndType = WindowFramePositionType.CURRENT_ROW;
        return this;
    }

    @Override
    public T excludeNoOthers() {
        // The default
        return end();
    }

    @Override
    public T excludeCurrentRow() {
        this.frameExclusionType = WindowFrameExclusionType.EXCLUDE_CURRENT_ROW;
        return end();
    }

    @Override
    public T excludeGroup() {
        this.frameExclusionType = WindowFrameExclusionType.EXCLUDE_GROUP;
        return end();
    }

    @Override
    public T excludeTies() {
        this.frameExclusionType = WindowFrameExclusionType.EXCLUDE_TIES;
        return end();
    }

    @Override
    public T end() {
        WindowFrameMode frameMode = this.frameMode;
        WindowFramePositionType frameStartType = this.frameStartType;
        WindowFramePositionType frameEndType = this.frameEndType;

        // The default
        if (frameMode == WindowFrameMode.RANGE && frameEndExpression == null && frameEndType == WindowFramePositionType.CURRENT_ROW) {
            frameEndType = null;
        }

        // The default
        if (frameMode == WindowFrameMode.RANGE && frameEndType == null && frameStartExpression == null && frameStartType == WindowFramePositionType.UNBOUNDED_PRECEDING) {
            frameStartType = null;
        }

        // The default
        if (frameMode == WindowFrameMode.RANGE && frameStartType == null && frameEndType == null) {
            frameMode = null;
        }

        windowManager.onBuilderEnded(name, new WindowDefinition(
                baseWindowName,
                partitionExpressions,
                orderByExpressions,
                rootPredicate.getPredicate(),
                frameMode,
                frameStartType,
                frameStartExpression,
                frameEndType,
                frameEndExpression,
                frameExclusionType
        ));
        return result;
    }

    /*
     * Where methods
     */
    public RestrictionBuilder> where(String expression) {
        Expression expr = expressionFactory.createSimpleExpression(expression, false);
        return restrict(this, expr);
    }

    public CaseWhenStarterBuilder>> whereCase() {
        return restrictCase(this);
    }

    public SimpleCaseWhenStarterBuilder>> whereSimpleCase(String expression) {
        return restrictSimpleCase(this, expressionFactory.createSimpleExpression(expression, false));
    }

    public WhereOrBuilder> whereOr() {
        return rootPredicate.startBuilder(new WhereOrBuilderImpl>(this, rootPredicate, subqueryInitFactory, expressionFactory, parameterManager));
    }

    @SuppressWarnings("unchecked")
    public SubqueryInitiator> whereExists() {
        return restrictExists(this);
    }

    @SuppressWarnings("unchecked")
    public SubqueryInitiator> whereNotExists() {
        return restrictNotExists(this);
    }

    @SuppressWarnings("unchecked")
    public SubqueryBuilder> whereExists(FullQueryBuilder criteriaBuilder) {
        return restrictExists(this, criteriaBuilder);
    }

    @SuppressWarnings("unchecked")
    public SubqueryBuilder> whereNotExists(FullQueryBuilder criteriaBuilder) {
        return restrictNotExists(this, criteriaBuilder);
    }

    public SubqueryInitiator>> whereSubquery() {
        return restrict(this);
    }

    public SubqueryInitiator>> whereSubquery(String subqueryAlias, String expression) {
        return restrict(this, subqueryAlias, expression);
    }

    public MultipleSubqueryInitiator>> whereSubqueries(String expression) {
        return restrictSubqueries(this, expression);
    }

    public SubqueryBuilder>> whereSubquery(FullQueryBuilder criteriaBuilder) {
        return restrict(this, criteriaBuilder);
    }

    public SubqueryBuilder>> whereSubquery(String subqueryAlias, String expression, FullQueryBuilder criteriaBuilder) {
        return restrict(this, subqueryAlias, expression, criteriaBuilder);
    }

    @SuppressWarnings("unchecked")
    public WindowBuilderImpl whereExpression(String expression) {
        Predicate predicate = expressionFactory.createBooleanExpression(expression, false);
        restrictExpression(predicate);
        return this;
    }

    @SuppressWarnings("unchecked")
    public MultipleSubqueryInitiator> whereExpressionSubqueries(String expression) {
        Predicate predicate = expressionFactory.createBooleanExpression(expression, true);
        return restrictExpressionSubqueries(this, predicate);
    }

    @SuppressWarnings("unchecked")
    public WindowBuilderImpl setWhereExpression(String expression) {
        Predicate predicate = expressionFactory.createBooleanExpression(expression, false);
        restrictSetExpression(predicate);
        return this;
    }

    @SuppressWarnings("unchecked")
    public MultipleSubqueryInitiator> setWhereExpressionSubqueries(String expression) {
        Predicate predicate = expressionFactory.createBooleanExpression(expression, true);
        return restrictSetExpressionSubqueries(this, predicate);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy