You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metamodel.apache.org by ka...@apache.org on 2013/07/19 11:33:27 UTC
[44/61] [partial] Hard rename of all 'org/eobjects' folders to
'org/apache'.
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/SelectClause.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/SelectClause.java b/core/src/main/java/org/apache/metamodel/query/SelectClause.java
new file mode 100644
index 0000000..82688a5
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/SelectClause.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query;
+
+import java.util.List;
+
+import org.eobjects.metamodel.schema.Column;
+
+/**
+ * Represents the SELECT clause of a query containing SelectItems.
+ *
+ * @see SelectItem
+ */
+public class SelectClause extends AbstractQueryClause<SelectItem> {
+
+ private static final long serialVersionUID = -2458447191169901181L;
+ private boolean _distinct = false;
+
+ public SelectClause(Query query) {
+ super(query, AbstractQueryClause.PREFIX_SELECT, AbstractQueryClause.DELIM_COMMA);
+ }
+
+ public SelectItem getSelectItem(Column column) {
+ if (column != null) {
+ for (SelectItem item : getItems()) {
+ if (column.equals(item.getColumn())) {
+ return item;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String toSql(boolean includeSchemaInColumnPaths) {
+ if (getItems().size() == 0) {
+ return "";
+ }
+
+ final String sql = super.toSql(includeSchemaInColumnPaths);
+ StringBuilder sb = new StringBuilder(sql);
+ if (_distinct) {
+ sb.insert(AbstractQueryClause.PREFIX_SELECT.length(), "DISTINCT ");
+ }
+ return sb.toString();
+ }
+
+ public boolean isDistinct() {
+ return _distinct;
+ }
+
+ public void setDistinct(boolean distinct) {
+ _distinct = distinct;
+ }
+
+ @Override
+ protected void decorateIdentity(List<Object> identifiers) {
+ super.decorateIdentity(identifiers);
+ identifiers.add(_distinct);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/SelectItem.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/SelectItem.java b/core/src/main/java/org/apache/metamodel/query/SelectItem.java
new file mode 100644
index 0000000..a9b1707
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/SelectItem.java
@@ -0,0 +1,517 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query;
+
+import java.util.List;
+
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.ColumnType;
+import org.eobjects.metamodel.schema.Schema;
+import org.eobjects.metamodel.schema.Table;
+import org.eobjects.metamodel.util.BaseObject;
+import org.eobjects.metamodel.util.EqualsBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a SELECT item. SelectItems can take different forms:
+ * <ul>
+ * <li>column SELECTs (selects a column from a table)</li>
+ * <li>column function SELECTs (aggregates the values of a column)</li>
+ * <li>expression SELECTs (retrieves data based on an expression (only supported
+ * for JDBC datastores)</li>
+ * <li>expression function SELECTs (retrieves databased on a function and an
+ * expression, only COUNT(*) is supported for non-JDBC datastores))</li>
+ * <li>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)</li>
+ * </ul>
+ *
+ * @see SelectClause
+ */
+public class SelectItem extends BaseObject implements QueryItem, Cloneable {
+
+ private static final long serialVersionUID = 317475105509663973L;
+ private static final Logger logger = LoggerFactory.getLogger(SelectItem.class);
+
+ // immutable fields (essense)
+ private final Column _column;
+ private final FunctionType _function;
+ private final String _expression;
+ private final SelectItem _subQuerySelectItem;
+ private final FromItem _fromItem;
+
+ // mutable fields (tweaking)
+ private boolean _functionApproximationAllowed;
+ private Query _query;
+ private String _alias;
+
+ /**
+ * All-arguments constructor
+ *
+ * @param column
+ * @param fromItem
+ * @param function
+ * @param expression
+ * @param subQuerySelectItem
+ * @param alias
+ * @param functionApproximationAllowed
+ */
+ private SelectItem(Column column, FromItem fromItem, FunctionType function, String expression,
+ SelectItem subQuerySelectItem, String alias, boolean functionApproximationAllowed) {
+ super();
+ _column = column;
+ _fromItem = fromItem;
+ _function = function;
+ _expression = expression;
+ _subQuerySelectItem = subQuerySelectItem;
+ _alias = alias;
+ _functionApproximationAllowed = functionApproximationAllowed;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Creates a simple SelectItem that selects from a column
+ *
+ * @param column
+ */
+ public SelectItem(Column column) {
+ this(null, 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(function, column, null);
+ }
+
+ /**
+ * Creates a SelectItem that references a column from a particular
+ * {@link FromItem}, for example a.price or p.age
+ *
+ * @param column
+ * @param fromItem
+ */
+ public SelectItem(Column column, FromItem fromItem) {
+ this(null, column, fromItem);
+ if (fromItem != null) {
+ Table fromItemTable = fromItem.getTable();
+ if (fromItemTable != null) {
+ Table columnTable = column.getTable();
+ if (columnTable != null && !columnTable.equals(fromItemTable)) {
+ throw new IllegalArgumentException("Column's table '" + columnTable.getName()
+ + "' is not equal to referenced table: " + fromItemTable);
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a SelectItem that uses a function on a column from a particular
+ * {@link FromItem}, for example SUM(a.price) or MAX(p.age)
+ *
+ * @param function
+ * @param column
+ * @param fromItem
+ */
+ public SelectItem(FunctionType function, Column column, FromItem fromItem) {
+ this(column, fromItem, function, null, null, null, false);
+ if (column == null) {
+ throw new IllegalArgumentException("column=null");
+ }
+ }
+
+ /**
+ * Creates a SelectItem based on an expression. All expression-based
+ * SelectItems must have aliases.
+ *
+ * @param expression
+ * @param alias
+ */
+ public SelectItem(String expression, String alias) {
+ this(null, expression, 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(null, null, function, expression, null, alias, false);
+ if (expression == null) {
+ throw new IllegalArgumentException("expression=null");
+ }
+ }
+
+ /**
+ * Creates a SelectItem that references another select item in a subquery
+ *
+ * @param subQuerySelectItem
+ * @param subQueryFromItem
+ * the FromItem that holds the sub-query
+ */
+ public SelectItem(SelectItem subQuerySelectItem, FromItem subQueryFromItem) {
+ this(null, subQueryFromItem, null, null, subQuerySelectItem, null, false);
+ if (subQueryFromItem.getSubQuery() == null) {
+ throw new IllegalArgumentException("Only sub-query based FromItems allowed.");
+ }
+ if (subQuerySelectItem.getQuery() != null
+ && !subQuerySelectItem.getQuery().equals(subQueryFromItem.getSubQuery())) {
+ throw new IllegalArgumentException("The SelectItem must exist in the sub-query");
+ }
+ }
+
+ public String getAlias() {
+ return _alias;
+ }
+
+ public SelectItem setAlias(String alias) {
+ _alias = alias;
+ return this;
+ }
+
+ public FunctionType getFunction() {
+ return _function;
+ }
+
+ /**
+ * @return if this is a function based SelectItem where function calculation
+ * is allowed to be approximated (if the datastore type has an
+ * approximate calculation method). Approximated function results
+ * are as the name implies not exact, but might be valuable as an
+ * optimization in some cases.
+ */
+ public boolean isFunctionApproximationAllowed() {
+ return _functionApproximationAllowed;
+ }
+
+ public void setFunctionApproximationAllowed(boolean functionApproximationAllowed) {
+ _functionApproximationAllowed = functionApproximationAllowed;
+ }
+
+ public Column getColumn() {
+ return _column;
+ }
+
+ /**
+ * Tries to infer the {@link ColumnType} of this {@link SelectItem}. For
+ * expression based select items, this is not possible, and the method will
+ * return null.
+ *
+ * @return
+ */
+ public ColumnType getExpectedColumnType() {
+ if (_subQuerySelectItem != null) {
+ return _subQuerySelectItem.getExpectedColumnType();
+ }
+ if (_function != null) {
+ if (_column != null) {
+ return _function.getExpectedColumnType(_column.getType());
+ } else {
+ return _function.getExpectedColumnType(null);
+ }
+ }
+ if (_column != null) {
+ return _column.getType();
+ }
+ return null;
+ }
+
+ public String getExpression() {
+ return _expression;
+ }
+
+ public SelectItem setQuery(Query query) {
+ _query = query;
+ return this;
+ }
+
+ public Query getQuery() {
+ return _query;
+ }
+
+ public SelectItem getSubQuerySelectItem() {
+ return _subQuerySelectItem;
+ }
+
+ /**
+ * @deprecated use {@link #getFromItem()} instead
+ */
+ @Deprecated
+ public FromItem getSubQueryFromItem() {
+ return _fromItem;
+ }
+
+ public FromItem getFromItem() {
+ return _fromItem;
+ }
+
+ /**
+ * @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) {
+ final StringBuilder sb = new StringBuilder();
+ if (_function != null) {
+ sb.append(_function.toString());
+ sb.append('(');
+ }
+ if (includeQuotes) {
+ sb.append(_column.getQuotedName());
+ } else {
+ sb.append(_column.getName());
+ }
+ if (_function != null) {
+ sb.append(')');
+ }
+ return sb.toString();
+ } else {
+ logger.debug("Could not resolve a reasonable super-query alias for SelectItem: {}", toSql());
+ return toStringNoAlias().toString();
+ }
+ }
+
+ public String getSameQueryAlias() {
+ return getSameQueryAlias(false);
+ }
+
+ /**
+ * @return an alias that can be used in WHERE, GROUP BY and ORDER BY clauses
+ * in the same query
+ */
+ public String getSameQueryAlias(boolean includeSchemaInColumnPath) {
+ if (_column != null) {
+ StringBuilder sb = new StringBuilder();
+ String columnPrefix = getToStringColumnPrefix(includeSchemaInColumnPath);
+ sb.append(columnPrefix);
+ sb.append(_column.getQuotedName());
+ if (_function != null) {
+ sb.insert(0, _function + "(");
+ sb.append(")");
+ }
+ return sb.toString();
+ }
+ String alias = getAlias();
+ if (alias == null) {
+ alias = toStringNoAlias(includeSchemaInColumnPath).toString();
+ logger.debug("Could not resolve a reasonable same-query alias for SelectItem: {}", toSql());
+ }
+ return alias;
+ }
+
+ @Override
+ public String toSql() {
+ return toSql(false);
+ }
+
+ @Override
+ public String toSql(boolean includeSchemaInColumnPath) {
+ StringBuilder sb = toStringNoAlias(includeSchemaInColumnPath);
+ if (_alias != null) {
+ sb.append(" AS ");
+ sb.append(_alias);
+ }
+ return sb.toString();
+ }
+
+ public StringBuilder toStringNoAlias() {
+ return toStringNoAlias(false);
+ }
+
+ public StringBuilder toStringNoAlias(boolean includeSchemaInColumnPath) {
+ StringBuilder sb = new StringBuilder();
+ if (_column != null) {
+ sb.append(getToStringColumnPrefix(includeSchemaInColumnPath));
+ sb.append(_column.getQuotedName());
+ }
+ if (_expression != null) {
+ sb.append(_expression);
+ }
+ if (_fromItem != null && _subQuerySelectItem != null) {
+ if (_fromItem.getAlias() != null) {
+ sb.append(_fromItem.getAlias() + '.');
+ }
+ sb.append(_subQuerySelectItem.getSuperQueryAlias());
+ }
+ if (_function != null) {
+ sb.insert(0, _function + "(");
+ sb.append(")");
+ }
+ return sb;
+ }
+
+ private String getToStringColumnPrefix(boolean includeSchemaInColumnPath) {
+ StringBuilder sb = new StringBuilder();
+ if (_fromItem != null && _fromItem.getAlias() != null) {
+ sb.append(_fromItem.getAlias());
+ sb.append('.');
+ } else {
+ final Table table = _column.getTable();
+ String tableLabel;
+ if (_query == null) {
+ tableLabel = null;
+ } else {
+ tableLabel = _query.getFromClause().getAlias(table);
+ }
+ if (table != null) {
+ if (tableLabel == null) {
+ tableLabel = table.getQuotedName();
+ if (includeSchemaInColumnPath) {
+ Schema schema = table.getSchema();
+ if (schema != null) {
+ tableLabel = schema.getQuotedName() + "." + tableLabel;
+ }
+ }
+ }
+ sb.append(tableLabel);
+ sb.append('.');
+ }
+ }
+ return sb.toString();
+ }
+
+ public boolean equalsIgnoreAlias(SelectItem that) {
+ return equalsIgnoreAlias(that, false);
+ }
+
+ public boolean equalsIgnoreAlias(SelectItem that, boolean exactColumnCompare) {
+ if (that == null) {
+ return false;
+ }
+ if (that == this) {
+ return true;
+ }
+
+ EqualsBuilder eb = new EqualsBuilder();
+ if (exactColumnCompare) {
+ eb.append(this._column == that._column);
+ eb.append(this._fromItem, that._fromItem);
+ } else {
+ eb.append(this._column, that._column);
+ }
+ eb.append(this._function, that._function);
+ eb.append(this._functionApproximationAllowed, that._functionApproximationAllowed);
+ eb.append(this._expression, that._expression);
+ if (_subQuerySelectItem != null) {
+ eb.append(_subQuerySelectItem.equalsIgnoreAlias(that._subQuerySelectItem));
+ } else {
+ if (that._subQuerySelectItem != null) {
+ eb.append(false);
+ }
+ }
+ return eb.isEquals();
+ }
+
+ @Override
+ protected void decorateIdentity(List<Object> identifiers) {
+ identifiers.add(_expression);
+ identifiers.add(_alias);
+ identifiers.add(_column);
+ identifiers.add(_function);
+ identifiers.add(_functionApproximationAllowed);
+ identifiers.add(_fromItem);
+ identifiers.add(_subQuerySelectItem);
+ }
+
+ @Override
+ protected SelectItem clone() {
+ final SelectItem subQuerySelectItem = (_subQuerySelectItem == null ? null : _subQuerySelectItem.clone());
+ final FromItem fromItem = (_fromItem == null ? null : _fromItem.clone());
+ final SelectItem s = new SelectItem(_column, fromItem, _function, _expression, subQuerySelectItem, _alias,
+ _functionApproximationAllowed);
+ return s;
+ }
+
+ /**
+ * Creates a copy of the {@link SelectItem}, with a different
+ * {@link FunctionType}.
+ *
+ * @param function
+ * @return
+ */
+ public SelectItem replaceFunction(FunctionType function) {
+ return new SelectItem(_column, _fromItem, function, _expression, _subQuerySelectItem, _alias,
+ _functionApproximationAllowed);
+ }
+
+ /**
+ * 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;
+ }
+
+ @Override
+ public String toString() {
+ return toSql();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/SumAggregateBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/SumAggregateBuilder.java b/core/src/main/java/org/apache/metamodel/query/SumAggregateBuilder.java
new file mode 100644
index 0000000..2cf8811
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/SumAggregateBuilder.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query;
+
+import org.eobjects.metamodel.util.AggregateBuilder;
+import org.eobjects.metamodel.util.NumberComparator;
+
+final class SumAggregateBuilder implements AggregateBuilder<Double> {
+
+ private double sum;
+
+ @Override
+ public void add(Object o) {
+ if (o == null) {
+ return;
+ }
+ Number number = NumberComparator.toNumber(o);
+ if (number == null) {
+ throw new IllegalArgumentException("Could not convert to number: " + o);
+ }
+ sum += number.doubleValue();
+ }
+
+ @Override
+ public Double getAggregate() {
+ return sum;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/AbstractFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/AbstractFilterBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/AbstractFilterBuilder.java
new file mode 100644
index 0000000..2d3bd25
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/AbstractFilterBuilder.java
@@ -0,0 +1,459 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.Collection;
+import java.util.Date;
+
+import org.eobjects.metamodel.query.FilterItem;
+import org.eobjects.metamodel.query.OperatorType;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.Column;
+
+/**
+ * Abstract implementation of {@link FilterBuilder} interface. All built filters
+ * are channeled to the {@link #applyFilter(FilterItem)} method which needs to
+ * be implemented by concrete implementations.
+ */
+public abstract class AbstractFilterBuilder<B> implements FilterBuilder<B> {
+
+ private final SelectItem _selectItem;
+
+ public AbstractFilterBuilder(SelectItem selectItem) {
+ this._selectItem = selectItem;
+ }
+
+ protected abstract B applyFilter(FilterItem filter);
+
+ /**
+ * Provides a way to
+ *
+ * @param queryParameter
+ * @return
+ */
+ public B applyFilter(OperatorType operator, Object operand) {
+ return applyFilter(new FilterItem(_selectItem, operator, operand));
+ }
+
+ @Override
+ public B in(Collection<?> values) {
+ return applyFilter(new FilterItem(_selectItem, OperatorType.IN, values));
+ }
+
+ @Override
+ public B in(Number... numbers) {
+ return applyFilter(new FilterItem(_selectItem, OperatorType.IN, numbers));
+ }
+
+ @Override
+ public B in(String... strings) {
+ return applyFilter(new FilterItem(_selectItem, OperatorType.IN, strings));
+ }
+
+ @Override
+ public B isNull() {
+ return applyFilter(new FilterItem(_selectItem, OperatorType.EQUALS_TO, null));
+ }
+
+ @Override
+ public B isNotNull() {
+ return applyFilter(new FilterItem(_selectItem, OperatorType.DIFFERENT_FROM, null));
+ }
+
+ @Override
+ public B isEquals(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.EQUALS_TO, new SelectItem(column)));
+ }
+
+ @Override
+ public B isEquals(Date date) {
+ if (date == null) {
+ throw new IllegalArgumentException("date cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.EQUALS_TO, date));
+ }
+
+ @Override
+ public B isEquals(Number number) {
+ if (number == null) {
+ throw new IllegalArgumentException("number cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.EQUALS_TO, number));
+ }
+
+ @Override
+ public B isEquals(String string) {
+ if (string == null) {
+ throw new IllegalArgumentException("string cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.EQUALS_TO, string));
+ }
+
+ @Override
+ public B isEquals(Boolean bool) {
+ if (bool == null) {
+ throw new IllegalArgumentException("bool cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.EQUALS_TO, bool));
+ }
+
+ @Override
+ public B isEquals(Object obj) {
+ if (obj == null) {
+ return isNull();
+ }
+ if (obj instanceof Boolean) {
+ return isEquals((Boolean) obj);
+ }
+ if (obj instanceof Number) {
+ return isEquals((Number) obj);
+ }
+ if (obj instanceof Date) {
+ return isEquals((Date) obj);
+ }
+ if (obj instanceof String) {
+ return isEquals((String) obj);
+ }
+ throw new UnsupportedOperationException("Argument must be a Boolean, Number, Date or String. Found: " + obj);
+ }
+
+ @Override
+ public B differentFrom(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.DIFFERENT_FROM, new SelectItem(column)));
+ }
+
+ @Override
+ public B differentFrom(Date date) {
+ if (date == null) {
+ throw new IllegalArgumentException("date cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.DIFFERENT_FROM, date));
+ }
+
+ @Override
+ public B differentFrom(Number number) {
+ if (number == null) {
+ throw new IllegalArgumentException("number cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.DIFFERENT_FROM, number));
+ }
+
+ @Override
+ public B differentFrom(String string) {
+ if (string == null) {
+ throw new IllegalArgumentException("string cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.DIFFERENT_FROM, string));
+ }
+
+ @Override
+ public B differentFrom(Boolean bool) {
+ if (bool == null) {
+ throw new IllegalArgumentException("bool cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.DIFFERENT_FROM, bool));
+ }
+
+ @Override
+ public B differentFrom(Object obj) {
+ if (obj == null) {
+ return isNotNull();
+ }
+ if (obj instanceof Boolean) {
+ return differentFrom((Boolean) obj);
+ }
+ if (obj instanceof Number) {
+ return differentFrom((Number) obj);
+ }
+ if (obj instanceof Date) {
+ return differentFrom((Date) obj);
+ }
+ if (obj instanceof String) {
+ return differentFrom((String) obj);
+ }
+ throw new UnsupportedOperationException("Argument must be a Boolean, Number, Date or String. Found: " + obj);
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(Column arg) {
+ return greaterThan(arg);
+ }
+
+ @Override
+ public B greaterThan(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.GREATER_THAN, new SelectItem(column)));
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(Date arg) {
+ return greaterThan(arg);
+ }
+
+ @Override
+ public B greaterThan(Date date) {
+ if (date == null) {
+ throw new IllegalArgumentException("date cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.GREATER_THAN, date));
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(Number arg) {
+ return greaterThan(arg);
+ }
+
+ @Override
+ public B greaterThan(Number number) {
+ if (number == null) {
+ throw new IllegalArgumentException("number cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.GREATER_THAN, number));
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(String arg) {
+ return greaterThan(arg);
+ }
+
+ @Override
+ public B greaterThan(String string) {
+ if (string == null) {
+ throw new IllegalArgumentException("string cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.GREATER_THAN, string));
+ }
+
+ @Override
+ public B lessThan(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.LESS_THAN, new SelectItem(column)));
+ }
+
+ @Override
+ public B lessThan(Date date) {
+ if (date == null) {
+ throw new IllegalArgumentException("date cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.LESS_THAN, date));
+ }
+
+ @Override
+ public B lessThan(Number number) {
+ if (number == null) {
+ throw new IllegalArgumentException("number cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.LESS_THAN, number));
+ }
+
+ @Override
+ public B lessThan(String string) {
+ if (string == null) {
+ throw new IllegalArgumentException("string cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.LESS_THAN, string));
+ }
+
+ @Override
+ public B lessThan(Object obj) {
+ if (obj instanceof Number) {
+ return lessThan((Number) obj);
+ }
+ if (obj instanceof Date) {
+ return lessThan((Date) obj);
+ }
+ if (obj instanceof String) {
+ return lessThan((String) obj);
+ }
+ throw new UnsupportedOperationException("Argument must be a Number, Date or String. Found: " + obj);
+ }
+
+ @Override
+ public B greaterThan(Object obj) {
+ if (obj instanceof Number) {
+ return greaterThan((Number) obj);
+ }
+ if (obj instanceof Date) {
+ return greaterThan((Date) obj);
+ }
+ if (obj instanceof String) {
+ return greaterThan((String) obj);
+ }
+ throw new UnsupportedOperationException("Argument must be a Number, Date or String. Found: " + obj);
+ }
+
+ @Override
+ public B like(String string) {
+ if (string == null) {
+ throw new IllegalArgumentException("string cannot be null");
+ }
+ return applyFilter(new FilterItem(_selectItem, OperatorType.LIKE, string));
+ }
+
+ @Override
+ public B gt(Column column) {
+ return greaterThan(column);
+ }
+
+ @Override
+ public B gt(Date date) {
+ return greaterThan(date);
+ }
+
+ @Override
+ public B gt(Number number) {
+ return greaterThan(number);
+ }
+
+ @Override
+ public B gt(String string) {
+ return greaterThan(string);
+ }
+
+ @Override
+ public B lt(Column column) {
+ return lessThan(column);
+ }
+
+ public B lt(Date date) {
+ return lessThan(date);
+ };
+
+ public B lt(Number number) {
+ return lessThan(number);
+ };
+
+ public B lt(String string) {
+ return lessThan(string);
+ };
+
+ @Override
+ public B eq(Boolean bool) {
+ return isEquals(bool);
+ }
+
+ @Override
+ public B eq(Column column) {
+ return isEquals(column);
+ }
+
+ @Override
+ public B eq(Date date) {
+ return isEquals(date);
+ }
+
+ @Override
+ public B eq(Number number) {
+ return isEquals(number);
+ }
+
+ @Override
+ public B eq(String string) {
+ return isEquals(string);
+ }
+
+ @Override
+ public B eq(Object obj) {
+ return isEquals(obj);
+ }
+
+ @Override
+ public B ne(Boolean bool) {
+ return differentFrom(bool);
+ }
+
+ @Override
+ public B ne(Column column) {
+ return differentFrom(column);
+ }
+
+ @Override
+ public B ne(Date date) {
+ return differentFrom(date);
+ }
+
+ @Override
+ public B ne(Number number) {
+ return differentFrom(number);
+ }
+
+ @Override
+ public B ne(String string) {
+ return differentFrom(string);
+ }
+
+ @Override
+ public B ne(Object obj) {
+ return differentFrom(obj);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Boolean bool) {
+ return isEquals(bool);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Column column) {
+ return isEquals(column);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Date date) {
+ return isEquals(date);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Number number) {
+ return isEquals(number);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(String string) {
+ return isEquals(string);
+ }
+
+ @Override
+ public B lt(Object obj) {
+ return lessThan(obj);
+ }
+
+ @Override
+ public B gt(Object obj) {
+ return greaterThan(obj);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/AbstractQueryFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/AbstractQueryFilterBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/AbstractQueryFilterBuilder.java
new file mode 100644
index 0000000..a015292
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/AbstractQueryFilterBuilder.java
@@ -0,0 +1,344 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.Collection;
+import java.util.Date;
+
+import org.eobjects.metamodel.query.FilterItem;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.Column;
+
+abstract class AbstractQueryFilterBuilder<B> extends GroupedQueryBuilderCallback implements FilterBuilder<B> {
+
+ protected final AbstractFilterBuilder<B> _filterBuilder;
+
+ public AbstractQueryFilterBuilder(SelectItem selectItem, GroupedQueryBuilder queryBuilder) {
+ super(queryBuilder);
+ _filterBuilder = new AbstractFilterBuilder<B>(selectItem) {
+ @Override
+ protected B applyFilter(FilterItem filter) {
+ return AbstractQueryFilterBuilder.this.applyFilter(filter);
+ }
+ };
+ }
+
+ protected abstract B applyFilter(FilterItem filter);
+
+ @Override
+ public B in(Collection<?> values) {
+ return _filterBuilder.in(values);
+ }
+
+ @Override
+ public B in(Number... numbers) {
+ return _filterBuilder.in(numbers);
+ }
+
+ @Override
+ public B in(String... strings) {
+ return _filterBuilder.in(strings);
+ }
+
+ @Override
+ public B isNull() {
+ return _filterBuilder.isNull();
+ }
+
+ @Override
+ public B isNotNull() {
+ return _filterBuilder.isNotNull();
+ }
+
+ @Override
+ public B isEquals(Column column) {
+ return _filterBuilder.isEquals(column);
+ }
+
+ @Override
+ public B isEquals(Date date) {
+ return _filterBuilder.isEquals(date);
+ }
+
+ @Override
+ public B isEquals(Number number) {
+ return _filterBuilder.isEquals(number);
+ }
+
+ @Override
+ public B isEquals(String string) {
+ return _filterBuilder.isEquals(string);
+ }
+
+ @Override
+ public B isEquals(Boolean bool) {
+ return _filterBuilder.isEquals(bool);
+ }
+
+ @Override
+ public B isEquals(Object obj) {
+ return _filterBuilder.isEquals(obj);
+ }
+
+ @Override
+ public B differentFrom(Column column) {
+ return _filterBuilder.differentFrom(column);
+ }
+
+ @Override
+ public B differentFrom(Date date) {
+ return _filterBuilder.differentFrom(date);
+ }
+
+ @Override
+ public B differentFrom(Number number) {
+ return _filterBuilder.differentFrom(number);
+ }
+
+ @Override
+ public B differentFrom(String string) {
+ return _filterBuilder.differentFrom(string);
+ }
+
+ @Override
+ public B differentFrom(Boolean bool) {
+ return _filterBuilder.differentFrom(bool);
+ }
+
+ @Override
+ public B differentFrom(Object obj) {
+ return _filterBuilder.differentFrom(obj);
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(Column arg) {
+ return _filterBuilder.higherThan(arg);
+ }
+
+ public B greaterThan(Column column) {
+ return _filterBuilder.greaterThan(column);
+ }
+
+ @Override
+ public B greaterThan(Object obj) {
+ return _filterBuilder.greaterThan(obj);
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(Date arg) {
+ return _filterBuilder.higherThan(arg);
+ }
+
+ @Override
+ public B greaterThan(Date date) {
+ return _filterBuilder.greaterThan(date);
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(Number arg) {
+ return _filterBuilder.higherThan(arg);
+ }
+
+ @Override
+ public B greaterThan(Number number) {
+ return _filterBuilder.greaterThan(number);
+ }
+
+ @Deprecated
+ @Override
+ public B higherThan(String arg) {
+ return _filterBuilder.higherThan(arg);
+ }
+
+ @Override
+ public B greaterThan(String string) {
+ return _filterBuilder.greaterThan(string);
+ }
+
+ @Override
+ public B lessThan(Column column) {
+ return _filterBuilder.lessThan(column);
+ }
+
+ @Override
+ public B lessThan(Date date) {
+ return _filterBuilder.lessThan(date);
+ }
+
+ @Override
+ public B lessThan(Number number) {
+ return _filterBuilder.lessThan(number);
+ }
+
+ @Override
+ public B lessThan(String string) {
+ return _filterBuilder.lessThan(string);
+ }
+
+ @Override
+ public B lessThan(Object obj) {
+ return _filterBuilder.lessThan(obj);
+ }
+
+ @Override
+ public B like(String string) {
+ return _filterBuilder.like(string);
+ }
+
+ @Override
+ public B gt(Column column) {
+ return greaterThan(column);
+ }
+
+ @Override
+ public B gt(Date date) {
+ return greaterThan(date);
+ }
+
+ @Override
+ public B gt(Number number) {
+ return greaterThan(number);
+ }
+
+ @Override
+ public B gt(String string) {
+ return greaterThan(string);
+ }
+
+ @Override
+ public B lt(Column column) {
+ return lessThan(column);
+ }
+
+ public B lt(Date date) {
+ return lessThan(date);
+ };
+
+ public B lt(Number number) {
+ return lessThan(number);
+ };
+
+ public B lt(String string) {
+ return lessThan(string);
+ };
+
+ @Override
+ public B eq(Boolean bool) {
+ return isEquals(bool);
+ }
+
+ @Override
+ public B eq(Column column) {
+ return isEquals(column);
+ }
+
+ @Override
+ public B eq(Date date) {
+ return isEquals(date);
+ }
+
+ @Override
+ public B eq(Number number) {
+ return isEquals(number);
+ }
+
+ @Override
+ public B eq(String string) {
+ return isEquals(string);
+ }
+
+ @Override
+ public B eq(Object obj) {
+ return isEquals(obj);
+ }
+
+ @Override
+ public B ne(Boolean bool) {
+ return differentFrom(bool);
+ }
+
+ @Override
+ public B ne(Column column) {
+ return differentFrom(column);
+ }
+
+ @Override
+ public B ne(Date date) {
+ return differentFrom(date);
+ }
+
+ @Override
+ public B ne(Number number) {
+ return differentFrom(number);
+ }
+
+ @Override
+ public B ne(String string) {
+ return differentFrom(string);
+ }
+
+ @Override
+ public B ne(Object obj) {
+ return differentFrom(obj);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Boolean bool) {
+ return isEquals(bool);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Column column) {
+ return isEquals(column);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Date date) {
+ return isEquals(date);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(Number number) {
+ return isEquals(number);
+ }
+
+ @Override
+ @Deprecated
+ public B equals(String string) {
+ return isEquals(string);
+ }
+
+ @Override
+ public B lt(Object obj) {
+ return lessThan(obj);
+ }
+
+ @Override
+ public B gt(Object obj) {
+ return greaterThan(obj);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilder.java
new file mode 100644
index 0000000..00208cf
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilder.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+public interface ColumnSelectBuilder<B extends SatisfiedQueryBuilder<?>>
+ extends SatisfiedSelectBuilder<B> {
+
+ public B as(String alias);
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilderImpl.java b/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilderImpl.java
new file mode 100644
index 0000000..161a36f
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/ColumnSelectBuilderImpl.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.List;
+
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.Column;
+
+final class ColumnSelectBuilderImpl extends SatisfiedSelectBuilderImpl
+ implements ColumnSelectBuilder<GroupedQueryBuilder> {
+
+ private SelectItem selectItem;
+
+ public ColumnSelectBuilderImpl(Column column, Query query,
+ GroupedQueryBuilder queryBuilder) {
+ super(queryBuilder);
+ this.selectItem = new SelectItem(column);
+
+ query.select(selectItem);
+ }
+
+ @Override
+ public GroupedQueryBuilder as(String alias) {
+ if (alias == null) {
+ throw new IllegalArgumentException("alias cannot be null");
+ }
+ selectItem.setAlias(alias);
+ return getQueryBuilder();
+ }
+
+ @Override
+ protected void decorateIdentity(List<Object> identifiers) {
+ super.decorateIdentity(identifiers);
+ identifiers.add(selectItem);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilder.java
new file mode 100644
index 0000000..61dd73d
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilder.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+public interface CountSelectBuilder<B extends SatisfiedQueryBuilder<?>> extends
+ SatisfiedSelectBuilder<B> {
+
+ public B as(String alias);
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilderImpl.java b/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilderImpl.java
new file mode 100644
index 0000000..e2114b2
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/CountSelectBuilderImpl.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.List;
+
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.query.SelectItem;
+
+final class CountSelectBuilderImpl extends SatisfiedSelectBuilderImpl implements
+ CountSelectBuilder<GroupedQueryBuilder> {
+
+ private SelectItem selectItem;
+
+ public CountSelectBuilderImpl(Query query, GroupedQueryBuilder queryBuilder) {
+ super(queryBuilder);
+ this.selectItem = SelectItem.getCountAllItem();
+ query.select(selectItem);
+ }
+
+ @Override
+ public GroupedQueryBuilder as(String alias) {
+ if (alias == null) {
+ throw new IllegalArgumentException("alias cannot be null");
+ }
+ selectItem.setAlias(alias);
+ return getQueryBuilder();
+ }
+
+ @Override
+ protected void decorateIdentity(List<Object> identifiers) {
+ super.decorateIdentity(identifiers);
+ identifiers.add(selectItem);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/FilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/FilterBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/FilterBuilder.java
new file mode 100644
index 0000000..01a09cc
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/FilterBuilder.java
@@ -0,0 +1,355 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.Collection;
+import java.util.Date;
+
+import org.eobjects.metamodel.schema.Column;
+
+/**
+ * Interface for builder callbacks that "respond" to filter condition building.
+ *
+ * @param <B>
+ * the builder type to return once filter has been created.
+ */
+public interface FilterBuilder<B> {
+
+ /**
+ * Not null
+ */
+ public B isNull();
+
+ /**
+ * Is not null
+ */
+ public B isNotNull();
+
+ /**
+ * In ...
+ */
+ public B in(Collection<?> values);
+
+ /**
+ * In ...
+ */
+ public B in(Number... numbers);
+
+ /**
+ * In ...
+ */
+ public B in(String... strings);
+
+ /**
+ * Like ...
+ *
+ * (use '%' as wildcard).
+ */
+ public B like(String string);
+
+ /**
+ * Equal to ...
+ */
+ public B eq(Column column);
+
+ /**
+ * Equal to ...
+ */
+ public B eq(Date date);
+
+ /**
+ * Equal to ...
+ */
+ public B eq(Number number);
+
+ /**
+ * Equal to ...
+ */
+ public B eq(String string);
+
+ /**
+ * Equal to ...
+ */
+ public B eq(Boolean bool);
+
+ /**
+ * Equal to ...
+ */
+ public B eq(Object obj);
+
+ /**
+ * Equal to ...
+ */
+ public B isEquals(Column column);
+
+ /**
+ * Equal to ...
+ */
+ public B isEquals(Date date);
+
+ /**
+ * Equal to ...
+ */
+ public B isEquals(Number number);
+
+ /**
+ * Equal to ...
+ */
+ public B isEquals(String string);
+
+ /**
+ * Equal to ...
+ */
+ public B isEquals(Boolean bool);
+
+ /**
+ * Equal to ...
+ */
+ public B isEquals(Object obj);
+
+ /**
+ * Equal to ...
+ *
+ * @deprecated use 'eq' or 'isEquals' instead.
+ */
+ @Deprecated
+ public B equals(Column column);
+
+ /**
+ * Equal to ...
+ *
+ * @deprecated use 'eq' or 'isEquals' instead.
+ */
+ @Deprecated
+ public B equals(Date date);
+
+ /**
+ * Equal to ...
+ *
+ * @deprecated use 'eq' or 'isEquals' instead.
+ */
+ @Deprecated
+ public B equals(Number number);
+
+ /**
+ * Equal to ...
+ *
+ * @deprecated use 'eq' or 'isEquals' instead.
+ */
+ @Deprecated
+ public B equals(String string);
+
+ /**
+ * Equal to ...
+ *
+ * @deprecated use 'eq' or 'isEquals' instead.
+ */
+ @Deprecated
+ public B equals(Boolean bool);
+
+ /**
+ * Not equal to ...
+ */
+ public B differentFrom(Column column);
+
+ /**
+ * Not equal to ...
+ */
+ public B differentFrom(Date date);
+
+ /**
+ * Not equal to ...
+ */
+ public B differentFrom(Number number);
+
+ /**
+ * Not equal to ...
+ */
+ public B differentFrom(String string);
+
+ /**
+ * Not equal to ...
+ */
+ public B differentFrom(Boolean bool);
+
+ /**
+ * Not equal to ...
+ */
+ public B differentFrom(Object obj);
+
+ /**
+ * Not equal to ...
+ */
+ public B ne(Column column);
+
+ /**
+ * Not equal to ...
+ */
+ public B ne(Date date);
+
+ /**
+ * Not equal to ...
+ */
+ public B ne(Number number);
+
+ /**
+ * Not equal to ...
+ */
+ public B ne(String string);
+
+ /**
+ * Not equal to ...
+ */
+ public B ne(Boolean bool);
+
+ /**
+ * Not equal to ...
+ */
+ public B ne(Object obj);
+
+ /**
+ * Greater than ...
+ *
+ * @deprecated use {@link #greaterThan(Column)} instead
+ */
+ @Deprecated
+ public B higherThan(Column column);
+
+ /**
+ * Greater than ...
+ */
+ public B greaterThan(Column column);
+
+ /**
+ * Greater than ...
+ */
+ public B gt(Column column);
+
+ /**
+ * Greater than ...
+ */
+ public B greaterThan(Object obj);
+
+ /**
+ * Greater than ...
+ */
+ public B gt(Object obj);
+
+ /**
+ * Greater than ...
+ *
+ * @deprecated use {@link #greaterThan(Date)} instead
+ */
+ @Deprecated
+ public B higherThan(Date date);
+
+ /**
+ * Greater than ...
+ */
+ public B greaterThan(Date date);
+
+ /**
+ * Greater than ...
+ */
+ public B gt(Date date);
+
+ /**
+ * @deprecated use {@link #greaterThan(Number)} instead
+ */
+ @Deprecated
+ public B higherThan(Number number);
+
+ /**
+ * Greater than ...
+ */
+ public B greaterThan(Number number);
+
+ /**
+ * Greater than ...
+ */
+ public B gt(Number number);
+
+ /**
+ * Greater than ...
+ *
+ * @deprecated use {@link #greaterThan(String)} instead
+ */
+ @Deprecated
+ public B higherThan(String string);
+
+ /**
+ * Greater than ...
+ */
+ public B greaterThan(String string);
+
+ /**
+ * Greater than ...
+ */
+ public B gt(String string);
+
+ /**
+ * Less than ...
+ */
+ public B lessThan(Column column);
+
+ /**
+ * Less than ...
+ */
+ public B lt(Column column);
+
+ /**
+ * Less than ...
+ */
+ public B lessThan(Date date);
+
+ /**
+ * Less than ...
+ */
+ public B lessThan(Number number);
+
+ /**
+ * Less than ...
+ */
+ public B lessThan(String string);
+
+ /**
+ * Less than ...
+ */
+ public B lessThan(Object obj);
+
+ /**
+ * Less than ...
+ */
+ public B lt(Object obj);
+
+ /**
+ * Less than ...
+ */
+ public B lt(Date date);
+
+ /**
+ * Less than ...
+ */
+ public B lt(Number number);
+
+ /**
+ * Less than ...
+ */
+ public B lt(String string);
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilder.java
new file mode 100644
index 0000000..516ce5e
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilder.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+public interface FunctionSelectBuilder<B extends SatisfiedQueryBuilder<?>>
+ extends SatisfiedSelectBuilder<B> {
+
+ public B as(String alias);
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilderImpl.java b/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilderImpl.java
new file mode 100644
index 0000000..68e9b39
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/FunctionSelectBuilderImpl.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.List;
+
+import org.eobjects.metamodel.query.FunctionType;
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.Column;
+
+final class FunctionSelectBuilderImpl extends SatisfiedSelectBuilderImpl
+ implements FunctionSelectBuilder<GroupedQueryBuilder> {
+
+ private SelectItem selectItem;
+
+ public FunctionSelectBuilderImpl(FunctionType functionType, Column column,
+ Query query, GroupedQueryBuilder queryBuilder) {
+ super(queryBuilder);
+
+ this.selectItem = new SelectItem(functionType, column);
+
+ query.select(selectItem);
+ }
+
+ @Override
+ public GroupedQueryBuilder as(String alias) {
+ if (alias == null) {
+ throw new IllegalArgumentException("alias cannot be null");
+ }
+ selectItem.setAlias(alias);
+ return getQueryBuilder();
+ }
+
+ @Override
+ protected void decorateIdentity(List<Object> identifiers) {
+ super.decorateIdentity(identifiers);
+ identifiers.add(selectItem);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilder.java
new file mode 100644
index 0000000..d798d9b
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilder.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import org.eobjects.metamodel.query.FunctionType;
+import org.eobjects.metamodel.schema.Column;
+
+/**
+ * Represents a built query that has a GROUP BY clause.
+ *
+ * @author Kasper Sørensen
+ *
+ */
+public interface GroupedQueryBuilder extends
+ SatisfiedQueryBuilder<GroupedQueryBuilder> {
+
+ public HavingBuilder having(FunctionType functionType, Column column);
+
+ public SatisfiedOrderByBuilder<GroupedQueryBuilder> orderBy(
+ FunctionType function, Column column);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderCallback.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderCallback.java b/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderCallback.java
new file mode 100644
index 0000000..6db7feb
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderCallback.java
@@ -0,0 +1,168 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.List;
+
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.query.CompiledQuery;
+import org.eobjects.metamodel.query.FilterItem;
+import org.eobjects.metamodel.query.FunctionType;
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.util.BaseObject;
+
+abstract class GroupedQueryBuilderCallback extends BaseObject implements GroupedQueryBuilder {
+
+ private GroupedQueryBuilder queryBuilder;
+
+ public GroupedQueryBuilderCallback(GroupedQueryBuilder queryBuilder) {
+ this.queryBuilder = queryBuilder;
+ }
+
+ protected GroupedQueryBuilder getQueryBuilder() {
+ return queryBuilder;
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> firstRow(int firstRow) {
+ return getQueryBuilder().firstRow(firstRow);
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> limit(int maxRows) {
+ return getQueryBuilder().limit(maxRows);
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> offset(int offset) {
+ return getQueryBuilder().offset(offset);
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> maxRows(int maxRows) {
+ return getQueryBuilder().maxRows(maxRows);
+ }
+
+ @Override
+ public SatisfiedSelectBuilder<GroupedQueryBuilder> select(Column... columns) {
+ return getQueryBuilder().select(columns);
+ }
+
+ @Override
+ public final Column findColumn(String columnName) throws IllegalArgumentException {
+ return getQueryBuilder().findColumn(columnName);
+ }
+
+ @Override
+ public ColumnSelectBuilder<GroupedQueryBuilder> select(Column column) {
+ return getQueryBuilder().select(column);
+ }
+
+ @Override
+ public FunctionSelectBuilder<GroupedQueryBuilder> select(FunctionType functionType, Column column) {
+ return getQueryBuilder().select(functionType, column);
+ }
+
+ @Override
+ public ColumnSelectBuilder<GroupedQueryBuilder> select(String columnName) {
+ return getQueryBuilder().select(columnName);
+ }
+
+ @Override
+ public CountSelectBuilder<GroupedQueryBuilder> selectCount() {
+ return getQueryBuilder().selectCount();
+ }
+
+ @Override
+ public WhereBuilder<GroupedQueryBuilder> where(Column column) {
+ return getQueryBuilder().where(column);
+ }
+
+ @Override
+ public SatisfiedOrderByBuilder<GroupedQueryBuilder> orderBy(Column column) {
+ return getQueryBuilder().orderBy(column);
+ }
+
+ @Override
+ public GroupedQueryBuilder groupBy(String columnName) {
+ return getQueryBuilder().groupBy(columnName);
+ }
+
+ @Override
+ public GroupedQueryBuilder groupBy(Column column) {
+ return getQueryBuilder().groupBy(column);
+ }
+
+ @Override
+ public Query toQuery() {
+ return getQueryBuilder().toQuery();
+ }
+
+ @Override
+ public CompiledQuery compile() {
+ return getQueryBuilder().compile();
+ }
+
+ @Override
+ public HavingBuilder having(FunctionType functionType, Column column) {
+ return getQueryBuilder().having(functionType, column);
+ }
+
+ @Override
+ public GroupedQueryBuilder groupBy(Column... columns) {
+ getQueryBuilder().groupBy(columns);
+ return this;
+ }
+
+ @Override
+ protected void decorateIdentity(List<Object> identifiers) {
+ identifiers.add(queryBuilder);
+ }
+
+ @Override
+ public DataSet execute() {
+ return queryBuilder.execute();
+ }
+
+ @Override
+ public WhereBuilder<GroupedQueryBuilder> where(String columnName) {
+ return getQueryBuilder().where(columnName);
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> where(FilterItem... filters) {
+ return getQueryBuilder().where(filters);
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> where(Iterable<FilterItem> filters) {
+ return getQueryBuilder().where(filters);
+ }
+
+ @Override
+ public SatisfiedOrderByBuilder<GroupedQueryBuilder> orderBy(String columnName) {
+ return getQueryBuilder().orderBy(columnName);
+ }
+
+ @Override
+ public SatisfiedOrderByBuilder<GroupedQueryBuilder> orderBy(FunctionType function, Column column) {
+ return getQueryBuilder().orderBy(function, column);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderImpl.java b/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderImpl.java
new file mode 100644
index 0000000..bd5248c
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/GroupedQueryBuilderImpl.java
@@ -0,0 +1,332 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eobjects.metamodel.DataContext;
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.query.CompiledQuery;
+import org.eobjects.metamodel.query.FilterItem;
+import org.eobjects.metamodel.query.FromItem;
+import org.eobjects.metamodel.query.FunctionType;
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.Table;
+import org.eobjects.metamodel.util.BaseObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Main implementation of the {@link GroupedQueryBuilder} interface.
+ */
+final class GroupedQueryBuilderImpl extends BaseObject implements GroupedQueryBuilder {
+
+ private static final Logger logger = LoggerFactory.getLogger(GroupedQueryBuilderImpl.class);
+
+ private final Query _query;
+ private final DataContext _dataContext;
+
+ public GroupedQueryBuilderImpl(DataContext dataContext, Query query) {
+ if (query == null) {
+ throw new IllegalArgumentException("query cannot be null");
+ }
+ _dataContext = dataContext;
+ _query = query;
+ }
+
+ @Override
+ public ColumnSelectBuilder<GroupedQueryBuilder> select(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return new ColumnSelectBuilderImpl(column, _query, this);
+ }
+
+ @Override
+ public FunctionSelectBuilder<GroupedQueryBuilder> select(FunctionType function, Column column) {
+ if (function == null) {
+ throw new IllegalArgumentException("function cannot be null");
+ }
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return new FunctionSelectBuilderImpl(function, column, _query, this);
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> where(FilterItem... filters) {
+ _query.where(filters);
+ return this;
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> where(Iterable<FilterItem> filters) {
+ _query.where(filters);
+ return this;
+ }
+
+ @Override
+ public ColumnSelectBuilder<GroupedQueryBuilder> select(String columnName) {
+ Column column = findColumn(columnName);
+ return select(column);
+ }
+
+ @Override
+ public CountSelectBuilder<GroupedQueryBuilder> selectCount() {
+ return new CountSelectBuilderImpl(_query, this);
+ }
+
+ @Override
+ public SatisfiedSelectBuilder<GroupedQueryBuilder> select(Column... columns) {
+ if (columns == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ _query.select(columns);
+ return new SatisfiedSelectBuilderImpl(this);
+ }
+
+ @Override
+ public WhereBuilder<GroupedQueryBuilder> where(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return new WhereBuilderImpl(column, _query, this);
+ }
+
+ @Override
+ public WhereBuilder<GroupedQueryBuilder> where(String columnName) {
+ Column column = findColumn(columnName);
+ return where(column);
+ }
+
+ @Override
+ public Column findColumn(final String columnName) throws IllegalArgumentException {
+ if (columnName == null) {
+ throw new IllegalArgumentException("columnName cannot be null");
+ }
+
+ final List<FromItem> fromItems = _query.getFromClause().getItems();
+ final List<SelectItem> selectItems = _query.getSelectClause().getItems();
+
+ int dotIndex = columnName.indexOf('.');
+ if (dotIndex != -1) {
+ // check aliases of from items
+ final String aliasPart = columnName.substring(0, dotIndex);
+ final String columnPart = columnName.substring(dotIndex + 1);
+
+ for (FromItem fromItem : fromItems) {
+ Column column = null;
+ column = findColumnInAliasedTable(column, fromItem, aliasPart, columnPart);
+ if (column != null) {
+ return column;
+ }
+ }
+ }
+
+ // check columns already in select clause
+ for (SelectItem item : selectItems) {
+ Column column = item.getColumn();
+ if (column != null) {
+ if (columnName.equals(column.getName())) {
+ return column;
+ }
+ }
+ }
+
+ for (FromItem fromItem : fromItems) {
+ Table table = fromItem.getTable();
+ if (table != null) {
+ Column column = table.getColumnByName(columnName);
+ if (column != null) {
+ return column;
+ }
+ }
+ }
+
+ Column column = _dataContext.getColumnByQualifiedLabel(columnName);
+ if (column != null) {
+ return column;
+ }
+
+ final IllegalArgumentException exception = new IllegalArgumentException("Could not find column: " + columnName);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("findColumn('" + columnName + "') could not resolve a column", exception);
+ for (FromItem fromItem : fromItems) {
+ final Table table = fromItem.getTable();
+ if (table != null) {
+ logger.debug("Table available in FROM item: {}. Column names: {}", table,
+ Arrays.toString(table.getColumnNames()));
+ }
+ }
+ }
+
+ throw exception;
+ }
+
+ private Column findColumnInAliasedTable(Column column, FromItem fromItem, String aliasPart, String columnPart) {
+ if (column != null) {
+ // ensure that if the column has already been found, return it
+ return column;
+ }
+
+ Table table = fromItem.getTable();
+ if (table != null) {
+ String alias = fromItem.getAlias();
+ if (alias != null && alias.equals(aliasPart)) {
+ column = table.getColumnByName(columnPart);
+ }
+ } else {
+ FromItem leftSide = fromItem.getLeftSide();
+ column = findColumnInAliasedTable(column, leftSide, aliasPart, columnPart);
+ FromItem rightSide = fromItem.getRightSide();
+ column = findColumnInAliasedTable(column, rightSide, aliasPart, columnPart);
+ if (column != null) {
+ Query subQuery = fromItem.getSubQuery();
+ if (subQuery != null) {
+ List<FromItem> items = subQuery.getFromClause().getItems();
+ for (FromItem subQueryFromItem : items) {
+ column = findColumnInAliasedTable(column, subQueryFromItem, aliasPart, columnPart);
+ }
+ }
+ }
+ }
+
+ return column;
+ }
+
+ @Override
+ public SatisfiedOrderByBuilder<GroupedQueryBuilder> orderBy(String columnName) {
+ return orderBy(findColumn(columnName));
+ }
+
+ @Override
+ public SatisfiedOrderByBuilder<GroupedQueryBuilder> orderBy(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return new SatisfiedOrderByBuilderImpl(column, _query, this);
+ }
+
+ @Override
+ public SatisfiedOrderByBuilder<GroupedQueryBuilder> orderBy(FunctionType function, Column column) {
+ if (function == null) {
+ throw new IllegalArgumentException("function cannot be null");
+ }
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return new SatisfiedOrderByBuilderImpl(function, column, _query, this);
+ }
+
+ @Override
+ public GroupedQueryBuilder groupBy(Column column) {
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ _query.groupBy(column);
+ return this;
+ }
+
+ @Override
+ public GroupedQueryBuilder groupBy(String columnName) {
+ Column column = findColumn(columnName);
+ return groupBy(column);
+ }
+
+ @Override
+ public GroupedQueryBuilder groupBy(Column... columns) {
+ if (columns == null) {
+ throw new IllegalArgumentException("columns cannot be null");
+ }
+ _query.groupBy(columns);
+ return this;
+ }
+
+ @Override
+ public HavingBuilder having(FunctionType function, Column column) {
+ if (function == null) {
+ throw new IllegalArgumentException("function cannot be null");
+ }
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ return new HavingBuilderImpl(function, column, _query, this);
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> limit(int maxRows) {
+ _query.setMaxRows(maxRows);
+ return this;
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> maxRows(int maxRows) {
+ _query.setMaxRows(maxRows);
+ return this;
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> firstRow(int firstRow) {
+ if (firstRow >= 0) {
+ _query.setFirstRow(firstRow);
+ } else {
+ _query.setFirstRow(null);
+ }
+ return this;
+ }
+
+ @Override
+ public SatisfiedQueryBuilder<GroupedQueryBuilder> offset(int offset) {
+ if (offset >= 0) {
+ _query.setFirstRow(offset + 1);
+ } else {
+ _query.setFirstRow(null);
+ }
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return _query.toSql();
+ }
+
+ @Override
+ public Query toQuery() {
+ return _query.clone();
+ }
+
+ @Override
+ public CompiledQuery compile() {
+ return _dataContext.compileQuery(_query);
+ }
+
+ @Override
+ public DataSet execute() {
+ return _dataContext.executeQuery(_query);
+ }
+
+ @Override
+ protected void decorateIdentity(List<Object> identifiers) {
+ identifiers.add(_query);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilder.java b/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilder.java
new file mode 100644
index 0000000..1596ada
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilder.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+/**
+ * Builder interface for having items.
+ */
+public interface HavingBuilder extends FilterBuilder<SatisfiedHavingBuilder> {
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilderImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilderImpl.java b/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilderImpl.java
new file mode 100644
index 0000000..13b197d
--- /dev/null
+++ b/core/src/main/java/org/apache/metamodel/query/builder/HavingBuilderImpl.java
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.eobjects.metamodel.query.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eobjects.metamodel.query.FilterItem;
+import org.eobjects.metamodel.query.FunctionType;
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.Column;
+
+final class HavingBuilderImpl extends
+ AbstractQueryFilterBuilder<SatisfiedHavingBuilder> implements
+ HavingBuilder, SatisfiedHavingBuilder {
+
+ private final Query _query;
+ private final List<FilterItem> _orFilters;
+ private FilterItem _parentOrFilter;
+
+ public HavingBuilderImpl(FunctionType function, Column column, Query query,
+ GroupedQueryBuilder queryBuilder) {
+ super(new SelectItem(function, column), queryBuilder);
+ _query = query;
+ _orFilters = new ArrayList<FilterItem>();
+ }
+
+ public HavingBuilderImpl(FunctionType function, Column column, Query query,
+ FilterItem parentOrFilter, List<FilterItem> orFilters,
+ GroupedQueryBuilder queryBuilder) {
+ super(new SelectItem(function, column), queryBuilder);
+ _query = query;
+ _orFilters = orFilters;
+ _parentOrFilter = parentOrFilter;
+ }
+
+ @Override
+ protected SatisfiedHavingBuilder applyFilter(FilterItem filter) {
+ if (_parentOrFilter == null) {
+ _query.having(filter);
+ } else {
+ if (_parentOrFilter.getChildItemCount() == 1) {
+ _query.getHavingClause().removeItem(_orFilters.get(0));
+ _query.getHavingClause().addItem(_parentOrFilter);
+ }
+ }
+ _orFilters.add(filter);
+ return this;
+ }
+
+ @Override
+ public HavingBuilder or(FunctionType function, Column column) {
+ if (function == null) {
+ throw new IllegalArgumentException("function cannot be null");
+ }
+ if (column == null) {
+ throw new IllegalArgumentException("column cannot be null");
+ }
+ if (_parentOrFilter == null) {
+ _parentOrFilter = new FilterItem(_orFilters);
+ }
+ return new HavingBuilderImpl(function, column, _query, _parentOrFilter,
+ _orFilters, getQueryBuilder());
+ }
+
+ @Override
+ public HavingBuilder and(FunctionType function, Column column) {
+ return getQueryBuilder().having(function, column);
+ }
+}
\ No newline at end of file