
dk.eobjects.metamodel.query.SelectItem Maven / Gradle / Ivy
/**
* This file is part of MetaModel.
*
* MetaModel is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MetaModel is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MetaModel. If not, see .
*/
package dk.eobjects.metamodel.query;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import dk.eobjects.metamodel.schema.Column;
import dk.eobjects.metamodel.schema.Table;
/**
* Represents a SELECT item. SelectItems can take different forms:
*
* - column SELECTs (selects a column from a table)
* - column function SELECTs (aggregates the values of a column)
* - expression SELECTs (retrieves data based on an expression (only supported
* for JDBC datastores)
* - expression function SELECTs (retrieves databased on a function and an
* expression, only COUNT(*) is supported for non-JDBC datastores))
* - SELECTs from subqueries (works just like column selects, but in stead of
* pointing to a column, it retrieves data from the select item of a subquery)
*
*
* @see SelectClause
*/
public class SelectItem implements IQueryItem, Cloneable {
private static final long serialVersionUID = 317475105509663973L;
private static final Log _log = LogFactory.getLog(SelectItem.class);
private Query _query;
private Column _column;
private FunctionType _function;
private String _expression;
private String _alias;
private SelectItem _subQuerySelectItem;
private FromItem _subQueryFromItem;
/**
* Generates a COUNT(*) select item
*/
public static SelectItem getCountAllItem() {
return new SelectItem(FunctionType.COUNT, "*", null);
}
public static boolean isCountAllItem(SelectItem item) {
if (item != null && item.getFunction() == FunctionType.COUNT
&& item.getExpression() == "*") {
return true;
}
return false;
}
/**
* Private constructor, used for cloning
*/
private SelectItem() {
}
/**
* Creates a simple SelectItem that selects from a column
*
* @param column
*/
public SelectItem(Column column) {
if (column == null) {
throw new IllegalArgumentException("column=null");
}
_column = column;
}
/**
* Creates a SelectItem that uses a function on a column, for example
* SUM(price) or MAX(age)
*
* @param function
* @param column
*/
public SelectItem(FunctionType function, Column column) {
this(column);
_function = function;
}
/**
* Creates a SelectItem based on an expression. All expression-based
* SelectItems must have aliases.
*
* @param expression
* @param alias
*/
public SelectItem(String expression, String alias) {
if (expression == null) {
throw new IllegalArgumentException("expression=null");
}
_expression = expression;
_alias = alias;
}
/**
* Creates a SelectItem based on a function and an expression. All
* expression-based SelectItems must have aliases.
*
* @param function
* @param expression
* @param alias
*/
public SelectItem(FunctionType function, String expression, String alias) {
this(expression, alias);
_function = function;
}
/**
* Creates a SelectItem that
*
* @param subQuerySelectItem
* @param subQueryFromItem
* the FromItem that holds the sub-query
*/
public SelectItem(SelectItem subQuerySelectItem, FromItem subQueryFromItem) {
if (subQueryFromItem.getSubQuery() == null) {
throw new IllegalArgumentException(
"Only sub-query based FromItems allowed.");
}
if (!subQuerySelectItem.getQuery().equals(
subQueryFromItem.getSubQuery())) {
throw new IllegalArgumentException(
"The SelectItem must exist in the sub-query");
}
_subQuerySelectItem = subQuerySelectItem;
_subQueryFromItem = subQueryFromItem;
}
public String getAlias() {
return _alias;
}
public SelectItem setAlias(String alias) {
_alias = alias;
return this;
}
public FunctionType getFunction() {
return _function;
}
public SelectItem setFunction(FunctionType function) {
_function = function;
return this;
}
public Column getColumn() {
return _column;
}
public String getExpression() {
return _expression;
}
public SelectItem setQuery(Query query) {
_query = query;
return this;
}
public Query getQuery() {
return _query;
}
public SelectItem getSubQuerySelectItem() {
return _subQuerySelectItem;
}
/**
* @return the name that this SelectItem can be referenced with, if
* referenced from a super-query. This will usually be the alias,
* but if there is no alias, then the column name will be used.
*/
public String getSuperQueryAlias() {
return getSuperQueryAlias(true);
}
/**
* @return the name that this SelectItem can be referenced with, if
* referenced from a super-query. This will usually be the alias,
* but if there is no alias, then the column name will be used.
*
* @param includeQuotes
* indicates whether or not the output should include quotes, if
* the select item's column has quotes associated (typically
* true, but false if used for presentation)
*/
public String getSuperQueryAlias(boolean includeQuotes) {
if (_alias != null) {
return _alias;
} else if (_column != null) {
if (includeQuotes) {
return _column.getQuotedName();
}
return _column.getName();
} else {
_log
.debug("Could not resolve a reasonable super-query alias for SelectItem: "
+ toString());
return toStringNoAlias().toString();
}
}
/**
* @return an alias that can be used in WHERE, GROUP BY and ORDER BY clauses
* in the same query
*/
public String getSameQueryAlias() {
if (_column != null) {
StringBuilder sb = new StringBuilder();
Table table = _column.getTable();
if (table != null && _query != null) {
String alias = _query.getFromClause().getAlias(table);
if (alias == null) {
alias = table.getQuotedName();
}
sb.append(alias + ".");
}
sb.append(_column.getQuotedName());
if (_function != null) {
sb.insert(0, _function + "(");
sb.append(")");
}
return sb.toString();
}
String alias = getAlias();
if (alias == null) {
alias = toStringNoAlias().toString();
_log
.warn("Could not resolve a reasonable same-query alias for SelectItem: "
+ toString());
}
return alias;
}
@Override
public String toString() {
StringBuilder sb = toStringNoAlias();
if (_alias != null) {
sb.append(" AS ");
sb.append(_alias);
}
return sb.toString();
}
public StringBuilder toStringNoAlias() {
StringBuilder sb = new StringBuilder();
if (_column != null) {
Table table = _column.getTable();
if (table != null && _query != null) {
String alias = _query.getFromClause().getAlias(table);
if (alias == null) {
alias = table.getQuotedName();
}
sb.append(alias);
sb.append(".");
}
sb.append(_column.getQuotedName());
}
if (_expression != null) {
sb.append(_expression);
}
if (_subQueryFromItem != null && _subQuerySelectItem != null) {
if (_subQueryFromItem.getAlias() != null) {
sb.append(_subQueryFromItem.getAlias() + '.');
}
sb.append(_subQuerySelectItem.getSuperQueryAlias());
}
if (_function != null) {
sb.insert(0, _function + "(");
sb.append(")");
}
return sb;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof SelectItem) {
SelectItem that = (SelectItem) obj;
EqualsBuilder eb = new EqualsBuilder();
eb.appendSuper(equalsIgnoreAlias(that));
eb.append(this._alias, that._alias);
return eb.isEquals();
}
return false;
}
public boolean equalsIgnoreAlias(SelectItem that) {
EqualsBuilder eb = new EqualsBuilder();
eb.append(this._function, that._function);
eb.append(this._expression, that._expression);
eb.append(this._column, that._column);
if (_subQuerySelectItem != null) {
eb.appendSuper(_subQuerySelectItem
.equalsIgnoreAlias(that._subQuerySelectItem));
} else {
if (that._subQuerySelectItem != null) {
eb.appendSuper(false);
}
}
return eb.isEquals();
}
@Override
public int hashCode() {
HashCodeBuilder hcb = new HashCodeBuilder();
hcb.append(_alias);
hcb.append(_column);
hcb.append(_expression);
hcb.append(_function);
hcb.append(_query);
hcb.append(_subQueryFromItem);
hcb.append(_subQuerySelectItem);
return hcb.toHashCode();
}
@Override
protected SelectItem clone() {
SelectItem s = new SelectItem();
s._alias = _alias;
s._column = _column;
s._expression = _expression;
s._function = _function;
if (_subQueryFromItem != null && _subQuerySelectItem != null) {
s._subQueryFromItem = _subQueryFromItem.clone();
s._subQuerySelectItem = _subQuerySelectItem.clone();
}
return s;
}
/**
* Investigates whether or not this SelectItem references a particular
* column. This will search for direct references and indirect references
* via subqueries.
*
* @param column
* @return a boolean that is true if the specified column is referenced by
* this SelectItem and false otherwise.
*/
public boolean isReferenced(Column column) {
if (column != null) {
if (column.equals(_column)) {
return true;
}
if (_subQuerySelectItem != null) {
return _subQuerySelectItem.isReferenced(column);
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy