org.dbflute.cbean.sqlclause.orderby.OrderByElement 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-2023 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.sqlclause.orderby;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.dbflute.cbean.ConditionBean;
import org.dbflute.cbean.chelper.HpCalcSpecification;
import org.dbflute.cbean.chelper.HpMobCaseWhenElement;
import org.dbflute.cbean.cipher.ColumnFunctionCipher;
import org.dbflute.cbean.cipher.GearedCipherManager;
import org.dbflute.cbean.ckey.ConditionKey;
import org.dbflute.cbean.ordering.ManualOrderOption;
import org.dbflute.dbmeta.accessory.DerivedMappable;
import org.dbflute.dbmeta.info.ColumnInfo;
import org.dbflute.exception.IllegalConditionBeanOperationException;
import org.dbflute.system.DBFluteSystem;
import org.dbflute.util.DfTypeUtil;
import org.dbflute.util.Srl;
/**
* @author jflute
*/
public class OrderByElement implements Serializable {
// ===================================================================================
// Definition
// ==========
/** The serial version UID for object serialization. (Default) */
private static final long serialVersionUID = 1L;
// ===================================================================================
// Attribute
// =========
/** The value of alias name. (NullAllowed: when e.g. derived order-by) */
protected final String _aliasName;
/** The value of column name. (NotNull) */
protected final String _columnName;
/** The column info of the order column. (NotNull) */
protected transient final ColumnInfo _columnInfo;
// transient but serializing is already bankrupt
/** Is this derived order-by? */
protected final boolean _derivedOrderBy;
/** The value of ascDesc. (NotNull, Changeable) */
protected String _ascDesc = "asc";
/** The manager of geared cipher. (NullAllowed) */
protected transient GearedCipherManager _gearedCipherManager;
/** The set-upper of order-by nulls. (NullAllowed, SetupLater) */
protected transient OrderByClause.OrderByNullsSetupper _orderByNullsSetupper;
/** Is nulls ordered first? (SetupLater) */
protected boolean _nullsFirst;
/** The option of manual order. (NullAllowed, SetupLater) */
protected transient ManualOrderOption _manualOrderOption;
// ===================================================================================
// Constructor
// ===========
public OrderByElement(String aliasName, String columnName, ColumnInfo columnInfo, boolean derivedOrderBy) {
assertColumnName(aliasName, columnName);
assertColumnInfo(aliasName, columnInfo);
_aliasName = aliasName;
_columnName = columnName;
_columnInfo = columnInfo;
_derivedOrderBy = derivedOrderBy;
}
protected void assertColumnName(String aliasName, String columnName) {
if (columnName == null) {
String msg = "The argument 'columnName' should not be null: aliasName=" + aliasName;
throw new IllegalArgumentException(msg);
}
}
protected void assertColumnInfo(String aliasName, ColumnInfo columnInfo) {
if (columnInfo == null) {
String msg = "The argument 'columnInfo' should not be null: aliasName=" + aliasName;
throw new IllegalArgumentException(msg);
}
}
// ===================================================================================
// Manipulation
// ============
public void setupAsc() {
_ascDesc = "asc";
}
public void setupDesc() {
_ascDesc = "desc";
}
public void reverse() {
if (_ascDesc == null) {
String msg = "The attribute[ascDesc] should not be null.";
throw new IllegalStateException(msg);
}
if (_ascDesc.equals("asc")) {
_ascDesc = "desc";
} else if (_ascDesc.equals("desc")) {
_ascDesc = "asc";
} else {
String msg = "The attribute[ascDesc] should be asc or desc: but ascDesc=" + _ascDesc;
throw new IllegalStateException(msg);
}
}
// ===================================================================================
// Order-By Clause
// ===============
public String getElementClause() { // needs cipher
if (_ascDesc == null) {
String msg = "The attribute[ascDesc] should not be null.";
throw new IllegalStateException(msg);
}
final StringBuilder sb = new StringBuilder();
final String columnFullName = getColumnFullName();
if (_manualOrderOption != null && _manualOrderOption.hasManualOrder()) {
setupManualOrderClause(sb, columnFullName, null);
return sb.toString();
} else {
sb.append(decryptIfNeeds(_columnInfo, columnFullName)).append(" ").append(_ascDesc);
final String clause = sb.toString();
if (_orderByNullsSetupper != null) {
return _orderByNullsSetupper.setup(columnFullName, clause, _nullsFirst);
} else {
return clause;
}
}
}
public String getElementClause(Map selectClauseRealColumnAliasMap) { // basically for union
if (selectClauseRealColumnAliasMap == null) {
String msg = "The argument 'selectClauseRealColumnAliasMap' should not be null.";
throw new IllegalArgumentException(msg);
}
if (_ascDesc == null) {
String msg = "The attribute 'ascDesc' should not be null.";
throw new IllegalStateException(msg);
}
final String columnAlias = mappingToRealColumnAlias(selectClauseRealColumnAliasMap, getColumnFullName());
final StringBuilder sb = new StringBuilder();
if (_manualOrderOption != null && _manualOrderOption.hasManualOrder()) {
setupManualOrderClause(sb, columnAlias, selectClauseRealColumnAliasMap);
return sb.toString();
} else {
sb.append(columnAlias).append(" ").append(_ascDesc); // no need to cipher because of union
if (_orderByNullsSetupper != null) {
return _orderByNullsSetupper.setup(columnAlias, sb.toString(), _nullsFirst);
} else {
return sb.toString();
}
}
}
protected String mappingToRealColumnAlias(Map selectClauseRealColumnAliasMap, String columnFullName) {
final String columnAlias = selectClauseRealColumnAliasMap.get(columnFullName);
if (columnAlias == null || columnAlias.trim().length() == 0) {
throwOrderByColumnNotFoundException(getColumnFullName(), selectClauseRealColumnAliasMap);
}
return columnAlias;
}
protected void setupManualOrderClause(StringBuilder sb, String columnAlias, Map selectClauseRealColumnAliasMap) {
final String realAlias;
if (_manualOrderOption.hasOrderByCalculation()) {
final HpCalcSpecification calculationOrder = _manualOrderOption.getOrderByCalculation();
realAlias = calculationOrder.buildStatementToSpecifidName(columnAlias, selectClauseRealColumnAliasMap);
} else {
if (selectClauseRealColumnAliasMap != null) { // means union
realAlias = columnAlias;
} else {
realAlias = decryptIfNeeds(_columnInfo, columnAlias);
}
}
final List caseWhenList = _manualOrderOption.getCaseWhenBoundList();
if (!caseWhenList.isEmpty()) {
sb.append(ln()).append(" case").append(ln());
int index = 0;
for (HpMobCaseWhenElement element : caseWhenList) {
sb.append(" when ");
doSetupManualOrderClause(sb, realAlias, element);
final List connectedElementList = element.getConnectedElementList();
for (HpMobCaseWhenElement connectedElement : connectedElementList) {
doSetupManualOrderClause(sb, realAlias, connectedElement);
}
final Object thenValue = element.getThenValue();
final String thenExp;
if (thenValue != null) {
thenExp = thenValue.toString();
} else {
thenExp = String.valueOf(index);
}
sb.append(" then ").append(thenExp).append(ln());
++index;
}
final Object elseValue = _manualOrderOption.getElseValue();
final String elseExp;
if (elseValue != null) {
elseExp = elseValue.toString();
} else {
elseExp = String.valueOf(index);
}
sb.append(" else ").append(elseExp).append(ln());
sb.append(" end");
} else {
sb.append(realAlias);
}
sb.append(" ").append(_ascDesc);
}
protected void doSetupManualOrderClause(StringBuilder sb, String columnAlias, HpMobCaseWhenElement element) {
final ConditionKey conditionKey = element.getConditionKey();
final String keyExp = conditionKey.getOperand();
final String connector = element.toConnector();
if (connector != null) { // only connected elements
sb.append(" ").append(connector).append(" ");
}
if (isManualOrderConditionKeyNullHandling(conditionKey)) {
sb.append(columnAlias).append(" ").append(keyExp);
} else {
final Object bindExp = element.getOrderValue();
sb.append(columnAlias).append(" ").append(keyExp).append(" ").append(bindExp);
}
}
protected boolean isManualOrderConditionKeyNullHandling(ConditionKey conditionKey) {
return conditionKey.equals(ConditionKey.CK_IS_NULL) || conditionKey.equals(ConditionKey.CK_IS_NOT_NULL);
}
protected void throwOrderByColumnNotFoundException(String columnName, Map selectClauseRealColumnAliasMap) {
String msg = "Look! Read the message below." + ln();
msg = msg + "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" + ln();
msg = msg + "The column for order-by was not found in select-clause!" + ln();
msg = msg + ln();
msg = msg + "[Advice]" + ln();
msg = msg + "If you use 'union()' or 'unionAll()', check your condition-bean!" + ln();
msg = msg + "You can use only order-by columns on select-clause if union." + ln();
msg = msg + "For example:" + ln();
msg = msg + " (x):" + ln();
msg = msg + " AaaCB cb = new AaaCB();" + ln();
msg = msg + " cb.query().setXxx...();" + ln();
msg = msg + " cb.union(new UnionQuery() {" + ln();
msg = msg + " public void query(AaaCB unionCB) {" + ln();
msg = msg + " unionCB.query().setXxx...();" + ln();
msg = msg + " }" + ln();
msg = msg + " }" + ln();
msg = msg + " cb.query().queryBbb().addOrderBy_BbbName_Asc();// *NG!" + ln();
msg = msg + " " + ln();
msg = msg + " (o):" + ln();
msg = msg + " AaaCB cb = new AaaCB();" + ln();
msg = msg + " cb.setupSelect_Bbb();// *Point!" + ln();
msg = msg + " cb.query().setXxx...();" + ln();
msg = msg + " cb.union(new UnionQuery() {" + ln();
msg = msg + " public void query(AaaCB unionCB) {" + ln();
msg = msg + " unionCB.query().setXxx...();" + ln();
msg = msg + " }" + ln();
msg = msg + " }" + ln();
msg = msg + " cb.query().queryBbb().addOrderBy_BbbName_Asc();// *OK!" + ln();
msg = msg + " " + ln();
msg = msg + "Or else if you DON'T use 'union()' or 'unionAll()', This is the Framework Exception!" + ln();
msg = msg + ln();
msg = msg + "[Target Column]" + ln();
msg = msg + columnName + ln();
msg = msg + ln();
msg = msg + "[Internal Object]" + ln();
msg = msg + "selectClauseRealColumnAliasMap=" + selectClauseRealColumnAliasMap + ln();
msg = msg + "* * * * * * * * * */";
throw new IllegalConditionBeanOperationException(msg);
}
protected String ln() {
return DBFluteSystem.ln();
}
// ===================================================================================
// Order-By Info
// =============
public boolean isAsc() {
if (_ascDesc == null) {
String msg = "The attribute[ascDesc] should not be null.";
throw new IllegalStateException(msg);
}
if (_ascDesc.equals("asc")) {
return true;
} else if (_ascDesc.equals("desc")) {
return false;
} else {
String msg = "The attribute[ascDesc] should be asc or desc: but ascDesc=" + _ascDesc;
throw new IllegalStateException(msg);
}
}
public String getColumnFullName() {
final StringBuilder sb = new StringBuilder();
if (_aliasName != null) {
sb.append(_aliasName).append(".");
}
if (_columnName == null) {
String msg = "The attribute[columnName] should not be null.";
throw new IllegalStateException(msg);
}
final String derivedMappingAliasPrefix = DerivedMappable.MAPPING_ALIAS_PREFIX;
if (_derivedOrderBy && _columnName.startsWith(derivedMappingAliasPrefix)) {
sb.append(Srl.substringFirstRear(_columnName, derivedMappingAliasPrefix));
} else {
sb.append(_columnName);
}
return sb.toString();
}
// ===================================================================================
// Geared Cipher
// =============
protected String decryptIfNeeds(ColumnInfo columnInfo, String valueExp) {
if (_gearedCipherManager == null) {
return valueExp;
}
final ColumnFunctionCipher cipher = _gearedCipherManager.findColumnFunctionCipher(columnInfo);
return cipher != null ? cipher.decrypt(valueExp) : valueExp;
}
// ===================================================================================
// Basic Override
// ==============
/**
* This method overrides the method that is declared at super.
* @return The view-string of all-columns value. (NotNull)
*/
public String toString() {
final String title = DfTypeUtil.toClassTitle(this);
final StringBuilder sb = new StringBuilder();
sb.append(title).append(":");
sb.append("{aliasName=").append(_aliasName);
sb.append(" columnName=").append(_columnName);
sb.append(" ascDesc=").append(_ascDesc);
sb.append("}");
return sb.toString();
}
// ===================================================================================
// Accessor
// ========
public String getAliasName() {
return _aliasName;
}
public String getColumnName() {
return _columnName;
}
public ColumnInfo getColumnInfo() {
return _columnInfo;
}
public boolean isDerivedOrderBy() {
return _derivedOrderBy;
}
public String getAscDesc() {
return _ascDesc;
}
public void setGearedCipherManager(GearedCipherManager gearedCipherManager) {
this._gearedCipherManager = gearedCipherManager;
}
public void setOrderByNullsSetupper(OrderByClause.OrderByNullsSetupper value, boolean nullsFirst) {
_orderByNullsSetupper = value;
_nullsFirst = nullsFirst;
}
public void setManualOrderOption(ManualOrderOption manualOrderOption) {
_manualOrderOption = manualOrderOption;
}
public ManualOrderOption getManualOrderOption() {
return _manualOrderOption;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy