org.dbflute.cbean.chelper.HpSDRFunction 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-2021 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.cbean.ConditionBean;
import org.dbflute.cbean.ConditionQuery;
import org.dbflute.cbean.coption.DerivedReferrerOption;
import org.dbflute.cbean.coption.DerivedReferrerOptionFactory;
import org.dbflute.cbean.coption.FunctionFilterOptionCall;
import org.dbflute.cbean.exception.ConditionBeanExceptionThrower;
import org.dbflute.cbean.scoping.SubQuery;
import org.dbflute.dbmeta.DBMeta;
import org.dbflute.dbmeta.DBMetaProvider;
import org.dbflute.dbmeta.accessory.DerivedMappable;
import org.dbflute.dbmeta.info.ColumnInfo;
import org.dbflute.exception.IllegalConditionBeanOperationException;
import org.dbflute.exception.SpecifyDerivedReferrerInvalidAliasNameException;
import org.dbflute.util.Srl;
/**
* The function for (Specify)DerivedReferrer.
* @param The type of referrer condition-bean.
* @param The type of local condition-query.
* @author jflute
*/
public class HpSDRFunction {
// ===================================================================================
// Attribute
// =========
protected final ConditionBean _baseCB;
protected final LOCAL_CQ _localCQ;
protected final HpSDRSetupper _querySetupper;
protected final DBMetaProvider _dbmetaProvider;
protected final DerivedReferrerOptionFactory _sdrOpFactory;
// ===================================================================================
// Constructor
// ===========
public HpSDRFunction(ConditionBean baseCB, LOCAL_CQ localCQ, HpSDRSetupper querySetupper,
DBMetaProvider dbmetaProvider, DerivedReferrerOptionFactory sdrOpFactory) {
_baseCB = baseCB;
_localCQ = localCQ;
_querySetupper = querySetupper;
_dbmetaProvider = dbmetaProvider;
_sdrOpFactory = sdrOpFactory;
}
// ===================================================================================
// Function
// ========
// -----------------------------------------------------
// Count
// -----
/**
* Set up the sub query of referrer for the scalar 'count'.
*
* cb.specify().derivePurchaseList().count(purchaseCB -> {
* purchaseCB.specify().columnPurchaseId(); // basically PK to count records
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_purchaseCount);
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
*/
public void count(SubQuery derivedCBLambda, String aliasName) {
doCount(derivedCBLambda, aliasName, null);
}
/**
* An overload method for count() with an option. So refer to the method's java-doc about basic info.
*
* cb.specify().derivePurchaseList().count(purchaseCB -> {
* purchaseCB.specify().columnPurchaseId(); // basically PK to count records
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_purchaseCount, op -> op.coalesce(0));
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
* @param opLambda The callback for option of DerivedReferrer. e.g. you can use a coalesce function. (NotNull)
*/
public void count(SubQuery derivedCBLambda, String aliasName, FunctionFilterOptionCall opLambda) {
doCount(derivedCBLambda, aliasName, createDerivedReferrerOption(opLambda));
}
protected void doCount(SubQuery subQuery, String aliasName, DerivedReferrerOption option) {
assertSubQuery(subQuery);
assertAliasName(aliasName);
_querySetupper.setup("count", subQuery, _localCQ, filterAliasName(aliasName), option);
}
// -----------------------------------------------------
// Count Distinct
// --------------
/**
* Set up the sub query of referrer for the scalar 'count-distinct'.
*
* cb.specify().derivePurchaseList().countDistinct(purchaseCB -> {
* purchaseCB.specify().columnProductId(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_productKindCount);
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
*/
public void countDistinct(SubQuery derivedCBLambda, String aliasName) {
doCountDistinct(derivedCBLambda, aliasName, null);
}
/**
* An overload method for count() with an option. So refer to the method's java-doc about basic info.
*
* cb.specify().derivePurchaseList().countDistinct(purchaseCB -> {
* purchaseCB.specify().columnProductId(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_productKindCount, op -> op.coalesce(0));
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
* @param opLambda The callback for option of DerivedReferrer. e.g. you can use a coalesce function. (NotNull)
*/
public void countDistinct(SubQuery derivedCBLambda, String aliasName,
FunctionFilterOptionCall opLambda) {
doCountDistinct(derivedCBLambda, aliasName, createDerivedReferrerOption(opLambda));
}
protected void doCountDistinct(SubQuery subQuery, String aliasName, DerivedReferrerOption option) {
assertSubQuery(subQuery);
assertAliasName(aliasName);
_querySetupper.setup("count(distinct", subQuery, _localCQ, filterAliasName(aliasName), option);
}
// -----------------------------------------------------
// Max
// -----
/**
* Set up the sub query of referrer for the scalar 'max'.
*
* cb.specify().derivePurchaseList().max(purchaseCB -> {
* purchaseCB.specify().columnPurchaseDatetime(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_latestPurchaseDatetime);
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
*/
public void max(SubQuery derivedCBLambda, String aliasName) {
doMax(derivedCBLambda, aliasName, null);
}
/**
* An overload method for max() with an option. So refer to the method's java-doc.
*
* cb.specify().derivePurchaseList().max(purchaseCB -> {
* purchaseCB.specify().columnPurchaseDatetime(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_latestPurchaseDatetime, op -> op.coalesce("2011-06-07"));
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
* @param opLambda The callback for option of DerivedReferrer. e.g. you can use a coalesce function. (NotNull)
*/
public void max(SubQuery derivedCBLambda, String aliasName, FunctionFilterOptionCall opLambda) {
doMax(derivedCBLambda, aliasName, createDerivedReferrerOption(opLambda));
}
protected void doMax(SubQuery subQuery, String aliasName, DerivedReferrerOption option) {
assertSubQuery(subQuery);
assertAliasName(aliasName);
_querySetupper.setup("max", subQuery, _localCQ, filterAliasName(aliasName), option);
}
// -----------------------------------------------------
// Min
// -----
/**
* Set up the sub query of referrer for the scalar 'min'.
*
* cb.specify().derivePurchaseList().min(purchaseCB -> {
* purchaseCB.specify().columnPurchaseDatetime(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_firstPurchaseDatetime);
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
*/
public void min(SubQuery derivedCBLambda, String aliasName) {
doMin(derivedCBLambda, aliasName, null);
}
/**
* An overload method for min() with an option. So refer to the method's java-doc.
*
* cb.specify().derivePurchaseList().min(purchaseCB -> {
* purchaseCB.specify().columnPurchaseDatetime(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_firstPurchaseDatetime, op -> op.coalesce("2011-06-07"));
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
* @param opLambda The callback for option of DerivedReferrer. e.g. you can use a coalesce function. (NotNull)
*/
public void min(SubQuery derivedCBLambda, String aliasName, FunctionFilterOptionCall opLambda) {
doMin(derivedCBLambda, aliasName, createDerivedReferrerOption(opLambda));
}
protected void doMin(SubQuery subQuery, String aliasName, DerivedReferrerOption option) {
assertSubQuery(subQuery);
assertAliasName(aliasName);
_querySetupper.setup("min", subQuery, _localCQ, filterAliasName(aliasName), option);
}
// -----------------------------------------------------
// Sum
// -----
/**
* Set up the sub query of referrer for the scalar 'sum'.
*
* cb.specify().derivePurchaseList().sum(purchaseCB -> {
* purchaseCB.specify().columnPurchasePrice(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_purchasePriceSummary);
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
*/
public void sum(SubQuery derivedCBLambda, String aliasName) {
doSum(derivedCBLambda, aliasName, null);
}
/**
* An overload method for sum() with an option. So refer to the method's java-doc.
*
* cb.specify().derivePurchaseList().sum(purchaseCB -> {
* purchaseCB.specify().columnPurchasePrice(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_purchasePriceSummary, op -> op.coalesce(0));
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
* @param opLambda The callback for option of DerivedReferrer. e.g. you can use a coalesce function. (NotNull)
*/
public void sum(SubQuery derivedCBLambda, String aliasName, FunctionFilterOptionCall opLambda) {
doSum(derivedCBLambda, aliasName, createDerivedReferrerOption(opLambda));
}
protected void doSum(SubQuery subQuery, String aliasName, DerivedReferrerOption option) {
assertSubQuery(subQuery);
assertAliasName(aliasName);
_querySetupper.setup("sum", subQuery, _localCQ, filterAliasName(aliasName), option);
}
// -----------------------------------------------------
// Average
// -------
/**
* Set up the sub query of referrer for the scalar 'avg'.
*
* cb.specify().derivePurchaseList().avg(purchaseCB -> {
* purchaseCB.specify().columnPurchasePrice(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_purchasePriceAverage);
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
*/
public void avg(SubQuery derivedCBLambda, String aliasName) {
doAvg(derivedCBLambda, aliasName, null);
}
/**
* An overload method for avg() with an option. So refer to the method's java-doc.
*
* cb.specify().derivePurchaseList().avg(purchaseCB -> {
* purchaseCB.specify().columnPurchasePrice(); // derived column by function
* purchaseCB.query().setPaymentCompleteFlg_Equal_True(); // referrer condition
* }, Member.ALIAS_purchasePriceAverage, op -> op.coalesce(0));
*
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
* @param opLambda The callback for option of DerivedReferrer. e.g. you can use a coalesce function. (NotNull)
*/
public void avg(SubQuery derivedCBLambda, String aliasName, FunctionFilterOptionCall opLambda) {
doAvg(derivedCBLambda, aliasName, createDerivedReferrerOption(opLambda));
}
protected void doAvg(SubQuery subQuery, String aliasName, DerivedReferrerOption option) {
doSetupQuery("avg", subQuery, aliasName, option);
}
protected void doSetupQuery(String function, SubQuery subQuery, String aliasName, DerivedReferrerOption option) {
assertSubQuery(subQuery);
assertAliasName(aliasName);
_querySetupper.setup(function, subQuery, _localCQ, filterAliasName(aliasName), option);
}
// -----------------------------------------------------
// User Definition
// ---------------
/**
* Basically for database dependency (DBMS sub-class). {Internal}
* Not public because of condition-bean policy: cannot input SQL string.
* @param derivedCBLambda The callback for sub-query of referrer. (NotNull)
* @param aliasName The alias of the name. The property should exists on the entity. (NotNull)
* @param function The function expression e.g. sum, max (NotNull)
* @param opLambda The callback for option of DerivedReferrer. e.g. you can use a coalesce function. (NotNull)
*/
protected void userDef(SubQuery derivedCBLambda, String aliasName, String function,
FunctionFilterOptionCall opLambda) { // closet
doUserDef(derivedCBLambda, aliasName, function, createDerivedReferrerOption(opLambda));
}
protected void doUserDef(SubQuery subQuery, String aliasName, String function, DerivedReferrerOption option) {
assertSubQuery(subQuery);
assertAliasName(aliasName);
assertUserDefFunction(aliasName, function);
_querySetupper.setup(function, subQuery, _localCQ, filterAliasName(aliasName), option);
}
// ===================================================================================
// Assist Helper
// =============
protected DerivedReferrerOption createDerivedReferrerOption(FunctionFilterOptionCall opLambda) {
assertDerivedReferrerOption(opLambda);
final DerivedReferrerOption option = newDerivedReferrerOption();
opLambda.callback(option);
return option;
}
protected DerivedReferrerOption newDerivedReferrerOption() {
return _sdrOpFactory.create();
}
protected void assertSubQuery(SubQuery> subQuery) {
if (subQuery == null) {
String msg = "The argument 'subQuery' for DerivedReferrer should not be null.";
throw new IllegalArgumentException(msg);
}
}
protected void assertAliasName(String aliasName) {
doAssertInvalidAliasName(aliasName);
doAssertConflictAliasName(aliasName);
// *this check was moved to runtime (when creating a behavior command)
//String tableDbName = _baseCB.asTableDbName();
//DBMeta dbmeta = _dbmetaProvider.provideDBMetaChecked(tableDbName);
//Method[] methods = dbmeta.getEntityType().getMethods();
//String targetMethodName = "set" + replaceString(aliasName, "_", "").toLowerCase();
//boolean existsSetterMethod = false;
//for (Method method : methods) {
// if (!method.getName().startsWith("set")) {
// continue;
// }
// if (targetMethodName.equals(method.getName().toLowerCase())) {
// existsSetterMethod = true;
// break;
// }
//}
//if (!existsSetterMethod) {
// throwSpecifyDerivedReferrerEntityPropertyNotFoundException(aliasName, dbmeta.getEntityType());
//}
}
protected void doAssertInvalidAliasName(String aliasName) {
if (isPurposeNullAlias()) {
if (aliasName != null) {
String msg = "The aliasName should be null in the purpose: " + _baseCB.getPurpose();
throw new SpecifyDerivedReferrerInvalidAliasNameException(msg);
}
} else { // normal
if (Srl.is_Null_or_TrimmedEmpty(aliasName)) {
throwSpecifyDerivedReferrerInvalidAliasNameException();
}
}
}
protected boolean isPurposeNullAlias() {
final HpCBPurpose purpose = _baseCB.getPurpose();
return purpose.equals(HpCBPurpose.COLUMN_QUERY) || purpose.equals(HpCBPurpose.SCALAR_SELECT)
|| purpose.equals(HpCBPurpose.DERIVED_REFERRER);
}
protected void throwSpecifyDerivedReferrerInvalidAliasNameException() {
createCBExThrower().throwSpecifyDerivedReferrerInvalidAliasNameException(_localCQ);
}
protected void doAssertConflictAliasName(String aliasName) {
if (isPurposeNullAlias()) {
return;
}
final String mappingAliasPrefix = DerivedMappable.MAPPING_ALIAS_PREFIX;
final String realName;
if (aliasName.startsWith(mappingAliasPrefix)) {
realName = Srl.substringFirstRear(aliasName, mappingAliasPrefix);
} else {
realName = aliasName;
}
final String tableDbName = _baseCB.asTableDbName();
final DBMeta dbmeta = _dbmetaProvider.provideDBMetaChecked(tableDbName);
if (dbmeta.hasColumn(realName)) {
throwSpecifyDerivedReferrerConflictAliasNameException(aliasName, dbmeta.findColumnInfo(realName));
}
}
protected void throwSpecifyDerivedReferrerConflictAliasNameException(String aliasName, ColumnInfo existingColumn) {
createCBExThrower().throwSpecifyDerivedReferrerConflictAliasNameException(_localCQ, aliasName, existingColumn);
}
// *this check was moved to runtime (when creating a behavior command)
//protected void throwSpecifyDerivedReferrerEntityPropertyNotFoundException(String aliasName, Class> entityType) {
// createCBExThrower().throwSpecifyDerivedReferrerEntityPropertyNotFoundException(aliasName, entityType);
//}
//protected String replaceString(String text, String fromText, String toText) {
// return Srl.replace(text, fromText, toText);
//}
protected void assertDerivedReferrerOption(FunctionFilterOptionCall opLambda) {
if (opLambda == null) {
String msg = "The argument 'opLambda' for DerivedReferrer should not be null.";
throw new IllegalArgumentException(msg);
}
}
protected String filterAliasName(String aliasName) {
if (aliasName != null) {
return aliasName.trim();
} else {
final HpCBPurpose purpose = _baseCB.getPurpose();
if (isPurposeNullAlias()) {
if (purpose.equals(HpCBPurpose.SCALAR_SELECT)) {
return _baseCB.getSqlClause().getScalarSelectColumnAlias();
} else if (purpose.equals(HpCBPurpose.DERIVED_REFERRER)) {
return _baseCB.getSqlClause().getDerivedReferrerNestedAlias();
} else { // for example, ColumnQuery
return null;
}
} else { // basically no way because of checked before
return null;
}
}
}
protected void assertUserDefFunction(String aliasName, String function) {
if (!Srl.isAlphabetNumberHarfAllOr(function, '_')) { // e.g. ')', ';' are NG
String msg = "Illegal function, only alphabet or number can be allowed:";
msg = msg + " aliasName=" + aliasName + ", function=" + function;
throw new IllegalConditionBeanOperationException(msg);
}
}
// ===================================================================================
// Exception Helper
// ================
protected ConditionBeanExceptionThrower createCBExThrower() {
return new ConditionBeanExceptionThrower();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy