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

io.army.criteria.impl.PostgreUtils Maven / Gradle / Ivy

There is a newer version: 0.6.6
Show newest version
package io.army.criteria.impl;

import io.army.criteria.Item;
import io.army.criteria.SubQuery;
import io.army.criteria.UndoneFunction;
import io.army.criteria.impl.inner._FunctionField;
import io.army.criteria.impl.inner._ParensRowSet;
import io.army.criteria.impl.inner._RowSet;
import io.army.criteria.postgre.FuncColumnDefCommaClause;
import io.army.criteria.postgre.PostgreStatement;
import io.army.dialect._Constant;
import io.army.dialect._SqlContext;
import io.army.dialect.postgre.PostgreDialect;

import javax.annotation.Nullable;

import io.army.mapping.MappingType;
import io.army.util._Collections;
import io.army.util._Exceptions;
import io.army.util._StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

abstract class PostgreUtils extends CriteriaUtils {

    private PostgreUtils() {
    }

    /**
     * reference last dialect
     */
    static final PostgreDialect DIALECT = PostgreDialect.POSTGRE15;


    static boolean isUnionQuery(final SubQuery query) {
        _RowSet rowSet = (_RowSet) query;
        while (rowSet instanceof _ParensRowSet) {
            rowSet = ((_ParensRowSet) rowSet).innerRowSet();
        }
        return rowSet instanceof SimpleQueries.UnionSubQuery;
    }


    static  PostgreStatement._FuncColumnDefinitionParensClause undoneFunc(
            final UndoneFunction func, final Function function) {
        return c -> {
            final FuncColumnDefinitionClause clause;
            clause = new FuncColumnDefinitionClause();

            c.accept(clause);

            clause.endClause(); // end clause
            return function.apply(new DoneFunc(func, clause.fieldList, clause.fieldMap));
        };
    }

    static  Function, R> rowsFromUndoneFunc(
            final UndoneFunction func, final Function function) {
        return c -> {
            final FuncColumnDefinitionClause clause;
            clause = new FuncColumnDefinitionClause();

            c.accept(clause);

            clause.endClause(); // end clause
            return function.apply(new DoneFunc(func, clause.fieldList, clause.fieldMap));
        };
    }

    /*-------------------below inner class -------------------*/

    private static final class FuncColumnDefinitionClause
            implements PostgreStatement._FuncColumnDefinitionSpaceClause,
            FuncColumnDefCommaClause {

        private List<_FunctionField> fieldList = _Collections.arrayList();

        private Map fieldMap = _Collections.hashMap();

        private Boolean state;

        private FuncColumnDefinitionClause() {
        }

        @Override
        public FuncColumnDefCommaClause space(String name, MappingType type) {
            if (this.state != null) {
                throw CriteriaUtils.spaceMethodNotFirst();
            }
            this.state = Boolean.TRUE;
            return this.comma(name, type);
        }

        @Override
        public FuncColumnDefCommaClause comma(final @Nullable String name,
                                              @Nullable final MappingType type) {
            final List<_FunctionField> fieldList = this.fieldList;
            if (this.state != Boolean.TRUE || !(fieldList instanceof ArrayList)) {
                throw ContextStack.clearStackAnd(_Exceptions::castCriteriaApi);
            } else if (name == null) {
                throw ContextStack.clearStackAndNullPointer();
            } else if (type == null) {
                throw ContextStack.clearStackAndNullPointer();
            } else if (!_StringUtils.hasText(name)) {
                throw CriteriaUtils.funcFieldNameNoText();
            }
            final Map fieldMap = this.fieldMap;

            final _FunctionField field;
            field = DialectFunctionUtils.funcField(name, type);
            if (fieldMap.putIfAbsent(name, field) != null) {
                throw CriteriaUtils.funcFieldDuplication(name);
            }
            fieldList.add(field);
            return this;
        }


        void endClause() {
            final List<_FunctionField> fieldList = this.fieldList;
            if (!(fieldList instanceof ArrayList)) {
                throw ContextStack.clearStackAnd(_Exceptions::castCriteriaApi);
            } else if (fieldList.size() == 0) {
                throw ContextStack.clearStackAndCriteriaError("you don't add any column definition.");
            }
            this.fieldList = _Collections.unmodifiableList(fieldList);
            this.fieldMap = _Collections.unmodifiableMap(this.fieldMap);
            this.state = Boolean.FALSE;
        }

    }//FuncColumnDefinitionClause


    static final class DoneFunc implements ArmySQLFunction {

        final UndoneFunction funcItem;

        final List<_FunctionField> fieldList;

        final Map fieldMap;

        /**
         * @param fieldList unmodified list
         * @param fieldMap  unmodified map
         */
        private DoneFunc(UndoneFunction funcItem, List<_FunctionField> fieldList,
                         Map fieldMap) {
            this.funcItem = funcItem;
            this.fieldList = fieldList;
            this.fieldMap = fieldMap;

        }

        @Override
        public String name() {
            return this.funcItem.name();
        }

        /**
         * this method for ROWS FROM( ... ) syntax.
         */
        @Override
        public void appendSql(final StringBuilder sqlBuilder, final _SqlContext context) {
            ((ArmySQLFunction) this.funcItem).appendSql(sqlBuilder, context);
            sqlBuilder.append(_Constant.SPACE_AS)
                    .append(_Constant.LEFT_PAREN);
            CriteriaUtils.appendSelfDescribedList(this.fieldList, sqlBuilder, context);
            sqlBuilder.append(_Constant.SPACE_RIGHT_PAREN);
        }


        @Override
        public String toString() {
            final StringBuilder builder = new StringBuilder();
            builder.append(this.funcItem)
                    .append(_Constant.SPACE_AS)
                    .append(_Constant.LEFT_PAREN);

            CriteriaUtils.selfDescribedListToString(this.fieldList, builder);

            return builder.append(_Constant.SPACE_RIGHT_PAREN)
                    .toString();
        }


    }//PostgreDoneFunc


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy