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

org.dbflute.cbean.chelper.HpSLSFunction Maven / Gradle / Ivy

/*
 * Copyright 2014-2020 the original author or authors.
 *
 * 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 org.dbflute.cbean.chelper;

import org.dbflute.bhv.exception.BehaviorExceptionThrower;
import org.dbflute.cbean.ConditionBean;
import org.dbflute.cbean.coption.FunctionFilterOptionCall;
import org.dbflute.cbean.coption.ScalarSelectOption;
import org.dbflute.cbean.exception.ConditionBeanExceptionThrower;
import org.dbflute.cbean.scoping.ScalarQuery;
import org.dbflute.cbean.sqlclause.SqlClause;
import org.dbflute.cbean.sqlclause.clause.SelectClauseType;
import org.dbflute.dbmeta.info.ColumnInfo;
import org.dbflute.optional.OptionalScalar;

/**
 * The function for scalar select. 
 * @param  The type of condition-bean.
 * @param  The type of result for scalar select
 * @author jflute
 */
public class HpSLSFunction {

    // ===================================================================================
    //                                                                           Attribute
    //                                                                           =========
    /** The condition-bean for scalar select. (NotNull) */
    protected final CB _conditionBean;

    /** The condition-bean for scalar select. (NotNull) */
    protected final Class _resultType;

    /** The executor of scalar select. (NotNull) */
    protected final HpSLSExecutor _executor;

    // ===================================================================================
    //                                                                         Constructor
    //                                                                         ===========
    /**
     * @param conditionBean The condition-bean initialized only for scalar select. (NotNull)
     * @param resultType The type as result. (NotNull)
     * @param executor The executor of scalar select with select clause type. (NotNull)
     */
    public HpSLSFunction(CB conditionBean, Class resultType, HpSLSExecutor executor) {
        _conditionBean = conditionBean;
        _resultType = resultType;
        _executor = executor;
    }

    // ===================================================================================
    //                                                                            Function
    //                                                                            ========
    // -----------------------------------------------------
    //                                                 Count
    //                                                 -----
    /**
     * Select the count value. 
* You can also get same result by selectCount(cb) method. *
     * memberBhv.scalarSelect(Integer.class).count(cb -> {
     *     cb.specify().columnMemberId(); // the required specification of (basically) primary key column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * });
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @return The count value calculated by function. (NotNull) */ public RESULT count(ScalarQuery cbLambda) { return doCount(cbLambda, null); } /** * Select the count value with function conversion option. *
     * memberBhv.scalarSelect(Integer.class).count(cb -> {
     *     cb.specify().columnMemberId(); // the required specification of (basically) primary key column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * }, op -> op.coalesce(0));
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @param opLambda The callback for option of scalar. (NotNull) * @return The count value calculated by function. (NotNull) */ public RESULT count(ScalarQuery cbLambda, FunctionFilterOptionCall opLambda) { return doCount(cbLambda, prepareOption(opLambda)); } protected RESULT doCount(ScalarQuery scalarQuery, ScalarSelectOption option) { assertScalarQuery(scalarQuery); return exec(scalarQuery, SelectClauseType.UNIQUE_COUNT, option); } // ----------------------------------------------------- // Count Distict // ------------- /** * Select the count-distinct value.
* You can also get same result by selectCount(cb) method. *
     * memberBhv.scalarSelect(Integer.class).countDistinct(cb -> {
     *     cb.specify().columnMemberId(); // the required specification of (basically) primary key column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * });
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @return The count-distinct value calculated by function. (NotNull) */ public RESULT countDistinct(ScalarQuery cbLambda) { return doCountDistinct(cbLambda, null); } /** * Select the count-distinct value with function conversion option. *
     * memberBhv.scalarSelect(Integer.class).countDistinct(cb -> {
     *     cb.specify().columnMemberId(); // the required specification of (basically) primary key column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * }, op -> op.coalesce(0));
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @param opLambda The callback for option of scalar. (NotNull) * @return The count-distinct value calculated by function. (NotNull) */ public RESULT countDistinct(ScalarQuery cbLambda, FunctionFilterOptionCall opLambda) { return doCountDistinct(cbLambda, prepareOption(opLambda)); } protected RESULT doCountDistinct(ScalarQuery scalarQuery, ScalarSelectOption option) { assertScalarQuery(scalarQuery); return exec(scalarQuery, SelectClauseType.COUNT_DISTINCT, option); } // ----------------------------------------------------- // Maximum // ------- /** * Select the maximum value. *
     * memberBhv.scalarSelect(Date.class).max(cb -> {
     *     cb.specify().columnBirthdate(); // the required specification of target column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * });
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @return The optional scalar for maximum value calculated by function. (NullAllowed) */ public OptionalScalar max(ScalarQuery cbLambda) { return doMax(cbLambda, null); } /** * Select the maximum value with function conversion option. *
     * memberBhv.scalarSelect(Date.class).max(cb -> {
     *     cb.specify().columnBirthdate(); // the required specification of target column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * }, op -> op.coalesce(0));
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @param opLambda The callback for option of scalar. (NotNull) * @return The optional scalar for maximum value calculated by function. (NullAllowed: or NotNull if you use coalesce by option) */ public OptionalScalar max(ScalarQuery cbLambda, FunctionFilterOptionCall opLambda) { return doMax(cbLambda, prepareOption(opLambda)); } protected OptionalScalar doMax(ScalarQuery scalarQuery, ScalarSelectOption option) { assertScalarQuery(scalarQuery); return optionalOf("max", exec(scalarQuery, SelectClauseType.MAX, option)); } // ----------------------------------------------------- // Minimum // ------- /** * Select the minimum value. *
     * memberBhv.scalarSelect(Date.class).min(cb -> {
     *     cb.specify().columnBirthdate(); // the required specification of target column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * });
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @return The optional scalar for minimum value calculated by function. (NullAllowed) */ public OptionalScalar min(ScalarQuery cbLambda) { return doMin(cbLambda, null); } /** * Select the minimum value with function conversion option. *
     * memberBhv.scalarSelect(Date.class).min(cb -> {
     *     cb.specify().columnBirthdate(); // the required specification of target column
     *     cb.query().setMemberStatusCode_Equal_Formalized(); // query as you like it
     * }, op -> op.coalesce(0));
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @param opLambda The callback for option of scalar. (NotNull) * @return The optional scalar for minimum value calculated by function. (NullAllowed: or NotNull if you use coalesce by option) */ public OptionalScalar min(ScalarQuery cbLambda, FunctionFilterOptionCall opLambda) { return doMin(cbLambda, prepareOption(opLambda)); } protected OptionalScalar doMin(ScalarQuery scalarQuery, ScalarSelectOption option) { assertScalarQuery(scalarQuery); return optionalOf("min", exec(scalarQuery, SelectClauseType.MIN, option)); } // ----------------------------------------------------- // Summary // ------- /** * Select the summary value. *
     * purchaseBhv.scalarSelect(Integer.class).sum(cb -> {
     *     cb.specify().columnPurchaseCount(); // the required specification of target column
     *     cb.query().setPurchaseDatetime_GreaterEqual(date); // query as you like it
     * });
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @return The optional scalar for summary value calculated by function. (NullAllowed) */ public OptionalScalar sum(ScalarQuery cbLambda) { return doSum(cbLambda, null); } /** * Select the summary value with function conversion option. *
     * purchaseBhv.scalarSelect(Integer.class).sum(cb -> {
     *     cb.specify().columnPurchaseCount(); // the required specification of target column
     *     cb.query().setPurchaseDatetime_GreaterEqual(date); // query as you like it
     * }, op -> op.coalesce(0));
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @param opLambda The callback for option of scalar. (NotNull) * @return The optional scalar for summary value calculated by function. (NullAllowed: or NotNull if you use coalesce by option) */ public OptionalScalar sum(ScalarQuery cbLambda, FunctionFilterOptionCall opLambda) { return doSum(cbLambda, prepareOption(opLambda)); } protected OptionalScalar doSum(ScalarQuery scalarQuery, ScalarSelectOption option) { assertScalarQuery(scalarQuery); return optionalOf("sum", exec(scalarQuery, SelectClauseType.SUM, option)); } // ----------------------------------------------------- // Average // ------- /** * Select the average value. *
     * purchaseBhv.scalarSelect(Integer.class).avg(cb -> {
     *     cb.specify().columnPurchaseCount(); // the required specification of target column
     *     cb.query().setPurchaseDatetime_GreaterEqual(date); // query as you like it
     * });
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @return The optional scalar for average value calculated by function. (NullAllowed) */ public OptionalScalar avg(ScalarQuery cbLambda) { return doAvg(cbLambda, null); } /** * Select the average value. *
     * purchaseBhv.scalarSelect(Integer.class).avg(cb -> {
     *     cb.specify().columnPurchaseCount(); // the required specification of target column
     *     cb.query().setPurchaseDatetime_GreaterEqual(date); // query as you like it
     * }, op -> op.coalesce(0));
     * 
* @param cbLambda The callback to select scalar value. (NotNull) * @param opLambda The callback for option of scalar. (NotNull) * @return The optional scalar for average value calculated by function. (NullAllowed: or NotNull if you use coalesce by option) */ public OptionalScalar avg(ScalarQuery cbLambda, FunctionFilterOptionCall opLambda) { return doAvg(cbLambda, prepareOption(opLambda)); } protected OptionalScalar doAvg(ScalarQuery scalarQuery, ScalarSelectOption option) { assertScalarQuery(scalarQuery); return optionalOf("avg", exec(scalarQuery, SelectClauseType.AVG, option)); } // ----------------------------------------------------- // Optional // -------- protected OptionalScalar optionalOf(String title, RESULT result) { return OptionalScalar.ofNullable(result, () -> { throwScalarSelectValueNotFoundException(title); }); } protected void throwScalarSelectValueNotFoundException(String title) { createBhvExThrower().throwScalarSelectValueNotFoundException(title, _conditionBean, _resultType); } // =================================================================================== // Execute // ======= protected RESULT exec(ScalarQuery scalarQuery, SelectClauseType selectClauseType, ScalarSelectOption option) { assertObjectNotNull("scalarQuery", scalarQuery); assertObjectNotNull("selectClauseType", selectClauseType); assertObjectNotNull("conditionBean", _conditionBean); assertObjectNotNull("resultType", _resultType); scalarQuery.query(_conditionBean); setupTargetColumnInfo(option); setupScalarSelectOption(option); assertScalarSelectRequiredSpecifyColumn(); return _executor.execute(_conditionBean, _resultType, selectClauseType); } protected void setupTargetColumnInfo(ScalarSelectOption option) { if (option == null) { return; } final SqlClause sqlClause = _conditionBean.getSqlClause(); ColumnInfo columnInfo = sqlClause.getSpecifiedColumnInfoAsOne(); if (columnInfo != null) { columnInfo = sqlClause.getSpecifiedDerivingColumnInfoAsOne(); } option.xsetTargetColumnInfo(columnInfo); } protected void setupScalarSelectOption(ScalarSelectOption option) { if (option != null) { _conditionBean.xacceptScalarSelectOption(option); _conditionBean.localCQ().xregisterParameterOption(option); } } protected void assertScalarSelectRequiredSpecifyColumn() { final SqlClause sqlClause = _conditionBean.getSqlClause(); final String columnName = sqlClause.getSpecifiedColumnDbNameAsOne(); final String subQuery = sqlClause.getSpecifiedDerivingSubQueryAsOne(); // should be specified is an only one object (column or sub-query) if ((columnName != null && subQuery != null) || (columnName == null && subQuery == null)) { throwScalarSelectInvalidColumnSpecificationException(); } } protected void throwScalarSelectInvalidColumnSpecificationException() { createCBExThrower().throwScalarSelectInvalidColumnSpecificationException(_conditionBean, _resultType); } // =================================================================================== // Assert Helper // ============= protected ScalarSelectOption prepareOption(FunctionFilterOptionCall opLambda) { assertObjectNotNull("opLambda", opLambda); final ScalarSelectOption option = createScalarSelectOption(); opLambda.callback(option); assertScalarSelectOption(option); return option; } protected ScalarSelectOption createScalarSelectOption() { return newScalarSelectOption(); } protected ScalarSelectOption newScalarSelectOption() { return new ScalarSelectOption(); } protected BehaviorExceptionThrower createBhvExThrower() { return new BehaviorExceptionThrower(); } protected ConditionBeanExceptionThrower createCBExThrower() { return new ConditionBeanExceptionThrower(); } protected void assertScalarQuery(ScalarQuery scalarQuery) { if (scalarQuery == null) { String msg = "The argument 'scalarQuery' for ScalarSelect should not be null."; throw new IllegalArgumentException(msg); } } protected void assertScalarSelectOption(ScalarSelectOption option) { if (option == null) { String msg = "The argument 'option' for ScalarSelect should not be null."; throw new IllegalArgumentException(msg); } } protected void assertObjectNotNull(String variableName, Object value) { if (variableName == null) { String msg = "The value should not be null: variableName=null value=" + value; throw new IllegalArgumentException(msg); } if (value == null) { String msg = "The value should not be null: variableName=" + variableName; throw new IllegalArgumentException(msg); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy