You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by Jacopo Cappellato <ja...@hotwaxmedia.com> on 2014/09/27 11:59:32 UTC
Re: svn commit: r1627940 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
This is really an amazing contribution! Thank you Scott.
Jacopo
On Sep 27, 2014, at 11:22 AM, lektran@apache.org wrote:
> Author: lektran
> Date: Sat Sep 27 09:22:31 2014
> New Revision: 1627940
>
> URL: http://svn.apache.org/r1627940
> Log:
> OFBIZ-4053 Implement an entity query builder to be used as a friendlier API for executing entity queries.
>
> Entry point is the static EntityQuery.use(Delegator) method which will then return an EntityQuery instance whose methods support method chaining to set query options.
> The query can then be executed using the first(), list(), iterator() and one() methods which respectively return:
> - The first result from a result set
> - The full list of results from a result set
> - An EntityListIterator to iterate over a result set
> - The single record from a query that will return only one record (such as a lookup by primary key)
>
> Added:
> ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java (with props)
>
> Added: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java?rev=1627940&view=auto
> ==============================================================================
> --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java (added)
> +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java Sat Sep 27 09:22:31 2014
> @@ -0,0 +1,416 @@
> +/*******************************************************************************
> + * 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.ofbiz.entity.util;
> +
> +import java.sql.Timestamp;
> +import java.util.Arrays;
> +import java.util.List;
> +import java.util.Map;
> +import java.util.Set;
> +
> +import org.ofbiz.base.util.Debug;
> +import org.ofbiz.base.util.UtilMisc;
> +import org.ofbiz.entity.Delegator;
> +import org.ofbiz.entity.GenericEntityException;
> +import org.ofbiz.entity.GenericValue;
> +import org.ofbiz.entity.condition.EntityCondition;
> +import org.ofbiz.entity.model.DynamicViewEntity;
> +import org.ofbiz.entity.util.EntityFindOptions;
> +import org.ofbiz.entity.util.EntityListIterator;
> +import org.ofbiz.entity.util.EntityUtil;
> +
> +/**
> + * Used to setup various options for and subsequently execute entity queries.
> + *
> + * All methods to set options modify the EntityQuery instance then return this modified object to allow method call chaining. It is
> + * important to note that this object is not immutable and is modified internally, and returning EntityQuery is just a
> + * self reference for convenience.
> + *
> + * After a query the object can be further modified and then used to perform another query if desired.
> + */
> +public class EntityQuery {
> +
> + public static final String module = EntityQuery.class.getName();
> +
> + private Delegator delegator;
> + private String entityName = null;
> + private DynamicViewEntity dynamicViewEntity = null;
> + private boolean useCache = false;
> + private EntityCondition whereEntityCondition = null;
> + private Set<String> fieldsToSelect = null;
> + private List<String> orderBy = null;
> + private Integer resultSetType = EntityFindOptions.TYPE_FORWARD_ONLY;
> + private Integer fetchSize = null;
> + private Integer maxRows = null;
> + private Boolean distinct = null;
> + private EntityCondition havingEntityCondition = null;
> + private boolean filterByDate = false;
> + private Timestamp filterByDateMoment;
> +
> +
> +
> + /** Construct an EntityQuery object for use against the specified Delegator
> + * @param delegator - The delegator instance to use for the query
> + * @return Returns a new EntityQuery object
> + */
> + public static EntityQuery use(Delegator delegator) {
> + return new EntityQuery(delegator);
> + }
> +
> + /** Construct an EntityQuery object for use against the specified Delegator
> + * @param delegator - The delegator instance to use for the query
> + * @return Returns a new EntityQuery object
> + */
> + public EntityQuery(Delegator delegator) {
> + this.delegator = delegator;
> + }
> +
> + /** Set the fields to be returned when the query is executed.
> + *
> + * Note that the select methods are not additive, if a subsequent
> + * call is made to select then the existing fields for selection
> + * will be replaced.
> + * @param fieldsToSelect - A Set of Strings containing the field names to be selected
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery select(Set<String> fieldsToSelect) {
> + this.fieldsToSelect = fieldsToSelect;
> + return this;
> + }
> +
> + /** Set the fields to be returned when the query is executed.
> + *
> + * Note that the select methods are not additive, if a subsequent
> + * call is made to select then the existing fields for selection
> + * will be replaced.
> + * @param fieldsToSelect - Strings containing the field names to be selected
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery select(String...fields) {
> + this.fieldsToSelect = UtilMisc.toSetArray(fields);
> + return this;
> + }
> +
> + /** Set the entity to query against
> + * @param entityName - The name of the entity to query against
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery from(String entityName) {
> + this.entityName = entityName;
> + this.dynamicViewEntity = null;
> + return this;
> + }
> +
> + /** Set the entity to query against
> + * @param dynamicViewEntity - The DynamicViewEntity object to query against
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery from(DynamicViewEntity dynamicViewEntity) {
> + this.dynamicViewEntity = dynamicViewEntity;
> + this.entityName = null;
> + return this;
> + }
> +
> + /** Set the EntityCondition to be used as the WHERE clause for the query
> + *
> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
> + * @param entityCondition - An EntityCondition object to be used as the where clause for this query
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery where(EntityCondition entityCondition) {
> + this.whereEntityCondition = entityCondition;
> + return this;
> + }
> +
> + /** Set a Map of field name/values to be ANDed together as the WHERE clause for the query
> + *
> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
> + * @param fieldMap - A Map of field names/values to be ANDed together as the where clause for the query
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery where(Map<String, Object> fieldMap) {
> + this.whereEntityCondition = EntityCondition.makeCondition(fieldMap);
> + return this;
> + }
> +
> + /** Set a series of field name/values to be ANDed together as the WHERE clause for the query
> + *
> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
> + * @param fieldMap - A series of field names/values to be ANDed together as the where clause for the query
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery where(Object...fields) {
> + this.whereEntityCondition = EntityCondition.makeCondition(UtilMisc.toMap(fields));
> + return this;
> + }
> +
> + /** Set a list of EntityCondition objects to be ANDed together as the WHERE clause for the query
> + *
> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
> + * @param fieldMap - A list of EntityCondition objects to be ANDed together as the WHERE clause for the query
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery where(List<EntityCondition> andConditions) {
> + this.whereEntityCondition = EntityCondition.makeCondition(andConditions);
> + return this;
> + }
> +
> + /** Set the EntityCondition to be used as the HAVING clause for the query.
> + *
> + * NOTE: Each successive call to any of the having(...) methods will replace the currently set condition for the query.
> + * @param entityCondition - The EntityCondition object that specifies how to constrain
> + * this query after any groupings are done (if this is a view
> + * entity with group-by aliases)
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery having(EntityCondition entityCondition) {
> + this.havingEntityCondition = entityCondition;
> + return this;
> + }
> +
> + /** The fields of the named entity to order the resultset by; optionally add a " ASC" for ascending or " DESC" for descending
> + *
> + * NOTE: Each successive call to any of the orderBy(...) methods will replace the currently set orderBy fields for the query.
> + * @param orderBy - The fields of the named entity to order the resultset by
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery orderBy(List<String> orderBy) {
> + this.orderBy = orderBy;
> + return this;
> + }
> +
> + /** The fields of the named entity to order the resultset by; optionally add a " ASC" for ascending or " DESC" for descending
> + *
> + * NOTE: Each successive call to any of the orderBy(...) methods will replace the currently set orderBy fields for the query.
> + * @param orderBy - The fields of the named entity to order the resultset by
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery orderBy(String...fields) {
> + this.orderBy = Arrays.asList(fields);
> + return this;
> + }
> +
> + /** Indicate that the ResultSet object's cursor may move only forward (this is the default behavior)
> + *
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery cursorForwardOnly() {
> + this.resultSetType = EntityFindOptions.TYPE_FORWARD_ONLY;
> + return this;
> + }
> +
> + /** Indicate that the ResultSet object's cursor is scrollable but generally sensitive to changes to the data that underlies the ResultSet.
> + *
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery cursorScrollSensitive() {
> + this.resultSetType = EntityFindOptions.TYPE_SCROLL_SENSITIVE;
> + return this;
> + }
> +
> + /** Indicate that the ResultSet object's cursor is scrollable but generally not sensitive to changes to the data that underlies the ResultSet.
> + *
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery cursorScrollInsensitive() {
> + this.resultSetType = EntityFindOptions.TYPE_SCROLL_INSENSITIVE;
> + return this;
> + }
> +
> + /** Specifies the fetch size for this query. -1 will fall back to datasource settings.
> + *
> + * @param fetchSize - The fetch size for this query
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery fetchSize(int fetchSize) {
> + this.fetchSize = fetchSize;
> + return this;
> + }
> +
> + /** Specifies the max number of rows to return, 0 means all rows.
> + *
> + * @param maxRows - the max number of rows to return
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery maxRows(int maxRows) {
> + this.maxRows = maxRows;
> + return this;
> + }
> +
> + /** Specifies that the values returned should be filtered to remove duplicate values.
> + *
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery distinct() {
> + this.distinct = true;
> + return this;
> + }
> +
> + /** Specifies whether the values returned should be filtered to remove duplicate values.
> + *
> + * @param distinct - boolean indicating whether the values returned should be filtered to remove duplicate values
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery distinct(boolean distinct) {
> + this.distinct = distinct;
> + return this;
> + }
> +
> + /** Specifies whether results should be read from the cache (or written to the cache if the results have not yet been cached)
> + *
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery cache() {
> + this.useCache = true;
> + return this;
> + }
> +
> + /** Specifies whether the query should return only values that are currently active using from/thruDate fields.
> + *
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery filterByDate() {
> + this.filterByDate = true;
> + this.filterByDateMoment = null;
> + return this;
> + }
> +
> + /** Specifies whether the query should return only values that are active during the specified moment using from/thruDate fields.
> + *
> + * @param moment - Timestamp representing the moment in time that the values should be active during
> + * @return this EntityQuery object, to enable chaining
> + */
> + public EntityQuery filterByDate(Timestamp moment) {
> + this.filterByDate = true;
> + this.filterByDateMoment = moment;
> + return this;
> + }
> +
> + /** Executes the EntityQuery and returns a list of results
> + *
> + * @return Returns a List of GenericValues representing the results of the query
> + */
> + public List<GenericValue> queryList() throws GenericEntityException {
> + return query(null);
> + }
> +
> + /** Executes the EntityQuery and returns an EntityListIterator representing the result of the query.
> + *
> + * NOTE: THAT THIS MUST BE CLOSED (preferably in a finally block) WHEN YOU
> + * ARE DONE WITH IT, AND DON'T LEAVE IT OPEN TOO LONG BEACUSE IT
> + * WILL MAINTAIN A DATABASE CONNECTION.
> + *
> + * @return Returns an EntityListIterator representing the result of the query
> + */
> + public EntityListIterator queryIterator() throws GenericEntityException {
> + if (useCache) {
> + Debug.logWarning("Call to iterator() with cache, ignoring cache", module);
> + }
> + if (dynamicViewEntity == null) {
> + return delegator.find(entityName, makeWhereCondition(false), havingEntityCondition, fieldsToSelect, orderBy, makeEntityFindOptions());
> + } else {
> + return delegator.findListIteratorByCondition(dynamicViewEntity, makeWhereCondition(false), havingEntityCondition, fieldsToSelect, orderBy, makeEntityFindOptions());
> + }
> + }
> +
> + /** Executes the EntityQuery and returns the first result
> + *
> + * @return GenericValue representing the first result record from the query
> + */
> + public GenericValue queryFirst() throws GenericEntityException {
> + EntityFindOptions efo = makeEntityFindOptions();
> + efo.setMaxRows(1);
> + GenericValue result = EntityUtil.getFirst(query(efo));
> + return result;
> + }
> +
> + /** Executes the EntityQuery and a single result record
> + *
> + * @return GenericValue representing the only result record from the query
> + */
> + public GenericValue queryOne() throws GenericEntityException {
> + GenericValue result = EntityUtil.getOnly(queryList());
> + return result;
> + }
> +
> + /** Executes the EntityQuery and returns the result count
> + *
> + * If the query generates more than a single result then an exception is thrown
> + *
> + * @return GenericValue representing the only result record from the query
> + */
> + public long queryCount() throws GenericEntityException {
> + if (dynamicViewEntity != null) {
> + return queryIterator().getResultsSizeAfterPartialList();
> + }
> + return delegator.findCountByCondition(entityName, makeWhereCondition(false), havingEntityCondition, makeEntityFindOptions());
> + }
> +
> + private List<GenericValue> query(EntityFindOptions efo) throws GenericEntityException {
> + EntityFindOptions findOptions = null;
> + if (efo == null) {
> + findOptions = makeEntityFindOptions();
> + } else {
> + findOptions = efo;
> + }
> + List<GenericValue> result = null;
> + if (dynamicViewEntity == null) {
> + result = delegator.findList(entityName, makeWhereCondition(useCache), fieldsToSelect, orderBy, findOptions, useCache);
> + } else {
> + result = queryIterator().getCompleteList();
> + }
> + if (filterByDate && useCache) {
> + if (filterByDateMoment == null) {
> + return EntityUtil.filterByDate(result);
> + } else {
> + return EntityUtil.filterByDate(result, filterByDateMoment);
> + }
> + }
> + return result;
> + }
> +
> + private EntityFindOptions makeEntityFindOptions() {
> + EntityFindOptions findOptions = new EntityFindOptions();
> + if (resultSetType != null) {
> + findOptions.setResultSetType(resultSetType);
> + }
> + if (fetchSize != null) {
> + findOptions.setFetchSize(fetchSize);
> + }
> + if (maxRows != null) {
> + findOptions.setMaxRows(maxRows);
> + }
> + if (distinct != null) {
> + findOptions.setDistinct(distinct);
> + }
> + return findOptions;
> + }
> +
> + private EntityCondition makeWhereCondition(boolean usingCache) {
> + // we don't use the useCache field here because not all queries will actually use the cache, e.g. findCountByCondition never uses the cache
> + if (filterByDate && !usingCache) {
> + if (filterByDateMoment == null) {
> + return EntityCondition.makeCondition(whereEntityCondition, EntityUtil.getFilterByDateExpr());
> + } else {
> + return EntityCondition.makeCondition(whereEntityCondition, EntityUtil.getFilterByDateExpr(filterByDateMoment));
> + }
> + }
> + return whereEntityCondition;
> + }
> +}
>
> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
> ------------------------------------------------------------------------------
> svn:keywords = "Date Rev Author URL Id"
>
> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
> ------------------------------------------------------------------------------
> svn:mime-type = text/plain
>
>
Re: svn commit: r1627940 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
Posted by Scott Gray <sc...@hotwaxmedia.com>.
Thanks Jacopo! I've begun converting the accounting component to use EntityQuery in r1628288, if anyone wants to help please feel free :-)
Regards
Scott
On 27/09/2014, at 9:59 pm, Jacopo Cappellato <ja...@hotwaxmedia.com> wrote:
> This is really an amazing contribution! Thank you Scott.
>
> Jacopo
>
> On Sep 27, 2014, at 11:22 AM, lektran@apache.org wrote:
>
>> Author: lektran
>> Date: Sat Sep 27 09:22:31 2014
>> New Revision: 1627940
>>
>> URL: http://svn.apache.org/r1627940
>> Log:
>> OFBIZ-4053 Implement an entity query builder to be used as a friendlier API for executing entity queries.
>>
>> Entry point is the static EntityQuery.use(Delegator) method which will then return an EntityQuery instance whose methods support method chaining to set query options.
>> The query can then be executed using the first(), list(), iterator() and one() methods which respectively return:
>> - The first result from a result set
>> - The full list of results from a result set
>> - An EntityListIterator to iterate over a result set
>> - The single record from a query that will return only one record (such as a lookup by primary key)
>>
>> Added:
>> ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java (with props)
>>
>> Added: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java?rev=1627940&view=auto
>> ==============================================================================
>> --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java (added)
>> +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java Sat Sep 27 09:22:31 2014
>> @@ -0,0 +1,416 @@
>> +/*******************************************************************************
>> + * 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.ofbiz.entity.util;
>> +
>> +import java.sql.Timestamp;
>> +import java.util.Arrays;
>> +import java.util.List;
>> +import java.util.Map;
>> +import java.util.Set;
>> +
>> +import org.ofbiz.base.util.Debug;
>> +import org.ofbiz.base.util.UtilMisc;
>> +import org.ofbiz.entity.Delegator;
>> +import org.ofbiz.entity.GenericEntityException;
>> +import org.ofbiz.entity.GenericValue;
>> +import org.ofbiz.entity.condition.EntityCondition;
>> +import org.ofbiz.entity.model.DynamicViewEntity;
>> +import org.ofbiz.entity.util.EntityFindOptions;
>> +import org.ofbiz.entity.util.EntityListIterator;
>> +import org.ofbiz.entity.util.EntityUtil;
>> +
>> +/**
>> + * Used to setup various options for and subsequently execute entity queries.
>> + *
>> + * All methods to set options modify the EntityQuery instance then return this modified object to allow method call chaining. It is
>> + * important to note that this object is not immutable and is modified internally, and returning EntityQuery is just a
>> + * self reference for convenience.
>> + *
>> + * After a query the object can be further modified and then used to perform another query if desired.
>> + */
>> +public class EntityQuery {
>> +
>> + public static final String module = EntityQuery.class.getName();
>> +
>> + private Delegator delegator;
>> + private String entityName = null;
>> + private DynamicViewEntity dynamicViewEntity = null;
>> + private boolean useCache = false;
>> + private EntityCondition whereEntityCondition = null;
>> + private Set<String> fieldsToSelect = null;
>> + private List<String> orderBy = null;
>> + private Integer resultSetType = EntityFindOptions.TYPE_FORWARD_ONLY;
>> + private Integer fetchSize = null;
>> + private Integer maxRows = null;
>> + private Boolean distinct = null;
>> + private EntityCondition havingEntityCondition = null;
>> + private boolean filterByDate = false;
>> + private Timestamp filterByDateMoment;
>> +
>> +
>> +
>> + /** Construct an EntityQuery object for use against the specified Delegator
>> + * @param delegator - The delegator instance to use for the query
>> + * @return Returns a new EntityQuery object
>> + */
>> + public static EntityQuery use(Delegator delegator) {
>> + return new EntityQuery(delegator);
>> + }
>> +
>> + /** Construct an EntityQuery object for use against the specified Delegator
>> + * @param delegator - The delegator instance to use for the query
>> + * @return Returns a new EntityQuery object
>> + */
>> + public EntityQuery(Delegator delegator) {
>> + this.delegator = delegator;
>> + }
>> +
>> + /** Set the fields to be returned when the query is executed.
>> + *
>> + * Note that the select methods are not additive, if a subsequent
>> + * call is made to select then the existing fields for selection
>> + * will be replaced.
>> + * @param fieldsToSelect - A Set of Strings containing the field names to be selected
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery select(Set<String> fieldsToSelect) {
>> + this.fieldsToSelect = fieldsToSelect;
>> + return this;
>> + }
>> +
>> + /** Set the fields to be returned when the query is executed.
>> + *
>> + * Note that the select methods are not additive, if a subsequent
>> + * call is made to select then the existing fields for selection
>> + * will be replaced.
>> + * @param fieldsToSelect - Strings containing the field names to be selected
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery select(String...fields) {
>> + this.fieldsToSelect = UtilMisc.toSetArray(fields);
>> + return this;
>> + }
>> +
>> + /** Set the entity to query against
>> + * @param entityName - The name of the entity to query against
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery from(String entityName) {
>> + this.entityName = entityName;
>> + this.dynamicViewEntity = null;
>> + return this;
>> + }
>> +
>> + /** Set the entity to query against
>> + * @param dynamicViewEntity - The DynamicViewEntity object to query against
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery from(DynamicViewEntity dynamicViewEntity) {
>> + this.dynamicViewEntity = dynamicViewEntity;
>> + this.entityName = null;
>> + return this;
>> + }
>> +
>> + /** Set the EntityCondition to be used as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param entityCondition - An EntityCondition object to be used as the where clause for this query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(EntityCondition entityCondition) {
>> + this.whereEntityCondition = entityCondition;
>> + return this;
>> + }
>> +
>> + /** Set a Map of field name/values to be ANDed together as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param fieldMap - A Map of field names/values to be ANDed together as the where clause for the query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(Map<String, Object> fieldMap) {
>> + this.whereEntityCondition = EntityCondition.makeCondition(fieldMap);
>> + return this;
>> + }
>> +
>> + /** Set a series of field name/values to be ANDed together as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param fieldMap - A series of field names/values to be ANDed together as the where clause for the query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(Object...fields) {
>> + this.whereEntityCondition = EntityCondition.makeCondition(UtilMisc.toMap(fields));
>> + return this;
>> + }
>> +
>> + /** Set a list of EntityCondition objects to be ANDed together as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param fieldMap - A list of EntityCondition objects to be ANDed together as the WHERE clause for the query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(List<EntityCondition> andConditions) {
>> + this.whereEntityCondition = EntityCondition.makeCondition(andConditions);
>> + return this;
>> + }
>> +
>> + /** Set the EntityCondition to be used as the HAVING clause for the query.
>> + *
>> + * NOTE: Each successive call to any of the having(...) methods will replace the currently set condition for the query.
>> + * @param entityCondition - The EntityCondition object that specifies how to constrain
>> + * this query after any groupings are done (if this is a view
>> + * entity with group-by aliases)
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery having(EntityCondition entityCondition) {
>> + this.havingEntityCondition = entityCondition;
>> + return this;
>> + }
>> +
>> + /** The fields of the named entity to order the resultset by; optionally add a " ASC" for ascending or " DESC" for descending
>> + *
>> + * NOTE: Each successive call to any of the orderBy(...) methods will replace the currently set orderBy fields for the query.
>> + * @param orderBy - The fields of the named entity to order the resultset by
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery orderBy(List<String> orderBy) {
>> + this.orderBy = orderBy;
>> + return this;
>> + }
>> +
>> + /** The fields of the named entity to order the resultset by; optionally add a " ASC" for ascending or " DESC" for descending
>> + *
>> + * NOTE: Each successive call to any of the orderBy(...) methods will replace the currently set orderBy fields for the query.
>> + * @param orderBy - The fields of the named entity to order the resultset by
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery orderBy(String...fields) {
>> + this.orderBy = Arrays.asList(fields);
>> + return this;
>> + }
>> +
>> + /** Indicate that the ResultSet object's cursor may move only forward (this is the default behavior)
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cursorForwardOnly() {
>> + this.resultSetType = EntityFindOptions.TYPE_FORWARD_ONLY;
>> + return this;
>> + }
>> +
>> + /** Indicate that the ResultSet object's cursor is scrollable but generally sensitive to changes to the data that underlies the ResultSet.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cursorScrollSensitive() {
>> + this.resultSetType = EntityFindOptions.TYPE_SCROLL_SENSITIVE;
>> + return this;
>> + }
>> +
>> + /** Indicate that the ResultSet object's cursor is scrollable but generally not sensitive to changes to the data that underlies the ResultSet.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cursorScrollInsensitive() {
>> + this.resultSetType = EntityFindOptions.TYPE_SCROLL_INSENSITIVE;
>> + return this;
>> + }
>> +
>> + /** Specifies the fetch size for this query. -1 will fall back to datasource settings.
>> + *
>> + * @param fetchSize - The fetch size for this query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery fetchSize(int fetchSize) {
>> + this.fetchSize = fetchSize;
>> + return this;
>> + }
>> +
>> + /** Specifies the max number of rows to return, 0 means all rows.
>> + *
>> + * @param maxRows - the max number of rows to return
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery maxRows(int maxRows) {
>> + this.maxRows = maxRows;
>> + return this;
>> + }
>> +
>> + /** Specifies that the values returned should be filtered to remove duplicate values.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery distinct() {
>> + this.distinct = true;
>> + return this;
>> + }
>> +
>> + /** Specifies whether the values returned should be filtered to remove duplicate values.
>> + *
>> + * @param distinct - boolean indicating whether the values returned should be filtered to remove duplicate values
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery distinct(boolean distinct) {
>> + this.distinct = distinct;
>> + return this;
>> + }
>> +
>> + /** Specifies whether results should be read from the cache (or written to the cache if the results have not yet been cached)
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cache() {
>> + this.useCache = true;
>> + return this;
>> + }
>> +
>> + /** Specifies whether the query should return only values that are currently active using from/thruDate fields.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery filterByDate() {
>> + this.filterByDate = true;
>> + this.filterByDateMoment = null;
>> + return this;
>> + }
>> +
>> + /** Specifies whether the query should return only values that are active during the specified moment using from/thruDate fields.
>> + *
>> + * @param moment - Timestamp representing the moment in time that the values should be active during
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery filterByDate(Timestamp moment) {
>> + this.filterByDate = true;
>> + this.filterByDateMoment = moment;
>> + return this;
>> + }
>> +
>> + /** Executes the EntityQuery and returns a list of results
>> + *
>> + * @return Returns a List of GenericValues representing the results of the query
>> + */
>> + public List<GenericValue> queryList() throws GenericEntityException {
>> + return query(null);
>> + }
>> +
>> + /** Executes the EntityQuery and returns an EntityListIterator representing the result of the query.
>> + *
>> + * NOTE: THAT THIS MUST BE CLOSED (preferably in a finally block) WHEN YOU
>> + * ARE DONE WITH IT, AND DON'T LEAVE IT OPEN TOO LONG BEACUSE IT
>> + * WILL MAINTAIN A DATABASE CONNECTION.
>> + *
>> + * @return Returns an EntityListIterator representing the result of the query
>> + */
>> + public EntityListIterator queryIterator() throws GenericEntityException {
>> + if (useCache) {
>> + Debug.logWarning("Call to iterator() with cache, ignoring cache", module);
>> + }
>> + if (dynamicViewEntity == null) {
>> + return delegator.find(entityName, makeWhereCondition(false), havingEntityCondition, fieldsToSelect, orderBy, makeEntityFindOptions());
>> + } else {
>> + return delegator.findListIteratorByCondition(dynamicViewEntity, makeWhereCondition(false), havingEntityCondition, fieldsToSelect, orderBy, makeEntityFindOptions());
>> + }
>> + }
>> +
>> + /** Executes the EntityQuery and returns the first result
>> + *
>> + * @return GenericValue representing the first result record from the query
>> + */
>> + public GenericValue queryFirst() throws GenericEntityException {
>> + EntityFindOptions efo = makeEntityFindOptions();
>> + efo.setMaxRows(1);
>> + GenericValue result = EntityUtil.getFirst(query(efo));
>> + return result;
>> + }
>> +
>> + /** Executes the EntityQuery and a single result record
>> + *
>> + * @return GenericValue representing the only result record from the query
>> + */
>> + public GenericValue queryOne() throws GenericEntityException {
>> + GenericValue result = EntityUtil.getOnly(queryList());
>> + return result;
>> + }
>> +
>> + /** Executes the EntityQuery and returns the result count
>> + *
>> + * If the query generates more than a single result then an exception is thrown
>> + *
>> + * @return GenericValue representing the only result record from the query
>> + */
>> + public long queryCount() throws GenericEntityException {
>> + if (dynamicViewEntity != null) {
>> + return queryIterator().getResultsSizeAfterPartialList();
>> + }
>> + return delegator.findCountByCondition(entityName, makeWhereCondition(false), havingEntityCondition, makeEntityFindOptions());
>> + }
>> +
>> + private List<GenericValue> query(EntityFindOptions efo) throws GenericEntityException {
>> + EntityFindOptions findOptions = null;
>> + if (efo == null) {
>> + findOptions = makeEntityFindOptions();
>> + } else {
>> + findOptions = efo;
>> + }
>> + List<GenericValue> result = null;
>> + if (dynamicViewEntity == null) {
>> + result = delegator.findList(entityName, makeWhereCondition(useCache), fieldsToSelect, orderBy, findOptions, useCache);
>> + } else {
>> + result = queryIterator().getCompleteList();
>> + }
>> + if (filterByDate && useCache) {
>> + if (filterByDateMoment == null) {
>> + return EntityUtil.filterByDate(result);
>> + } else {
>> + return EntityUtil.filterByDate(result, filterByDateMoment);
>> + }
>> + }
>> + return result;
>> + }
>> +
>> + private EntityFindOptions makeEntityFindOptions() {
>> + EntityFindOptions findOptions = new EntityFindOptions();
>> + if (resultSetType != null) {
>> + findOptions.setResultSetType(resultSetType);
>> + }
>> + if (fetchSize != null) {
>> + findOptions.setFetchSize(fetchSize);
>> + }
>> + if (maxRows != null) {
>> + findOptions.setMaxRows(maxRows);
>> + }
>> + if (distinct != null) {
>> + findOptions.setDistinct(distinct);
>> + }
>> + return findOptions;
>> + }
>> +
>> + private EntityCondition makeWhereCondition(boolean usingCache) {
>> + // we don't use the useCache field here because not all queries will actually use the cache, e.g. findCountByCondition never uses the cache
>> + if (filterByDate && !usingCache) {
>> + if (filterByDateMoment == null) {
>> + return EntityCondition.makeCondition(whereEntityCondition, EntityUtil.getFilterByDateExpr());
>> + } else {
>> + return EntityCondition.makeCondition(whereEntityCondition, EntityUtil.getFilterByDateExpr(filterByDateMoment));
>> + }
>> + }
>> + return whereEntityCondition;
>> + }
>> +}
>>
>> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> ------------------------------------------------------------------------------
>> svn:eol-style = native
>>
>> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> ------------------------------------------------------------------------------
>> svn:keywords = "Date Rev Author URL Id"
>>
>> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> ------------------------------------------------------------------------------
>> svn:mime-type = text/plain
>>
>>
>
Re: svn commit: r1627940 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
Posted by Pranay Pandey <pr...@hotwaxmedia.com>.
+1
Thanks Scott.
Pranay Pandey
HotWax Media
http://www.hotwaxmedia.com
On Sep 27, 2014, at 3:29 PM, Jacopo Cappellato <ja...@hotwaxmedia.com> wrote:
> This is really an amazing contribution! Thank you Scott.
>
> Jacopo
>
> On Sep 27, 2014, at 11:22 AM, lektran@apache.org wrote:
>
>> Author: lektran
>> Date: Sat Sep 27 09:22:31 2014
>> New Revision: 1627940
>>
>> URL: http://svn.apache.org/r1627940
>> Log:
>> OFBIZ-4053 Implement an entity query builder to be used as a friendlier API for executing entity queries.
>>
>> Entry point is the static EntityQuery.use(Delegator) method which will then return an EntityQuery instance whose methods support method chaining to set query options.
>> The query can then be executed using the first(), list(), iterator() and one() methods which respectively return:
>> - The first result from a result set
>> - The full list of results from a result set
>> - An EntityListIterator to iterate over a result set
>> - The single record from a query that will return only one record (such as a lookup by primary key)
>>
>> Added:
>> ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java (with props)
>>
>> Added: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java?rev=1627940&view=auto
>> ==============================================================================
>> --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java (added)
>> +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java Sat Sep 27 09:22:31 2014
>> @@ -0,0 +1,416 @@
>> +/*******************************************************************************
>> + * 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.ofbiz.entity.util;
>> +
>> +import java.sql.Timestamp;
>> +import java.util.Arrays;
>> +import java.util.List;
>> +import java.util.Map;
>> +import java.util.Set;
>> +
>> +import org.ofbiz.base.util.Debug;
>> +import org.ofbiz.base.util.UtilMisc;
>> +import org.ofbiz.entity.Delegator;
>> +import org.ofbiz.entity.GenericEntityException;
>> +import org.ofbiz.entity.GenericValue;
>> +import org.ofbiz.entity.condition.EntityCondition;
>> +import org.ofbiz.entity.model.DynamicViewEntity;
>> +import org.ofbiz.entity.util.EntityFindOptions;
>> +import org.ofbiz.entity.util.EntityListIterator;
>> +import org.ofbiz.entity.util.EntityUtil;
>> +
>> +/**
>> + * Used to setup various options for and subsequently execute entity queries.
>> + *
>> + * All methods to set options modify the EntityQuery instance then return this modified object to allow method call chaining. It is
>> + * important to note that this object is not immutable and is modified internally, and returning EntityQuery is just a
>> + * self reference for convenience.
>> + *
>> + * After a query the object can be further modified and then used to perform another query if desired.
>> + */
>> +public class EntityQuery {
>> +
>> + public static final String module = EntityQuery.class.getName();
>> +
>> + private Delegator delegator;
>> + private String entityName = null;
>> + private DynamicViewEntity dynamicViewEntity = null;
>> + private boolean useCache = false;
>> + private EntityCondition whereEntityCondition = null;
>> + private Set<String> fieldsToSelect = null;
>> + private List<String> orderBy = null;
>> + private Integer resultSetType = EntityFindOptions.TYPE_FORWARD_ONLY;
>> + private Integer fetchSize = null;
>> + private Integer maxRows = null;
>> + private Boolean distinct = null;
>> + private EntityCondition havingEntityCondition = null;
>> + private boolean filterByDate = false;
>> + private Timestamp filterByDateMoment;
>> +
>> +
>> +
>> + /** Construct an EntityQuery object for use against the specified Delegator
>> + * @param delegator - The delegator instance to use for the query
>> + * @return Returns a new EntityQuery object
>> + */
>> + public static EntityQuery use(Delegator delegator) {
>> + return new EntityQuery(delegator);
>> + }
>> +
>> + /** Construct an EntityQuery object for use against the specified Delegator
>> + * @param delegator - The delegator instance to use for the query
>> + * @return Returns a new EntityQuery object
>> + */
>> + public EntityQuery(Delegator delegator) {
>> + this.delegator = delegator;
>> + }
>> +
>> + /** Set the fields to be returned when the query is executed.
>> + *
>> + * Note that the select methods are not additive, if a subsequent
>> + * call is made to select then the existing fields for selection
>> + * will be replaced.
>> + * @param fieldsToSelect - A Set of Strings containing the field names to be selected
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery select(Set<String> fieldsToSelect) {
>> + this.fieldsToSelect = fieldsToSelect;
>> + return this;
>> + }
>> +
>> + /** Set the fields to be returned when the query is executed.
>> + *
>> + * Note that the select methods are not additive, if a subsequent
>> + * call is made to select then the existing fields for selection
>> + * will be replaced.
>> + * @param fieldsToSelect - Strings containing the field names to be selected
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery select(String...fields) {
>> + this.fieldsToSelect = UtilMisc.toSetArray(fields);
>> + return this;
>> + }
>> +
>> + /** Set the entity to query against
>> + * @param entityName - The name of the entity to query against
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery from(String entityName) {
>> + this.entityName = entityName;
>> + this.dynamicViewEntity = null;
>> + return this;
>> + }
>> +
>> + /** Set the entity to query against
>> + * @param dynamicViewEntity - The DynamicViewEntity object to query against
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery from(DynamicViewEntity dynamicViewEntity) {
>> + this.dynamicViewEntity = dynamicViewEntity;
>> + this.entityName = null;
>> + return this;
>> + }
>> +
>> + /** Set the EntityCondition to be used as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param entityCondition - An EntityCondition object to be used as the where clause for this query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(EntityCondition entityCondition) {
>> + this.whereEntityCondition = entityCondition;
>> + return this;
>> + }
>> +
>> + /** Set a Map of field name/values to be ANDed together as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param fieldMap - A Map of field names/values to be ANDed together as the where clause for the query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(Map<String, Object> fieldMap) {
>> + this.whereEntityCondition = EntityCondition.makeCondition(fieldMap);
>> + return this;
>> + }
>> +
>> + /** Set a series of field name/values to be ANDed together as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param fieldMap - A series of field names/values to be ANDed together as the where clause for the query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(Object...fields) {
>> + this.whereEntityCondition = EntityCondition.makeCondition(UtilMisc.toMap(fields));
>> + return this;
>> + }
>> +
>> + /** Set a list of EntityCondition objects to be ANDed together as the WHERE clause for the query
>> + *
>> + * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query.
>> + * @param fieldMap - A list of EntityCondition objects to be ANDed together as the WHERE clause for the query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery where(List<EntityCondition> andConditions) {
>> + this.whereEntityCondition = EntityCondition.makeCondition(andConditions);
>> + return this;
>> + }
>> +
>> + /** Set the EntityCondition to be used as the HAVING clause for the query.
>> + *
>> + * NOTE: Each successive call to any of the having(...) methods will replace the currently set condition for the query.
>> + * @param entityCondition - The EntityCondition object that specifies how to constrain
>> + * this query after any groupings are done (if this is a view
>> + * entity with group-by aliases)
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery having(EntityCondition entityCondition) {
>> + this.havingEntityCondition = entityCondition;
>> + return this;
>> + }
>> +
>> + /** The fields of the named entity to order the resultset by; optionally add a " ASC" for ascending or " DESC" for descending
>> + *
>> + * NOTE: Each successive call to any of the orderBy(...) methods will replace the currently set orderBy fields for the query.
>> + * @param orderBy - The fields of the named entity to order the resultset by
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery orderBy(List<String> orderBy) {
>> + this.orderBy = orderBy;
>> + return this;
>> + }
>> +
>> + /** The fields of the named entity to order the resultset by; optionally add a " ASC" for ascending or " DESC" for descending
>> + *
>> + * NOTE: Each successive call to any of the orderBy(...) methods will replace the currently set orderBy fields for the query.
>> + * @param orderBy - The fields of the named entity to order the resultset by
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery orderBy(String...fields) {
>> + this.orderBy = Arrays.asList(fields);
>> + return this;
>> + }
>> +
>> + /** Indicate that the ResultSet object's cursor may move only forward (this is the default behavior)
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cursorForwardOnly() {
>> + this.resultSetType = EntityFindOptions.TYPE_FORWARD_ONLY;
>> + return this;
>> + }
>> +
>> + /** Indicate that the ResultSet object's cursor is scrollable but generally sensitive to changes to the data that underlies the ResultSet.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cursorScrollSensitive() {
>> + this.resultSetType = EntityFindOptions.TYPE_SCROLL_SENSITIVE;
>> + return this;
>> + }
>> +
>> + /** Indicate that the ResultSet object's cursor is scrollable but generally not sensitive to changes to the data that underlies the ResultSet.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cursorScrollInsensitive() {
>> + this.resultSetType = EntityFindOptions.TYPE_SCROLL_INSENSITIVE;
>> + return this;
>> + }
>> +
>> + /** Specifies the fetch size for this query. -1 will fall back to datasource settings.
>> + *
>> + * @param fetchSize - The fetch size for this query
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery fetchSize(int fetchSize) {
>> + this.fetchSize = fetchSize;
>> + return this;
>> + }
>> +
>> + /** Specifies the max number of rows to return, 0 means all rows.
>> + *
>> + * @param maxRows - the max number of rows to return
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery maxRows(int maxRows) {
>> + this.maxRows = maxRows;
>> + return this;
>> + }
>> +
>> + /** Specifies that the values returned should be filtered to remove duplicate values.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery distinct() {
>> + this.distinct = true;
>> + return this;
>> + }
>> +
>> + /** Specifies whether the values returned should be filtered to remove duplicate values.
>> + *
>> + * @param distinct - boolean indicating whether the values returned should be filtered to remove duplicate values
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery distinct(boolean distinct) {
>> + this.distinct = distinct;
>> + return this;
>> + }
>> +
>> + /** Specifies whether results should be read from the cache (or written to the cache if the results have not yet been cached)
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery cache() {
>> + this.useCache = true;
>> + return this;
>> + }
>> +
>> + /** Specifies whether the query should return only values that are currently active using from/thruDate fields.
>> + *
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery filterByDate() {
>> + this.filterByDate = true;
>> + this.filterByDateMoment = null;
>> + return this;
>> + }
>> +
>> + /** Specifies whether the query should return only values that are active during the specified moment using from/thruDate fields.
>> + *
>> + * @param moment - Timestamp representing the moment in time that the values should be active during
>> + * @return this EntityQuery object, to enable chaining
>> + */
>> + public EntityQuery filterByDate(Timestamp moment) {
>> + this.filterByDate = true;
>> + this.filterByDateMoment = moment;
>> + return this;
>> + }
>> +
>> + /** Executes the EntityQuery and returns a list of results
>> + *
>> + * @return Returns a List of GenericValues representing the results of the query
>> + */
>> + public List<GenericValue> queryList() throws GenericEntityException {
>> + return query(null);
>> + }
>> +
>> + /** Executes the EntityQuery and returns an EntityListIterator representing the result of the query.
>> + *
>> + * NOTE: THAT THIS MUST BE CLOSED (preferably in a finally block) WHEN YOU
>> + * ARE DONE WITH IT, AND DON'T LEAVE IT OPEN TOO LONG BEACUSE IT
>> + * WILL MAINTAIN A DATABASE CONNECTION.
>> + *
>> + * @return Returns an EntityListIterator representing the result of the query
>> + */
>> + public EntityListIterator queryIterator() throws GenericEntityException {
>> + if (useCache) {
>> + Debug.logWarning("Call to iterator() with cache, ignoring cache", module);
>> + }
>> + if (dynamicViewEntity == null) {
>> + return delegator.find(entityName, makeWhereCondition(false), havingEntityCondition, fieldsToSelect, orderBy, makeEntityFindOptions());
>> + } else {
>> + return delegator.findListIteratorByCondition(dynamicViewEntity, makeWhereCondition(false), havingEntityCondition, fieldsToSelect, orderBy, makeEntityFindOptions());
>> + }
>> + }
>> +
>> + /** Executes the EntityQuery and returns the first result
>> + *
>> + * @return GenericValue representing the first result record from the query
>> + */
>> + public GenericValue queryFirst() throws GenericEntityException {
>> + EntityFindOptions efo = makeEntityFindOptions();
>> + efo.setMaxRows(1);
>> + GenericValue result = EntityUtil.getFirst(query(efo));
>> + return result;
>> + }
>> +
>> + /** Executes the EntityQuery and a single result record
>> + *
>> + * @return GenericValue representing the only result record from the query
>> + */
>> + public GenericValue queryOne() throws GenericEntityException {
>> + GenericValue result = EntityUtil.getOnly(queryList());
>> + return result;
>> + }
>> +
>> + /** Executes the EntityQuery and returns the result count
>> + *
>> + * If the query generates more than a single result then an exception is thrown
>> + *
>> + * @return GenericValue representing the only result record from the query
>> + */
>> + public long queryCount() throws GenericEntityException {
>> + if (dynamicViewEntity != null) {
>> + return queryIterator().getResultsSizeAfterPartialList();
>> + }
>> + return delegator.findCountByCondition(entityName, makeWhereCondition(false), havingEntityCondition, makeEntityFindOptions());
>> + }
>> +
>> + private List<GenericValue> query(EntityFindOptions efo) throws GenericEntityException {
>> + EntityFindOptions findOptions = null;
>> + if (efo == null) {
>> + findOptions = makeEntityFindOptions();
>> + } else {
>> + findOptions = efo;
>> + }
>> + List<GenericValue> result = null;
>> + if (dynamicViewEntity == null) {
>> + result = delegator.findList(entityName, makeWhereCondition(useCache), fieldsToSelect, orderBy, findOptions, useCache);
>> + } else {
>> + result = queryIterator().getCompleteList();
>> + }
>> + if (filterByDate && useCache) {
>> + if (filterByDateMoment == null) {
>> + return EntityUtil.filterByDate(result);
>> + } else {
>> + return EntityUtil.filterByDate(result, filterByDateMoment);
>> + }
>> + }
>> + return result;
>> + }
>> +
>> + private EntityFindOptions makeEntityFindOptions() {
>> + EntityFindOptions findOptions = new EntityFindOptions();
>> + if (resultSetType != null) {
>> + findOptions.setResultSetType(resultSetType);
>> + }
>> + if (fetchSize != null) {
>> + findOptions.setFetchSize(fetchSize);
>> + }
>> + if (maxRows != null) {
>> + findOptions.setMaxRows(maxRows);
>> + }
>> + if (distinct != null) {
>> + findOptions.setDistinct(distinct);
>> + }
>> + return findOptions;
>> + }
>> +
>> + private EntityCondition makeWhereCondition(boolean usingCache) {
>> + // we don't use the useCache field here because not all queries will actually use the cache, e.g. findCountByCondition never uses the cache
>> + if (filterByDate && !usingCache) {
>> + if (filterByDateMoment == null) {
>> + return EntityCondition.makeCondition(whereEntityCondition, EntityUtil.getFilterByDateExpr());
>> + } else {
>> + return EntityCondition.makeCondition(whereEntityCondition, EntityUtil.getFilterByDateExpr(filterByDateMoment));
>> + }
>> + }
>> + return whereEntityCondition;
>> + }
>> +}
>>
>> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> ------------------------------------------------------------------------------
>> svn:eol-style = native
>>
>> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> ------------------------------------------------------------------------------
>> svn:keywords = "Date Rev Author URL Id"
>>
>> Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
>> ------------------------------------------------------------------------------
>> svn:mime-type = text/plain
>>
>>
>