/*
 * 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
 *
 *     https://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.
 */

/*
 * Query.java
 *
 */
package javax.jdo;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * The <code>Query</code> interface allows applications to obtain persistent instances, values, and
 * aggregate data from the data store.
 *
 * <p>The {@link PersistenceManager} is the factory for <code>Query</code> instances. There may be
 * many <code>Query</code> instances associated with a <code>PersistenceManager</code>. Multiple
 * queries might be executed simultaneously by different threads, but the implementation might
 * choose to execute them serially. In either case, the implementation must be thread-safe.
 *
 * <p>There are three required elements in a <code>Query</code>: the class of the results, the
 * candidate collection of instances, and the filter.
 *
 * <p>There are optional elements: parameter declarations, variable declarations, import statements,
 * ordering and grouping specifications, result and result class, the range of results, and flags
 * indicating whether the query result is unique and whether the query can be modified.
 *
 * <p>The query namespace is modeled after methods in Java:
 *
 * <ul>
 *   <li><code>setClass</code> corresponds to the class definition
 *   <li><code>declareParameters</code> corresponds to formal parameters of a method
 *   <li><code>declareVariables</code> corresponds to local variables of a method
 *   <li><code>setFilter</code> and <code>setOrdering</code> correspond to the method body
 * </ul>
 *
 * <p>There are two namespaces in queries. Type names have their own namespace that is separate from
 * the namespace for fields, variables and parameters.
 *
 * <p>The method <code>setClass</code> introduces the name of the candidate class in the type
 * namespace. The method <code>declareImports</code> introduces the names of the imported class or
 * interface types in the type namespace. Imported type names must be unique. When used (e.g. in a
 * parameter declaration, cast expression, etc.) a type name must be the name of the candidate
 * class, the name of a class or interface imported by method <code>declareImports</code>, or denote
 * a class or interface from the same package as the candidate class.
 *
 * <p>The method <code>setClass</code> introduces the names of the candidate class fields.
 *
 * <p>The method <code>declareParameters</code> introduces the names of the parameters. A name
 * introduced by <code>declareParameters</code> hides the name of a candidate class field of the
 * same name. Parameter names must be unique.
 *
 * <p>The method <code>declareVariables</code> introduces the names of the variables. A name
 * introduced by <code>declareVariables</code> hides the name of a candidate class field if equal.
 * Variable names must be unique and must not conflict with parameter names.
 *
 * <p>The result of the query by default is a list of result class instances, but might be specified
 * via <code>setResult</code>. The class of the result by default is the candidate class, but might
 * be specified via <code>setResultClass</code>.
 *
 * <p>A hidden field may be accessed using the 'this' qualifier: <code>this.fieldName</code>.
 *
 * <p>The <code>Query</code> interface provides methods which execute the query based on the
 * parameters given. They return a single instance or a <code>List</code> of result class instances
 * which the user can iterate to get results. The signature of the <code>execute</code> methods
 * specifies that they return an <code>Object</code> which must be cast to the appropriate result by
 * the user.
 *
 * <p>Any parameters passed to the <code>execute</code> methods are used only for this execution,
 * and are not remembered for future execution.
 *
 * @version 2.1
 * @param T Candidate class for the query
 */
public interface Query<T> extends AutoCloseable, Serializable {

  /**
   * The string constant used as the first argument to {@link
   * PersistenceManager#newQuery(String,Object)} to identify that the created query should obey the
   * JDOQL syntax and semantic rules.
   *
   * <p>This is the default query language used when creating a query with any of the other {@link
   * PersistenceManager#newQuery} methods, except {@link PersistenceManager#newQuery(Object)}, which
   * uses the query language of the compiled query template object passed to that method.
   *
   * @since 2.0
   */
  String JDOQL = "javax.jdo.query.JDOQL";

  /**
   * The string constant used as the first argument to {@link
   * PersistenceManager#newQuery(String,Object)} to identify that the created query should use SQL
   * semantics. This is only meaningful for relational JDO implementations.
   *
   * <p>If this is used, the <code>Object</code> argument to the {@link
   * PersistenceManager#newQuery(String,Object)} method should be a <code>String</code> containing a
   * SQL <code>SELECT</code> statement.
   *
   * @since 2.0
   */
  String SQL = "javax.jdo.query.SQL";

  /**
   * Set the class of the candidate instances of the query.
   *
   * <p>The class specifies the class of the candidates of the query. Elements of the candidate
   * collection that are of the specified class are filtered before being put into the result <code>
   * Collection</code>.
   *
   * @param cls the <code>Class</code> of the candidate instances.
   */
  void setClass(Class<T> cls);

  /**
   * Set the candidate <code>Extent</code> to query.
   *
   * @param pcs the candidate <code>Extent</code>.
   */
  void setCandidates(Extent<T> pcs);

  /**
   * Set the candidate <code>Collection</code> to query.
   *
   * @param pcs the candidate <code>Collection</code>.
   */
  void setCandidates(Collection<T> pcs);

  /**
   * Set the filter for the query.
   *
   * <p>The filter specification is a <code>String</code> containing a Boolean expression that is to
   * be evaluated for each of the instances in the candidate collection. If the filter is not
   * specified, then it defaults to "true", which has the effect of filtering the input <code>
   * Collection</code> only for class type.
   *
   * <p>An element of the candidate collection is returned in the result if:
   *
   * <ul>
   *   <li>it is assignment compatible to the candidate <code>Class</code> of the <code>Query</code>
   *       ; and
   *   <li>for all variables there exists a value for which the filter expression evaluates to
   *       <code>true</code>.
   * </ul>
   *
   * <p>The user may denote uniqueness in the filter expression by explicitly declaring an
   * expression (for example, <code>e1 != e2</code>).
   *
   * <p>Rules for constructing valid expressions follow the Java language, except for these
   * differences:
   *
   * <ul>
   *   <li>Equality and ordering comparisons between primitives and instances of wrapper classes are
   *       valid.
   *   <li>Equality and ordering comparisons of <code>Date</code> fields and <code>Date</code>
   *       parameters are valid.
   *   <li>White space (non-printing characters space, tab, carriage return, and line feed) is a
   *       separator and is otherwise ignored.
   *   <li>The assignment operators <code>=</code>, <code>+=</code>, etc. and pre- and
   *       post-increment and -decrement are not supported. Therefore, there are no side effects
   *       from evaluation of any expressions.
   *   <li>Methods, including object construction, are not supported, except for <code>
   *       Collection.contains(Object o)</code>, <code>Collection.isEmpty()</code>, <code>
   *       String.startsWith(String s)</code>, and <code>String.endsWith(String e)</code>.
   *       Implementations might choose to support non-mutating method calls as non-standard
   *       extensions.
   *   <li>Navigation through a <code>null</code>-valued field, which would throw <code>
   *       NullPointerException</code>, is treated as if the filter expression returned <code>false
   *       </code> for the evaluation of the current set of variable values. Other values for
   *       variables might still qualify the candidate instance for inclusion in the result set.
   *   <li>Navigation through multi-valued fields (<code>Collection</code> types) is specified using
   *       a variable declaration and the <code>Collection.contains(Object o)</code> method.
   * </ul>
   *
   * <p>Identifiers in the expression are considered to be in the name space of the specified class,
   * with the addition of declared imports, parameters and variables. As in the Java language,
   * <code>this</code> is a reserved word which means the element of the collection being evaluated.
   *
   * <p>Navigation through single-valued fields is specified by the Java language syntax of <code>
   * field_name.field_name....field_name</code>.
   *
   * <p>A JDO implementation is allowed to reorder the filter expression for optimization purposes.
   *
   * @param filter the query filter.
   */
  void setFilter(String filter);

  /**
   * Set the import statements to be used to identify the fully qualified name of variables or
   * parameters. Parameters and unbound variables might come from a different class from the
   * candidate class, and the names need to be declared in an import statement to eliminate
   * ambiguity. Import statements are specified as a <code>String</code> with semicolon-separated
   * statements.
   *
   * <p>The <code>String</code> parameter to this method follows the syntax of the import statement
   * of the Java language.
   *
   * @param imports import statements separated by semicolons.
   */
  void declareImports(String imports);

  /**
   * Declare the list of parameters query execution.
   *
   * <p>The parameter declaration is a <code>String</code> containing one or more query parameter
   * declarations separated with commas. Each parameter named in the parameter declaration must be
   * bound to a value when the query is executed.
   *
   * <p>The <code>String</code> parameter to this method follows the syntax for formal parameters in
   * the Java language.
   *
   * @param parameters the list of parameters separated by commas.
   */
  void declareParameters(String parameters);

  /**
   * Declare the unbound variables to be used in the query. Variables might be used in the filter,
   * and these variables must be declared with their type. The unbound variable declaration is a
   * <code>String</code> containing one or more unbound variable declarations separated with
   * semicolons. It follows the syntax for local variables in the Java language.
   *
   * @param variables the variables separated by semicolons.
   */
  void declareVariables(String variables);

  /**
   * Set the ordering specification for the result <code>Collection</code>. The ordering
   * specification is a <code>String</code> containing one or more ordering declarations separated
   * by commas.
   *
   * <p>Each ordering declaration is the name of the field on which to order the results followed by
   * one of the following words: "<code>ascending</code>" or "<code>descending</code>".
   *
   * <p>The field must be declared in the candidate class or must be a navigation expression
   * starting with a field in the candidate class.
   *
   * <p>Valid field types are primitive types except <code>boolean</code>; wrapper types except
   * <code>Boolean</code>; <code>BigDecimal</code>; <code>BigInteger</code>; <code>String</code>;
   * and <code>Date</code>.
   *
   * @param ordering the ordering specification.
   */
  void setOrdering(String ordering);

  /**
   * Set the ignoreCache option. The default value for this option was set by the <code>
   * PersistenceManagerFactory</code> or the <code>PersistenceManager</code> used to create this
   * <code>Query</code>.
   *
   * <p>The ignoreCache option setting specifies whether the query should execute entirely in the
   * back end, instead of in the cache. If this flag is set to <code>true</code>, an implementation
   * might be able to optimize the query execution by ignoring changed values in the cache. For
   * optimistic transactions, this can dramatically improve query response times.
   *
   * @param ignoreCache the setting of the ignoreCache option.
   */
  void setIgnoreCache(boolean ignoreCache);

  /**
   * Get the ignoreCache option setting.
   *
   * @return the ignoreCache option setting.
   * @see #setIgnoreCache
   */
  boolean getIgnoreCache();

  /**
   * Verify the elements of the query and provide a hint to the query to prepare and optimize an
   * execution plan.
   */
  void compile();

  /**
   * Execute the query and return the filtered Collection.
   *
   * <p>Cancellation of the query using cancel() will result in JDOQueryInterruptedException being
   * thrown here
   *
   * @return the filtered <code>Collection</code>.
   * @see #executeWithArray(Object[] parameters)
   */
  Object execute();

  /**
   * Execute the query and return the filtered <code>Collection</code>.
   *
   * <p>Cancellation of the query using cancel() will result in JDOQueryInterruptedException being
   * thrown here
   *
   * @return the filtered <code>Collection</code>.
   * @see #executeWithArray(Object[] parameters)
   * @param p1 the value of the first parameter declared.
   */
  Object execute(Object p1);

  /**
   * Execute the query and return the filtered <code>Collection</code>.
   *
   * <p>Cancellation of the query using cancel() will result in JDOQueryInterruptedException being
   * thrown here
   *
   * @return the filtered <code>Collection</code>.
   * @see #executeWithArray(Object[] parameters)
   * @param p1 the value of the first parameter declared.
   * @param p2 the value of the second parameter declared.
   */
  Object execute(Object p1, Object p2);

  /**
   * Execute the query and return the filtered <code>Collection</code>.
   *
   * <p>Cancellation of the query using cancel() will result in JDOQueryInterruptedException being
   * thrown here
   *
   * @return the filtered <code>Collection</code>.
   * @see #executeWithArray(Object[] parameters)
   * @param p1 the value of the first parameter declared.
   * @param p2 the value of the second parameter declared.
   * @param p3 the value of the third parameter declared.
   */
  Object execute(Object p1, Object p2, Object p3);

  /**
   * Execute the query and return the filtered <code>Collection</code>. The query is executed with
   * the parameters set by the <code>Map</code> values. Each <code>Map</code> entry consists of a
   * key which is the name of the parameter in the <code>declareParameters</code> method, and a
   * value which is the value used in the <code>execute</code> method. The keys in the <code>Map
   * </code> and the declared parameters must exactly match or a <code>JDOUserException</code> is
   * thrown.
   *
   * <p>Cancellation of the query using cancel() will result in JDOQueryInterruptedException being
   * thrown here
   *
   * @return the filtered <code>Collection</code>.
   * @see #executeWithArray(Object[] parameters)
   * @param parameters the <code>Map</code> containing all of the parameters.
   */
  Object executeWithMap(Map<String, ?> parameters);

  /**
   * Execute the query and return the filtered <code>Collection</code>.
   *
   * <p>The execution of the query obtains the values of the parameters and matches them against the
   * declared parameters in order. The names of the declared parameters are ignored. The type of the
   * declared parameters must match the type of the passed parameters, except that the passed
   * parameters might need to be unwrapped to get their primitive values.
   *
   * <p>The filter, import, declared parameters, declared variables, and ordering statements are
   * verified for consistency.
   *
   * <p>Each element in the candidate <code>Collection</code> is examined to see that it is
   * assignment compatible to the <code>Class</code> of the query. It is then evaluated by the
   * Boolean expression of the filter. The element passes the filter if there exist unique values
   * for all variables for which the filter expression evaluates to <code>true</code>.
   *
   * <p>Cancellation of the query using cancel() will result in JDOQueryInterruptedException being
   * thrown here
   *
   * @return the filtered <code>Collection</code>.
   * @param parameters the <code>Object</code> array with all of the parameters.
   */
  Object executeWithArray(Object... parameters);

  /**
   * Get the <code>PersistenceManager</code> associated with this <code>Query</code>.
   *
   * <p>If this <code>Query</code> was restored from a serialized form, it has no <code>
   * PersistenceManager</code>, and this method returns <code>null</code>.
   *
   * @return the <code>PersistenceManager</code> associated with this <code>Query</code>.
   */
  PersistenceManager getPersistenceManager();

  /**
   * Close a query result and release any resources associated with it. The parameter is the return
   * from <code>execute(...)</code> and might have iterators open on it. Iterators associated with
   * the query result are invalidated: they return <code>false</code> to <code>hasNext()</code> and
   * throw <code>NoSuchElementException</code> to <code>next()</code>.
   *
   * @param queryResult the result of <code>execute(...)</code> on this <code>Query</code> instance.
   */
  void close(Object queryResult);

  /**
   * Close all query results associated with this <code>Query</code> instance, and release all
   * resources associated with them. The query results might have iterators open on them. Iterators
   * associated with the query results are invalidated: they return <code>false</code> to <code>
   * hasNext()</code> and throw <code>NoSuchElementException</code> to <code>next()</code>.
   */
  void closeAll();

  /**
   * Don't use this method directly; use <code>closeAll()</code> instead. It is intended for use
   * with try-with-resources.
   */
  void close();

  /**
   * Set the grouping expressions, optionally including a "having" clause. When grouping is
   * specified, each result expression must either be an expression contained in the grouping, or an
   * aggregate evaluated once per group.
   *
   * @param group a comma-delimited list of expressions, optionally followed by the "having" keyword
   *     and a boolean expression
   * @since 2.0
   */
  void setGrouping(String group);

  /**
   * Specify that only the first result of the query should be returned, rather than a collection.
   * The execute method will return null if the query result size is 0.
   *
   * @since 2.0
   * @param unique if true, only one element is returned
   */
  void setUnique(boolean unique);

  /**
   * Specifies what type of data this query should return. If this is unset or set to <code>null
   * </code>, this query returns instances of the query's candidate class. If set, this query will
   * return expressions, including field values (projections) and aggregate function results.
   *
   * @param data a comma-delimited list of expressions (fields, functions on fields, or aggregate
   *     functions) to return from this query
   * @since 2.0
   */
  void setResult(String data);

  /**
   * Specify the type of object in which to return each element of the result of invoking {@link
   * #execute} or one of its siblings. If the result is not set or set to null, the result class
   * defaults to the candidate class of the query. If the result consists of one expression, the
   * result class defaults to the type of that expression. If the result consists of more than one
   * expression, the result class defaults to Object[]. The result class may be specified to be one
   * of the java.lang classes Character, Boolean, Byte, Short, Integer, Long, Float, Double, String,
   * or Object[]; or one of the java.math classes BigInteger or BigDecimal; or the java.util class
   * Date; or one of the java.sql classes Date, Time, or Timestamp; or a user-defined class.
   *
   * <p>If there are multiple result expressions, the result class must be able to hold all elements
   * of the result specification or a JDOUserException is thrown.
   *
   * <p>If there is only one result expression, the result class must be assignable from the type of
   * the result expression or must be able to hold all elements of the result specification. A
   * single value must be able to be coerced into the specified result class (treating wrapper
   * classes as equivalent to their unwrapped primitive types) or by matching. If the result class
   * does not satisfy these conditions, a JDOUserException is thrown.
   *
   * <p>A constructor of a result class specified in the setResult method will be used if the
   * results specification matches the parameters of the constructor by position and type. If more
   * than one constructor satisfies the requirements, the JDO implementation chooses one of them. If
   * no constructor satisfies the results requirements, or if the result class is specified via the
   * setResultClass method, the following requirements apply:
   *
   * <ul>
   *   <li>A user-defined result class must have a no-args constructor and one or more public <code>
   *       set</code> or <code>put</code> methods or fields.
   *   <li>Each result expression must match one of:
   *       <ul>
   *         <li>a public field that matches the name of the result expression and is of the type
   *             (treating wrapper types equivalent to primitive types) of the result expression;
   *         <li>or if no public field matches the name and type, a public <code>set</code> method
   *             that returns void and matches the name of the result expression and takes a single
   *             parameter which is the exact type of the result expression;
   *         <li>or if neither of the above applies,a public method must be found with the signature
   *             <code>void put(Object, Object)</code>. During processing of the results, the first
   *             argument is the name of the result expression and the second argument is the value
   *             from the query result.
   *       </ul>
   * </ul>
   *
   * Portable result classes do not invoke any persistence behavior during their no-args constructor
   * or <code>set</code> methods.
   *
   * @param cls the result class
   * @since 2.0
   */
  void setResultClass(Class<?> cls);

  /**
   * Set the range of results to return. The execution of the query is modified to return only a
   * subset of results. If the filter would normally return 100 instances, and fromIncl is set to
   * 50, and toExcl is set to 70, then the first 50 results that would have been returned are
   * skipped, the next 20 results are returned and the remaining 30 results are ignored. An
   * implementation should execute the query such that the range algorithm is done at the data
   * store.
   *
   * @param fromIncl 0-based inclusive start index
   * @param toExcl 0-based exclusive end index, or {@link Long#MAX_VALUE} for no limit.
   * @since 2.0
   */
  void setRange(long fromIncl, long toExcl);

  /**
   * Set the range of results to return. The parameter is a String containing a comma-separated
   * fromIncl and toExcl. The fromIncl and toExcl can be either String representations of long
   * values, or can be parameters identified with a leading ":". For example, <code>
   * setRange("50, 70");</code> or <code>setRange(":from, :to");</code> or <code>
   * setRange("50, :to");</code>. The execution of the query is modified to return only a subset of
   * results. If the filter would normally return 100 instances, and fromIncl is set to 50, and
   * toExcl is set to 70, then the first 50 results that would have been returned are skipped, the
   * next 20 results are returned and the remaining 30 results are ignored. An implementation should
   * execute the query such that the range algorithm is done at the data store.
   *
   * @param fromInclToExcl comma-separated fromIncl and toExcl values
   * @see #setRange(long, long)
   * @since 2.0
   */
  void setRange(String fromInclToExcl);

  /**
   * Add a vendor-specific extension to this query. The key and value are not standard. An
   * implementation must ignore keys that are not recognized.
   *
   * @param key the key of the extension
   * @param value the value of the extension
   * @since 2.0
   */
  void addExtension(String key, Object value);

  /**
   * Set multiple extensions, or use null to clear all extensions. Map keys and values are not
   * standard. An implementation must ignore entries that are not recognized.
   *
   * @param extensions the map of extensions
   * @see #addExtension
   * @since 2.0
   */
  void setExtensions(Map<?, ?> extensions);

  /**
   * Returns the <code>FetchPlan</code> used by this <code>Query</code>. Modifications of the
   * returned fetch plan will not cause this query's owning <code>PersistenceManager</code>'s <code>
   * FetchPlan</code> to be modified.
   *
   * @since 2.0
   * @return the fetch plan used by this query
   */
  FetchPlan getFetchPlan();

  /**
   * Deletes all the instances of the candidate class that pass the filter.
   *
   * @see #deletePersistentAll()
   * @param parameters for the query
   * @return the number of instances of the candidate class that were deleted
   * @since 2.0
   */
  long deletePersistentAll(Object... parameters);

  /**
   * Deletes all the instances of the candidate class that pass the filter.
   *
   * @see #deletePersistentAll()
   * @param parameters for the query
   * @return the number of instances of the candidate class that were deleted
   * @since 2.0
   */
  long deletePersistentAll(Map<?, ?> parameters);

  /**
   * Deletes all the instances of the candidate class that pass the filter. Returns the number of
   * instances of the candidate class that were deleted, specifically not including the number of
   * dependent and embedded instances.
   *
   * <p>Dirty instances of affected classes in the cache are first flushed to the datastore.
   * Instances in the cache or brought into the cache as a result of executing one of the <code>
   * deletePersistentAll</code> methods undergo life cycle changes as if <code>deletePersistent
   * </code> were called on them.
   *
   * <p>Specifically, if the class of deleted instances implements the delete callback interface,
   * the corresponding callback methods are called on the deleted instances. Similarly, if there are
   * lifecycle listeners registered for delete events on affected classes, the listener is called
   * for each appropriate deleted instance.
   *
   * <p>Before returning control to the application, instances of affected classes in the cache are
   * refreshed to reflect whether they were deleted from the datastore.
   *
   * @return the number of instances of the candidate class that were deleted
   * @since 2.0
   */
  long deletePersistentAll();

  /**
   * The unmodifiable flag, when set, disallows further modification of the query, except for
   * specifying the range, result class, and ignoreCache option. The unmodifiable flag can also be
   * set in metadata.
   *
   * @since 2.0
   */
  void setUnmodifiable();

  /**
   * The unmodifiable flag, when set, disallows further modification of the query, except for
   * specifying the range, result class, and ignoreCache option.
   *
   * @return the current setting of the flag
   * @since 2.0
   */
  boolean isUnmodifiable();

  /**
   * Add a subquery to this query.
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable in the outer query to bind the results of
   *     the subquery
   * @param candidateCollectionExpression the candidate collection of the subquery as an expression
   *     using terms of the outer query
   * @see #addSubquery(Query sub, String variableDeclaration, String candidateCollectionExpression,
   *     String... parameters)
   * @since 2.1
   */
  void addSubquery(Query<?> sub, String variableDeclaration, String candidateCollectionExpression);

  /**
   * Add a subquery to this query. The String version of the method binds the named expression to
   * the parameter implictly or explicitly declared in the subquery.
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable to be used in this Query
   * @param candidateCollectionExpression the candidate collection to apply to the subquery
   * @param parameter the expression from the outer query to bind the parameter in the subquery
   * @see #addSubquery(Query sub, String variableDeclaration, String candidateCollectionExpression,
   *     String... parameters)
   * @since 2.1
   */
  void addSubquery(
      Query<?> sub,
      String variableDeclaration,
      String candidateCollectionExpression,
      String parameter);

  /**
   * Add a subquery to this query. A subquery is composed as a Query and subsequently attached to a
   * different query (the outer query) by calling this method. The query parameter instance is
   * unmodified as a result of the addSubquery or subsequent execution of the outer query. Only some
   * of the query parts are copied for use as the subquery. The parts copied include the candidate
   * class, filter, parameter declarations, variable declarations, imports, ordering specification,
   * uniqueness, result specification, and grouping specification. The association with a
   * PersistenceManager, the candidate collection or extent, result class, and range limits are not
   * used. The String parameters are trimmed of white space. The variableDeclaration parameter is
   * the name of the variable containing the results of the subquery execution. If the same value of
   * variableDeclaration is used to add multiple subqueries, the subquery replaces the previous
   * subquery for the same named variable. If the subquery parameter is null, the variable is unset,
   * effectively making the variable named in the variableDeclaration unbound. If the trimmed value
   * is the empty String, or the parameter is null, then JDOUserException is thrown. The
   * candidateCollectionExpression is the expression from the outer query that represents the
   * candidates over which the subquery is evaluated. If the trimmed value is the empty String, or
   * the parameter is null, then the candidate collection is the extent of the candidate class. The
   * String... version of the method binds the named expressions in turn to parameters in the order
   * in which they are declared in the subquery, or in the order they are found in the filter if not
   * explicitly declared in the subquery.
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable in the outer query to bind the results of
   *     the subquery
   * @param candidateCollectionExpression the candidate collection of the subquery as an expression
   *     using terms of the outer query
   * @param parameters the expressions from the outer query to bind the parameters in the subquery
   * @since 2.1
   */
  void addSubquery(
      Query<?> sub,
      String variableDeclaration,
      String candidateCollectionExpression,
      String... parameters);

  /**
   * Add a subquery to this query. The Map version of the method treats the key of each map entry as
   * the name of the parameter in the subquery, with or without the leading ":", and the value as
   * the name of the expression in the outer query. If the trimmed expression is the empty String
   * for either the parameter or the value of the String[], or for any map key or value, that
   * expression is ignored.
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable to be used in this Query
   * @param candidateCollectionExpression the candidate collection to apply to the subquery
   * @param parameters the expressions from the outer query to bind the parameter in the subquery
   * @see #addSubquery(Query sub, String variableDeclaration, String candidateCollectionExpression,
   *     String... parameters)
   * @since 2.1
   */
  void addSubquery(
      Query<?> sub,
      String variableDeclaration,
      String candidateCollectionExpression,
      Map<?, ?> parameters);

  /**
   * Specify a timeout interval (milliseconds) for any read operations associated with this query.
   * To unset the explicit timeout for this query, specify null. For no timeout, specify 0. If the
   * datastore granularity is larger than milliseconds, the timeout value will be rounded up to the
   * nearest supported datastore value. If a read operation hasn't completed within this interval,
   * executeXXX will throw a JDODatastoreException. If multiple datastore operations are required to
   * complete the query, the timeout value applies to each of them individually. If the datastore
   * and JDO implementation support timeouts, then javax.jdo.option.DatastoreTimeout is returned by
   * PersistenceManagerFactory.supportedOptions(). If timeouts are not supported,this method will
   * throw JDOUnsupportedOptionException.
   *
   * @since 3.0
   * @param interval the timeout interval (milliseconds)
   */
  void setDatastoreReadTimeoutMillis(Integer interval);

  /**
   * Get the effective timeout setting for read operations. If the timeout has not been set on this
   * query explicitly, the effective datastore read timeout value from the persistence manager is
   * returned.
   *
   * @see #setDatastoreReadTimeoutMillis(Integer)
   * @see PersistenceManager#setDatastoreReadTimeoutMillis(Integer)
   * @return the effective timeout setting (milliseconds).
   * @since 3.0
   */
  Integer getDatastoreReadTimeoutMillis();

  /**
   * Specify a timeout interval (milliseconds) for any write operations associated with this query.
   * To unset the explicit timeout for this query, specify null. For no timeout, specify 0. If the
   * datastore granularity is larger than milliseconds, the timeout value will be rounded up to the
   * nearest supported datastore value. If a write operation hasn't completed within this interval,
   * deleteXXX will throw a JDODatastoreException. If multiple datastore operations are required to
   * complete the query, the timeout value applies to each of them individually. If the datastore
   * and JDO implementation support timeouts, then javax.jdo.option.DatastoreTimeout is returned by
   * PersistenceManagerFactory.supportedOptions(). If timeouts are not supported,this method will
   * throw JDOUnsupportedOptionException.
   *
   * @since 3.0
   * @param interval the timeout interval (milliseconds)
   */
  void setDatastoreWriteTimeoutMillis(Integer interval);

  /**
   * Get the effective timeout setting for write operations. If the timeout has not been set on this
   * query explicitly, the effective datastore write timeout value from the persistence manager is
   * returned.
   *
   * @see #setDatastoreWriteTimeoutMillis(Integer)
   * @see PersistenceManager#setDatastoreWriteTimeoutMillis(Integer)
   * @return the effective timeout setting (milliseconds).
   * @since 3.0
   */
  Integer getDatastoreWriteTimeoutMillis();

  /**
   * Method to cancel any executing queries. If the underlying datastore doesn't support
   * cancellation of queries this will throw JDOUnsupportedOptionException. If the cancellation
   * fails (e.g in the underlying datastore) then this will throw a JDOException.
   *
   * @since 3.0
   */
  void cancelAll();

  /**
   * Method to cancel an executing query in the specified thread. If the underlying datastore
   * doesn't support cancellation of queries this will throw JDOUnsupportedOptionException. If the
   * cancellation fails (e.g in the underlying datastore) then this will throw a JDOException.
   *
   * @param thread The thread to cancel
   * @since 3.0
   */
  void cancel(Thread thread);

  /**
   * If <code>true</code>, a lock will be applied to all objects read in this query.
   *
   * <p>If <code>false</code> then retrieved objects will not be locked. If null will fallback to
   * the value for metadata for the class in question.
   *
   * @param serialize the value of the serializeRead property
   * @since 3.0
   */
  void setSerializeRead(Boolean serialize);

  /**
   * Return the current value of the serializeRead property.
   *
   * @return the value of the serializeRead property
   * @since 3.0
   */
  Boolean getSerializeRead();

  /**
   * Save the query, as it is currently defined, as a named query under the specified name. If a
   * named query already exists under this name (either defined in metadata, or previously saved)
   * then it will be overwritten.
   *
   * @param name Name to save it under.
   * @return This query
   */
  Query<T> saveAsNamedQuery(String name);

  /**
   * Set the filter for the query. Shortcut for the {@link #setFilter(String)} method
   *
   * @param filter the query filter.
   * @return This query
   */
  Query<T> filter(String filter);

  /**
   * Set the ordering specification for the result <code>Collection</code>. Shortcut for the {@link
   * #setOrdering(String)} method
   *
   * @param ordering the ordering specification.
   * @return This query
   */
  Query<T> orderBy(String ordering);

  /**
   * Set the grouping expressions, optionally including a "having" clause. Shortcut for the {@link
   * #setGrouping(String)} method
   *
   * @param group a comma-delimited list of expressions, optionally followed by the "having" keyword
   *     and a boolean expression
   * @return This query
   */
  Query<T> groupBy(String group);

  /**
   * Set the result clause for the query. Shortcut for the {@link #setResult(String)} method
   *
   * @param result The result clause
   * @return This query
   */
  Query<T> result(String result);

  /**
   * Set the range of results to return. Shortcut for the {@link #setRange(long, long)} method
   *
   * @param fromIncl 0-based inclusive start index
   * @param toExcl 0-based exclusive end index, or {@link Long#MAX_VALUE} for no limit.
   * @return This query
   */
  Query<T> range(long fromIncl, long toExcl);

  /**
   * Set the range of results to return. Shortcut for the {@link #setRange(String)} method
   *
   * @param fromInclToExcl comma-separated fromIncl and toExcl values
   * @return This query
   */
  Query<T> range(String fromInclToExcl);

  /**
   * Add a subquery to this query. Shortcut for the {@link #subquery(Query, String, String)} method
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable in the outer query to bind the results of
   *     the subquery
   * @param candidateCollectionExpression the candidate collection of the subquery as an expression
   *     using terms of the outer query
   * @return This query
   */
  Query<T> subquery(Query<?> sub, String variableDeclaration, String candidateCollectionExpression);

  /**
   * Add a subquery to this query. Shortcut for the {@link #subquery(Query, String, String, String)}
   * method
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable to be used in this Query
   * @param candidateCollectionExpression the candidate collection to apply to the subquery
   * @param parameter the expression from the outer query to bind the parameter in the subquery
   * @return This query
   */
  Query<T> subquery(
      Query<?> sub,
      String variableDeclaration,
      String candidateCollectionExpression,
      String parameter);

  /**
   * Add a subquery to this query. Shortcut for the {@link #subquery(Query, String, String,
   * String...)} method
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable in the outer query to bind the results of
   *     the subquery
   * @param candidateCollectionExpression the candidate collection of the subquery as an expression
   *     using terms of the outer query
   * @param parameters the expressions from the outer query to bind the parameters in the subquery
   * @return This query
   */
  Query<T> subquery(
      Query<?> sub,
      String variableDeclaration,
      String candidateCollectionExpression,
      String... parameters);

  /**
   * Add a subquery to this query. Shortcut for the {@link #subquery(Query, String, String, Map)}
   * method
   *
   * @param sub the subquery to add to this Query
   * @param variableDeclaration the name of the variable to be used in this Query
   * @param candidateCollectionExpression the candidate collection to apply to the subquery
   * @param parameters the expressions from the outer query to bind the parameter in the subquery
   * @return This query
   */
  Query<T> subquery(
      Query<?> sub,
      String variableDeclaration,
      String candidateCollectionExpression,
      Map<?, ?> parameters);

  /**
   * Set the import statements to be used to identify the fully qualified name of variables or
   * parameters. Shortcut for {@link #declareImports(String)} method.
   *
   * @param imports the imports declaration
   * @return This query
   */
  Query<T> imports(String imports);

  /**
   * Declare the list of parameters for query execution. Shortcut for {@link
   * #declareParameters(String)} method.
   *
   * @param parameters the list of parameters separated by commas.
   * @return This query
   */
  Query<T> parameters(String parameters);

  /**
   * Declare the unbound variables to be used in the query. Shortcut for {@link
   * #declareVariables(String)} method.
   *
   * @param variables the variables separated by semicolons.
   * @return This query
   */
  Query<T> variables(String variables);

  /**
   * Set the datastore read timeout (millis). Shortcut for {@link
   * #setDatastoreReadTimeoutMillis(Integer)} method.
   *
   * @param interval The interval
   * @return This query
   */
  Query<T> datastoreReadTimeoutMillis(Integer interval);

  /**
   * Set the datastore write timeout (millis). Shortcut for {@link
   * #setDatastoreWriteTimeoutMillis(Integer)} method.
   *
   * @param interval The interval
   * @return This query
   */
  Query<T> datastoreWriteTimeoutMillis(Integer interval);

  /**
   * Set whether we to lock all objects read by this query. Shortcut for {@link
   * #setSerializeRead(Boolean)} method.
   *
   * @param serialize Whether to lock
   * @return This query
   */
  Query<T> serializeRead(Boolean serialize);

  /**
   * Set whether to make this query unmodifiable. Shortcut for {@link #setUnmodifiable()} method.
   *
   * @return This query
   */
  Query<T> unmodifiable();

  /**
   * Set whether we to ignore the cache with this query. Shortcut for {@link
   * #setIgnoreCache(boolean)} method.
   *
   * @param flag Whether to ignore the cache
   * @return This query
   */
  Query<T> ignoreCache(boolean flag);

  /**
   * Specify an extension for this query. Shortcut for {@link #addExtension(String, Object)} method.
   *
   * @param key The extension key
   * @param value The extension value
   * @return This query
   */
  Query<T> extension(String key, Object value);

  /**
   * Specify a map of extensions for this query. Shortcut for {@link #setExtensions(Map)} method.
   *
   * @param values The extension map of keys and values
   * @return This query
   */
  Query<T> extensions(Map<?, ?> values);

  /**
   * Method to set the named parameters on this query prior to execution. If using the execute
   * methods taking parameters then those parameter values will override these values. All parameter
   * values specified in this method will only be retained until the subsequent query execution.
   *
   * @param namedParamMap The map of parameter values keyed by their names.
   * @return This query
   */
  Query<T> setNamedParameters(Map<String, ?> namedParamMap);

  /**
   * Method to set the values of the numbered parameters on this query prior to execution. If using
   * the execute methods taking parameters then those parameter values will override these values.
   * All parameter values specified in this method will only be retained until the subsequent query
   * execution.
   *
   * @param paramValues Values of the numbered parameters, in order.
   * @return This query
   */
  Query<T> setParameters(Object... paramValues);

  /**
   * Method to execute the query where there are (potentially) multiple rows and we are returning
   * the candidate type. Any parameters required should be set prior to calling this method, using
   * one of the <cite>setParameters</cite> methods.
   *
   * <p>Calling this method with a result being specified will result in JDOUserException being
   * thrown.
   *
   * @return The List of candidate objects
   */
  List<T> executeList();

  /**
   * Method to execute the query where there is a single row and we are returning the candidate
   * type. Any parameters required should be set prior to calling this method, using one of the
   * <cite>setParameters</cite> methods.
   *
   * <p>Calling this method with a result being specified will result in JDOUserException being
   * thrown.
   *
   * @return The candidate object returned by the query (or null)
   */
  T executeUnique();

  /**
   * Method to execute the query where there are (potentially) multiple rows and we are returning a
   * result type for the specified result. Any parameters required should be set prior to calling
   * this method, using one of the <cite>setParameters</cite> methods.
   *
   * <p>Calling this method with no result being specified will result in JDOUserException being
   * thrown.
   *
   * @param resultCls The result class
   * @return List of result objects
   * @param <R> The result type
   */
  <R> List<R> executeResultList(Class<R> resultCls);

  /**
   * Method to execute the query where there is a single row and we are returning a result type for
   * the specified result. Any parameters required should be set prior to calling this method, using
   * one of the <cite>setParameters</cite> methods.
   *
   * <p>Calling this method with no result being specified will result in JDOUserException being
   * thrown.
   *
   * @param resultCls The result class
   * @return The result object (or null)
   * @param <R> The result type
   */
  <R> R executeResultUnique(Class<R> resultCls);

  /**
   * Method to execute the query where there are (potentially) multiple rows and we have a result
   * defined but no result class. Any parameters required should be set prior to calling this
   * method, using one of the <cite>setParameters</cite> methods.
   *
   * <p>Calling this method with no result being specified will result in JDOUserException being
   * thrown.
   *
   * @return The list of query results
   */
  List<Object> executeResultList();

  /**
   * Method to execute the query where there is a single row and we have a result defined but no
   * result class. Any parameters required should be set prior to calling this method, using one of
   * the <cite>setParameters</cite> methods.
   *
   * <p>Calling this method with no result being specified will result in JDOUserException being
   * thrown.
   *
   * @return The query result (or null)
   */
  Object executeResultUnique();
}
