org.dbflute.cbean.chelper.HpSLSFunction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dbflute-runtime Show documentation
Show all versions of dbflute-runtime Show documentation
The runtime library of DBFlute
/*
* Copyright 2014-2019 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