Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014-2015 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.subquery;
 
 import java.util.List;
 import java.util.Set;
 

Author(s):
jflute
Since:
0.9.7.2 (2010/06/20 Sunday)
 
 public abstract class DerivedReferrer extends AbstractSubQuery {
 
     // ===================================================================================
     //                                                                           Attribute
     //                                                                           =========
     protected final String _mainSubQueryIdentity;
 
     // ===================================================================================
     //                                                                         Constructor
     //                                                                         ===========
     public DerivedReferrer(SubQueryPath subQueryPathColumnRealNameProvider localRealNameProvider,
             ColumnSqlNameProvider subQuerySqlNameProviderint subQueryLevelSqlClause subQuerySqlClauseString subQueryIdentity,
             DBMeta subQueryDBMetaGearedCipherManager cipherManagerString mainSubQueryIdentity) {
         super(subQueryPathlocalRealNameProvidersubQuerySqlNameProvidersubQueryLevelsubQuerySqlClausesubQueryIdentity,
                 subQueryDBMetacipherManager);
          = mainSubQueryIdentity;
     }
 
     // ===================================================================================
     //                                                                        Build Clause
     //                                                                        ============
     public String buildDerivedReferrer(String functionString correlatedColumnDbNameString relatedColumnDbName,
             String correlatedFixedConditionDerivedReferrerOption option) {
         setupOptionAttribute(option);
         if (isSinglePrimaryKey(correlatedColumnDbNamerelatedColumnDbName)) {
             final ColumnRealName correlatedColumnRealName = .provide(correlatedColumnDbName);
             final ColumnSqlName relatedColumnSqlName = .provide(relatedColumnDbName);
             final String subQueryClause =
                     buildSubQueryClause(functioncorrelatedColumnRealNamerelatedColumnSqlNamecorrelatedFixedConditionoption);
             final String beginMark = resolveSubQueryBeginMark() + ln();
             final String endMark = resolveSubQueryEndMark();
             final String endIndent = "       ";
             return doBuildDerivedReferrer(functioncorrelatedColumnRealNamerelatedColumnSqlNamesubQueryClausebeginMarkendMark,
                     endIndent);
         } else {
             final List<StringcolumnDbNameSplit = Srl.splitListTrimmed(correlatedColumnDbName",");
             final ColumnRealName[] correlatedColumnRealNames = new ColumnRealName[columnDbNameSplit.size()];
             for (int i = 0; i < columnDbNameSplit.size(); i++) {
                 correlatedColumnRealNames[i] = .provide(columnDbNameSplit.get(i));
             }
             final List<StringrelatedColumnSplit = Srl.splitListTrimmed(relatedColumnDbName",");
             final ColumnSqlName[] relatedColumnSqlNames = new ColumnSqlName[relatedColumnSplit.size()];
             for (int i = 0; i < relatedColumnSplit.size(); i++) {
                 relatedColumnSqlNames[i] = .provide(relatedColumnSplit.get(i));
             }
             final String subQueryClause =
                     getSubQueryClause(functioncorrelatedColumnRealNamesrelatedColumnSqlNamescorrelatedFixedConditionoption);
             final String beginMark = resolveSubQueryBeginMark() + ln();
             final String endMark = resolveSubQueryEndMark();
             final String endIndent = "       ";
             return doBuildDerivedReferrer(functioncorrelatedColumnRealNamesrelatedColumnSqlNamessubQueryClausebeginMarkendMark,
                     endIndent);
         }
     }
 
     protected void setupOptionAttribute(DerivedReferrerOption option) {
         ColumnInfo columnInfo = .getSpecifiedColumnInfoAsOne();
         if (columnInfo == null) {
             columnInfo = .getSpecifiedDerivingColumnInfoAsOne();
         }
         option.xsetTargetColumnInfo(columnInfo); // basically not null (checked before)
         option.xjudgeDatabase();
     }
    protected abstract String doBuildDerivedReferrer(String functionColumnRealName correlatedColumnRealName,
            ColumnSqlName relatedColumnSqlNameString subQueryClauseString beginMarkString endMarkString endIndent);
    protected abstract String doBuildDerivedReferrer(String functionColumnRealName[] correlatedColumnRealNames,
            ColumnSqlName[] relatedColumnSqlNamesString subQueryClauseString beginMarkString endMarkString endIndent);
    // ===================================================================================
    //                                                 (Single PrimaryKey) SubQuery Clause
    //                                                 ===================================
    
Build the clause of sub-query by single primary key.

Parameters:
function The expression for deriving function. (NotNull)
correlatedColumnRealName The real names of correlated column that is main-query table's column. (NotNull)
relatedColumnSqlName The real names of related column that is sub-query table's column. (NotNull)
correlatedFixedCondition The fixed condition as correlated condition. (NullAllowed)
option The option of DerivedReferrer. (NotNull)
Returns:
The clause of sub-query. (NotNull)
    protected String buildSubQueryClause(String functionColumnRealName correlatedColumnRealNameColumnSqlName relatedColumnSqlName,
            String correlatedFixedConditionDerivedReferrerOption option) {
        final String tableAliasName = getSubQueryLocalAliasName();
        final ColumnSqlName derivedColumnSqlName = getDerivedColumnSqlName();
        if (derivedColumnSqlName == null) {
        }
        final ColumnRealName derivedColumnRealName = getDerivedColumnRealName();
        final String subQueryClause;
        if (.hasUnionQuery()) {
            subQueryClause =
                    buildUnionSubQueryClause(functioncorrelatedColumnRealNamerelatedColumnSqlNameoptiontableAliasName,
                            derivedColumnRealNamederivedColumnSqlNamecorrelatedFixedCondition);
        } else {
            final String selectClause = "select " + buildFunctionPart(functionderivedColumnRealNameoptionfalse);
            final String fromWhereClause;
            if (option.isSuppressCorrelation()) { // e.g. myselfDerived
                fromWhereClause = buildPlainFromWhereClause(selectClausetableAliasNamecorrelatedFixedCondition);
            } else { // basically here
                fromWhereClause =
                        buildCorrelationFromWhereClause(selectClausetableAliasNamecorrelatedColumnRealNamerelatedColumnSqlName,
                                correlatedFixedCondition);
            }
            subQueryClause = selectClause + " " + fromWhereClause;
        }
        return resolveSubQueryLevelVariable(subQueryClause);
    }
    // -----------------------------------------------------
    //                    (Single PrimaryKey) Union Handling
    //                    ----------------------------------
    protected String buildUnionSubQueryClause(String functionColumnRealName correlatedColumnRealNameColumnSqlName relatedColumnSqlName,
            DerivedReferrerOption optionString tableAliasNameColumnRealName derivedColumnRealNameColumnSqlName derivedColumnSqlName,
            String correlatedFixedCondition) {
        final String mainSql =
                buildUnionMainPartClause(relatedColumnSqlNametableAliasNamederivedColumnRealNamederivedColumnSqlName,
                        correlatedFixedCondition);
        final String mainAlias = buildSubQueryMainAliasName();
        final String whereJoinCondition;
        if (option.isSuppressCorrelation()) { // e.g. myselfDerived
            whereJoinCondition = "";
        } else { // mainly here
            final ColumnRealName relatedColumnRealName = ColumnRealName.create(mainAliasrelatedColumnSqlName);
            final StringBuilder sb = new StringBuilder();
            sb.append(ln()).append(" where ");
            sb.append(relatedColumnRealName).append(" = ").append(correlatedColumnRealName);
            if (isFixedCondition(correlatedFixedCondition)) {
                sb.append(ln()).append("   and ");
                sb.append(Srl.replace(correlatedFixedConditiontableAliasName + "."mainAlias + "."));
            }
            whereJoinCondition = sb.toString(); // correlation
        }
        final ColumnRealName mainDerivedColumnRealName = ColumnRealName.create(mainAliasderivedColumnSqlName);
        return doBuildUnionSubQueryClause(functionoptionmainSqlmainAliaswhereJoinConditionmainDerivedColumnRealName);
    }
    protected String buildUnionMainPartClause(ColumnSqlName relatedColumnSqlNameString tableAliasName,
            ColumnRealName derivedColumnRealNameColumnSqlName derivedColumnSqlNameString correlatedFixedCondition) {
        // derivedColumnSqlName : e.g. PURCHASE_PRICE
        // derivedRealSqlName   : might be sub-query
        final ColumnSqlName derivedRealSqlName = derivedColumnRealName.getColumnSqlName();
        final StringBuilder keySb = new StringBuilder();
        if (isFixedCondition(correlatedFixedCondition)) {
            setupUnionMainForFixedCondition(keySbtableAliasNamederivedColumnSqlName);
        } else { // no fixed condition, mainly here
            final List<ColumnInfopkList = .getPrimaryInfo().getPrimaryColumnList();
            for (ColumnInfo pk : pkList) {
                final ColumnSqlName pkSqlName = pk.getColumnSqlName();
                if (pkSqlName.equals(derivedRealSqlName) || pkSqlName.equals(relatedColumnSqlName)) {
                    continue// to suppress same columns selected
                }
                keySb.append(keySb.length() > 0 ? ", " : "");
                keySb.append(ColumnRealName.create(tableAliasNamepk.getColumnSqlName()));
            }
            if (!relatedColumnSqlName.equals(derivedRealSqlName)) { // to suppress same columns selected
                keySb.append(keySb.length() > 0 ? ", " : "");
                keySb.append(ColumnRealName.create(tableAliasNamerelatedColumnSqlName));
            }
        }
        setupUnionMainForDerivedColumn(keySbderivedColumnRealNamederivedColumnSqlNamederivedRealSqlName);
        return completeUnionMainWholeClause(tableAliasNamekeySb);
    }
    protected String doBuildUnionSubQueryClause(String functionDerivedReferrerOption optionString mainSqlString mainAlias,
            String whereJoinConditionColumnRealName mainDerivedColumnRealName) {
        final String beginMark = resolveSubQueryBeginMark() + ln();
        final String endMark = resolveSubQueryEndMark();
        return "select " + buildFunctionPart(functionmainDerivedColumnRealNameoptiontrue// select
                + ln() + "  from (" + beginMark + mainSql + ln() + "       ) " + mainAlias + endMark // from
                + whereJoinCondition// where
    }
    protected void setupUnionMainForFixedCondition(StringBuilder keySbString tableAliasNameColumnSqlName derivedColumnSqlName) {
        // all columns because fixed condition might contain them
        final List<ColumnInfocolumnInfoList = .getColumnInfoList();
        for (ColumnInfo columnInfo : columnInfoList) {
            final ColumnSqlName sqlName = columnInfo.getColumnSqlName();
            if (sqlName.equals(derivedColumnSqlName)) {
                continue// to suppress same columns selected
            }
            final ColumnRealName realName = ColumnRealName.create(tableAliasNamecolumnInfo.getColumnSqlName());
            keySb.append(keySb.length() > 0 ? ", " : "");
            keySb.append(realName);
        }
    }
    protected void setupUnionMainForDerivedColumn(StringBuilder keySbColumnRealName derivedColumnRealName,
            ColumnSqlName derivedColumnSqlNameColumnSqlName derivedRealSqlName) {
        // derivedColumnSqlName : e.g. PURCHASE_PRICE
        // derivedRealSqlName   : might be sub-query
        if (mightBeSubQueryOrCalculation(derivedRealSqlName)) { // nested sub-query or calculation
            if (!isNestedDerivedReferrer(derivedRealSqlName)) { // might be calculation (needs to resolve location)
                keySb.append(keySb.length() > 0 ? ", " : "");
                final String realNameExp = derivedColumnRealName.toString();
                final String locationResolved = .resolveParameterLocationPath(realNameExp);
                keySb.append(locationResolved).append(" as ").append(derivedColumnSqlName);
            }
            // *skip here if nested sub-query, handled at function part in select clause
        } else {
            keySb.append(keySb.length() > 0 ? ", " : "");
            keySb.append(derivedColumnRealName);
        }
    }
    protected boolean mightBeSubQueryOrCalculation(ColumnSqlName derivedRealSqlName) {
        final String exp = derivedRealSqlName.toString();
        return exp.contains(" ") || exp.contains("("); // not accurate but small problem
    }
    protected String completeUnionMainWholeClause(String tableAliasNameStringBuilder keySb) {
        final String selectClause = "select " + keySb.toString();
        final String fromWhereClause = buildPlainFromWhereClause(selectClausetableAliasNamenull);
        return selectClause + " " + fromWhereClause;
    }
    // ===================================================================================
    //                                               SubQuery Clause (Compound PrimaryKey)
    //                                               =====================================
    
Build the clause of sub-query by compound primary key.

Parameters:
function The expression for deriving function. (NotNull)
correlatedColumnRealNames The real names of correlated column that is main-query table's column. (NotNull)
relatedColumnSqlNames The real names of related column that is sub-query table's column. (NotNull)
correlatedFixedCondition The fixed condition as correlated condition. (NullAllowed)
option The option of DerivedReferrer. (NotNull)
Returns:
The clause of sub-query. (NotNull)
    protected String getSubQueryClause(String functionColumnRealName[] correlatedColumnRealNamesColumnSqlName[] relatedColumnSqlNames,
            String correlatedFixedConditionDerivedReferrerOption option) {
        final String tableAliasName = getSubQueryLocalAliasName();
        final ColumnSqlName derivedColumnSqlName = getDerivedColumnSqlName();
        if (derivedColumnSqlName == null) {
        }
        final ColumnRealName derivedColumnRealName = getDerivedColumnRealName();
        final String subQueryClause;
        if (.hasUnionQuery()) {
            subQueryClause =
                    buildUnionSubQueryClause(functioncorrelatedColumnRealNamesrelatedColumnSqlNamesoptiontableAliasName,
                            derivedColumnRealNamederivedColumnSqlNamecorrelatedFixedCondition);
        } else {
            final String selectClause = "select " + buildFunctionPart(functionderivedColumnRealNameoptionfalse);
            final String fromWhereClause;
            if (option.isSuppressCorrelation()) { // e.g. myselfDerived
                fromWhereClause = buildPlainFromWhereClause(selectClausetableAliasNamecorrelatedFixedCondition);
            } else { // basically here
                fromWhereClause =
                        buildCorrelationFromWhereClause(selectClausetableAliasNamecorrelatedColumnRealNamesrelatedColumnSqlNames,
                                correlatedFixedCondition);
            }
            subQueryClause = selectClause + " " + fromWhereClause;
        }
        return resolveSubQueryLevelVariable(subQueryClause);
    }
    // -----------------------------------------------------
    //                  (Compound PrimaryKey) Union Handling
    //                  ------------------------------------
    protected String buildUnionSubQueryClause(String functionColumnRealName[] correlatedColumnRealNames,
            ColumnSqlName[] relatedColumnSqlNamesDerivedReferrerOption optionString tableAliasName,
            ColumnRealName derivedColumnRealNameColumnSqlName derivedColumnSqlNameString correlatedFixedCondition) {
        final String mainSql =
                buildUnionMainPartClause(correlatedColumnRealNamesrelatedColumnSqlNamestableAliasNamederivedColumnRealName,
                        derivedColumnSqlNamecorrelatedFixedCondition);
        final String mainAlias = buildSubQueryMainAliasName();
        final String whereJoinCondition;
        if (option.isSuppressCorrelation()) { // e.g. myselfDerived
            whereJoinCondition = "";
        } else { // mainly here
            final StringBuilder sb = new StringBuilder();
            sb.append(ln()).append(" where ");
            for (int i = 0; i < correlatedColumnRealNames.lengthi++) {
                if (i > 0) {
                    sb.append(ln()).append("   and ");
                }
                sb.append(ColumnRealName.create(mainAliasrelatedColumnSqlNames[i]));
                sb.append(" = ").append(correlatedColumnRealNames[i]);
            }
            if (isFixedCondition(correlatedFixedCondition)) {
                if (correlatedColumnRealNames.length > 0) { // basically true (but just in case)
                    sb.append(ln()).append("   and ");
                }
                sb.append(Srl.replace(correlatedFixedConditiontableAliasName + "."mainAlias + "."));
            }
            whereJoinCondition = sb.toString(); // correlation
        }
        final ColumnRealName mainDerivedColumnRealName = ColumnRealName.create(mainAliasderivedColumnSqlName);
        return doBuildUnionSubQueryClause(functionoptionmainSqlmainAliaswhereJoinConditionmainDerivedColumnRealName);
    }
    protected String buildUnionMainPartClause(ColumnRealName[] correlatedColumnRealNamesColumnSqlName[] relatedColumnSqlNames,
            String tableAliasNameColumnRealName derivedColumnRealNameColumnSqlName derivedColumnSqlNameString correlatedFixedCondition) {
        // similar to simple primary key so refer it
        final StringBuilder keySb = new StringBuilder();
        final ColumnSqlName derivedRealSqlName = derivedColumnRealName.getColumnSqlName();
        if (isFixedCondition(correlatedFixedCondition)) {
            setupUnionMainForFixedCondition(keySbtableAliasNamederivedColumnSqlName);
        } else { // no fixed condition, mainly here
            final Set<ColumnSqlNamerelatedColumnSqlSet = new HashSet<ColumnSqlName>();
            for (ColumnSqlName columnSqlName : relatedColumnSqlNames) {
                relatedColumnSqlSet.add(columnSqlName);
            }
            final ColumnSqlName derivedSqlName = derivedRealSqlName;
            final List<ColumnInfopkList = .getPrimaryInfo().getPrimaryColumnList();
            for (ColumnInfo pk : pkList) {
                final ColumnSqlName pkSqlName = pk.getColumnSqlName();
                if (pkSqlName.equals(derivedSqlName) || relatedColumnSqlSet.contains(pkSqlName)) {
                    continue// to suppress same columns selected
                }
                keySb.append(keySb.length() > 0 ? ", " : "");
                keySb.append(ColumnRealName.create(tableAliasNamepk.getColumnSqlName()));
            }
            for (ColumnSqlName relatedSqlName : relatedColumnSqlNames) {
                if (relatedSqlName.equals(derivedSqlName)) {
                    continue// to suppress same columns selected
                }
                keySb.append(keySb.length() > 0 ? ", " : "");
                keySb.append(ColumnRealName.create(tableAliasNamerelatedSqlName));
            }
        }
        setupUnionMainForDerivedColumn(keySbderivedColumnRealNamederivedColumnSqlNamederivedRealSqlName);
        return completeUnionMainWholeClause(tableAliasNamekeySb);
    }
    // ===================================================================================
    //                                                                      Derived Column
    //                                                                      ==============
    protected ColumnSqlName getDerivedColumnSqlName() {
    }
        return .getSpecifiedResolvedColumnRealNameAsOne(); // resolved calculation
    }
    // ===================================================================================
    //                                                                       Function Part
    //                                                                       =============
    protected String buildFunctionPart(String functionColumnRealName columnRealNameDerivedReferrerOption optionboolean union) {
        final String connector = buildFunctionConnector(function);
        final String columnWithEndExp;
        {
            final String aliasDef = getDerivedReferrerNestedAliasDef();
            final ColumnSqlName columnSqlName = columnRealName.getColumnSqlName();
            if (isNestedDerivedReferrer(columnSqlName)) { // e.g. select max((select ... from ...))
                // needs to resolve location path on nested query, connect it to base location
                final String sqlNameExp = columnSqlName.toString(); // no use tableAlias here because of sub-query
                final String localtionResolved = .resolveParameterLocationPath(sqlNameExp);
                final String aliasResolved = resolveNestedDerivedReferrerAliasDef(localtionResolvedaliasDef);
                columnWithEndExp = union ? resolveUnionCorrelation(aliasResolved) : aliasResolved;
            } else { // normal column derived
                // might be calculation e.g. sub1loc.DOCKSIDE_PRICE + coalesce(HUNGER_PRICE, 0)
                // so also needs to resolve location here
                final ColumnInfo derivedColumnInfo = .getSpecifiedColumnInfoAsOne();
                final String localtionResolved = .resolveParameterLocationPath(columnRealName.toString());
                columnWithEndExp = decrypt(derivedColumnInfolocaltionResolved) + ")";
            }
        }
        final String functionExp = function + connector + columnWithEndExp;
        return option.filterFunction(functionExp);
    }
    protected String resolveNestedDerivedReferrerAliasDef(String derivedExpString aliasDef) {
        return replace(derivedExpaliasDef")"); // ' as dfrelview' to ')'
    }
    protected String resolveUnionCorrelation(String derivedExp) {
        // replace e.g. ... = sub1loc.MEMBER_ID to ... = sub1main.MEMBER_ID
        final String basePointAlias = .getBasePointAliasName();
        final String mainAlias = buildSubQueryMainAliasName();
        return replace(derivedExpbasePointAliasmainAlias);
    }
    // ===================================================================================
    //                                                                       Assist Helper
    //                                                                       =============
    protected boolean isFixedCondition(String correlatedFixedCondition) {
        return correlatedFixedCondition != null && correlatedFixedCondition.trim().length() > 0;
    }
    protected boolean isNestedDerivedReferrer(String name) {
        return name.contains(getDerivedReferrerNestedAliasDef());
    }
    protected boolean isNestedDerivedReferrer(ColumnSqlName name) {
        return name.toString().contains(getDerivedReferrerNestedAliasDef());
    }
    protected String getDerivedReferrerNestedAlias() {
    }
        return " as " + getDerivedReferrerNestedAlias();
    }
    // ===================================================================================
    //                                                                    Assert/Exception
    //                                                                    ================
    protected abstract void throwDerivedReferrerInvalidColumnSpecificationException(String function);
    protected void assertDerivedReferrerColumnType(String functionString derivedColumnDbName) {
        if (derivedColumnDbName.contains(".")) {
            derivedColumnDbName = derivedColumnDbName.substring(derivedColumnDbName.lastIndexOf(".") + ".".length());
        }
        final Class<?> derivedColumnType = .findColumnInfo(derivedColumnDbName).getObjectNativeType();
        doAssertDerivedReferrerColumnType(functionderivedColumnDbNamederivedColumnType);
    }
    protected abstract void doAssertDerivedReferrerColumnType(String functionString derivedColumnDbNameClass<?> deriveColumnType);
    // ===================================================================================
    //                                                                  Function Connector
    //                                                                  ==================
    protected String buildFunctionConnector(String function) {
        if (function != null && function.endsWith("(distinct")) { // for example 'count(distinct'
            return " ";
        } else {
            return "(";
        }
    }
New to GrepCode? Check out our FAQ X