001package com.avaje.ebean;
002
003import com.avaje.ebean.text.PathProperties;
004import org.jetbrains.annotations.Nullable;
005
006import java.io.Serializable;
007import java.sql.Timestamp;
008import java.util.List;
009import java.util.Map;
010import java.util.Set;
011
012/**
013 * Object relational query for finding a List, Set, Map or single entity bean.
014 * <p>
015 * Example: Create the query using the API.
016 * </p>
017 * 
018 * <pre>{@code
019 *
020 * List<Order> orderList = 
021 *   ebeanServer.find(Order.class)
022 *     .fetch("customer")
023 *     .fetch("details")
024 *     .where()
025 *       .like("customer.name","rob%")
026 *       .gt("orderDate",lastWeek)
027 *     .orderBy("customer.id, id desc")
028 *     .setMaxRows(50)
029 *     .findList();
030 *   
031 * ...
032 * }</pre>
033 * 
034 * <p>
035 * Example: The same query using the query language
036 * </p>
037 * 
038 * <pre>{@code
039 *
040 * String oql = 
041 *      "  find  order "
042 *      +" fetch customer "
043 *      +" fetch details "
044 *      +" where customer.name like :custName and orderDate > :minOrderDate "
045 *      +" order by customer.id, id desc "
046 *      +" limit 50 ";
047 *   
048 * Query<Order> query = ebeanServer.createQuery(Order.class, oql);
049 * query.setParameter("custName", "Rob%");
050 * query.setParameter("minOrderDate", lastWeek);
051 *   
052 * List<Order> orderList = query.findList();
053 * ...
054 * }</pre>
055 * 
056 * <p>
057 * Example: Using a named query called "with.cust.and.details"
058 * </p>
059 * 
060 * <pre>{@code
061 *
062 * Query<Order> query = ebeanServer.createNamedQuery(Order.class,"with.cust.and.details");
063 * query.setParameter("custName", "Rob%");
064 * query.setParameter("minOrderDate", lastWeek);
065 *   
066 * List<Order> orderList = query.findList();
067 * ...
068 * }</pre>
069 * 
070 * <h3>AutoTune</h3>
071 * <p>
072 * Ebean has built in support for "AutoTune". This is a mechanism where a query
073 * can be automatically tuned based on profiling information that is collected.
074 * </p>
075 * <p>
076 * This is effectively the same as automatically using select() and fetch() to
077 * build a query that will fetch all the data required by the application and no
078 * more.
079 * </p>
080 * <p>
081 * It is expected that AutoTune will be the default approach for many queries
082 * in a system. It is possibly not as useful where the result of a query is sent
083 * to a remote client or where there is some requirement for "Read Consistency"
084 * guarantees.
085 * </p>
086 * 
087 * <h3>Query Language</h3>
088 * <p>
089 * <b>Partial Objects</b>
090 * </p>
091 * <p>
092 * The <em>find</em> and <em>fetch</em> clauses support specifying a list of
093 * properties to fetch. This results in objects that are "partially populated".
094 * If you try to get a property that was not populated a "lazy loading" query
095 * will automatically fire and load the rest of the properties of the bean (This
096 * is very similar behaviour as a reference object being "lazy loaded").
097 * </p>
098 * <p>
099 * Partial objects can be saved just like fully populated objects. If you do
100 * this you should remember to include the <em>"Version"</em> property in the
101 * initial fetch. If you do not include a version property then optimistic
102 * concurrency checking will occur but only include the fetched properties.
103 * Refer to "ALL Properties/Columns" mode of Optimistic Concurrency checking.
104 * </p>
105 * 
106 * <pre>{@code
107 * [ find  {bean type} [ ( * | {fetch properties} ) ] ]
108 * [ fetch {associated bean} [ ( * | {fetch properties} ) ] ]
109 * [ where {predicates} ]
110 * [ order by {order by properties} ]
111 * [ limit {max rows} [ offset {first row} ] ]
112 * }</pre>
113 * 
114 * <p>
115 * <b>FIND</b> <b>{bean type}</b> [ ( <i>*</i> | <i>{fetch properties}</i> ) ]
116 * </p>
117 * <p>
118 * With the find you specify the type of beans to fetch. You can optionally
119 * specify a list of properties to fetch. If you do not specify a list of
120 * properties ALL the properties for those beans are fetched.
121 * </p>
122 * <p>
123 * In object graph terms the <em>find</em> clause specifies the type of bean at
124 * the root level and the <em>fetch</em> clauses specify the paths of the object
125 * graph to populate.
126 * </p>
127 * <p>
128 * <b>FETCH</b> <b>{associated property}</b> [ ( <i>*</i> | <i>{fetch
129 * properties}</i> ) ]
130 * </p>
131 * <p>
132 * With the fetch you specify the associated property to fetch and populate. The
133 * associated property is a OneToOnem, ManyToOne, OneToMany or ManyToMany
134 * property. When the query is executed Ebean will fetch the associated data.
135 * </p>
136 * <p>
137 * For fetch of a path we can optionally specify a list of properties to fetch.
138 * If you do not specify a list of properties ALL the properties for that bean
139 * type are fetched.
140 * </p>
141 * <p>
142 * <b>WHERE</b> <b>{list of predicates}</b>
143 * </p>
144 * <p>
145 * The list of predicates which are joined by AND OR NOT ( and ). They can
146 * include named (or positioned) bind parameters. These parameters will need to
147 * be bound by {@link Query#setParameter(String, Object)}.
148 * </p>
149 * <p>
150 * <b>ORDER BY</b> <b>{order by properties}</b>
151 * </p>
152 * <p>
153 * The list of properties to order the result. You can include ASC (ascending)
154 * and DESC (descending) in the order by clause.
155 * </p>
156 * <p>
157 * <b>LIMIT</b> <b>{max rows}</b> [ OFFSET <i>{first row}</i> ]
158 * </p>
159 * <p>
160 * The limit offset specifies the max rows and first row to fetch. The offset is
161 * optional.
162 * </p>
163 * <h4>Examples of Ebean's Query Language</h4>
164 * <p>
165 * Find orders fetching all its properties
166 * </p>
167 * 
168 * <pre>{@code
169 * find order
170 * }</pre>
171 * 
172 * <p>
173 * Find orders fetching all its properties
174 * </p>
175 * 
176 * <pre>{@code
177 * find order (*)
178 * }</pre>
179 * 
180 * <p>
181 * Find orders fetching its id, shipDate and status properties. Note that the id
182 * property is always fetched even if it is not included in the list of fetch
183 * properties.
184 * </p>
185 * 
186 * <pre>{@code
187 * find order (shipDate, status)
188 * }</pre>
189 * 
190 * <p>
191 * Find orders with a named bind variable (that will need to be bound via
192 * {@link Query#setParameter(String, Object)}).
193 * </p>
194 * 
195 * <pre>{@code
196 * find order
197 * where customer.name like :custLike
198 * }</pre>
199 * 
200 * <p>
201 * Find orders and also fetch the customer with a named bind parameter. This
202 * will fetch and populate both the order and customer objects.
203 * </p>
204 * 
205 * <pre>{@code
206 * find  order
207 * fetch customer
208 * where customer.id = :custId
209 * }</pre>
210 * 
211 * <p>
212 * Find orders and also fetch the customer, customer shippingAddress, order
213 * details and related product. Note that customer and product objects will be
214 * "Partial Objects" with only some of their properties populated. The customer
215 * objects will have their id, name and shipping address populated. The product
216 * objects (associated with each order detail) will have their id, sku and name
217 * populated.
218 * </p>
219 * 
220 * <pre>{@code
221 * find  order
222 * fetch customer (name)
223 * fetch customer.shippingAddress
224 * fetch details
225 * fetch details.product (sku, name)
226 * }</pre>
227 * 
228 * <h3>Early parsing of the Query</h3>
229 * <p>
230 * When you get a Query object from a named query, the query statement has
231 * already been parsed. You can then add to that query (add fetch paths, add to
232 * the where clause) or override some of its settings (override the order by
233 * clause, first rows, max rows).
234 * </p>
235 * <p>
236 * The thought is that you can use named queries as a 'starting point' and then
237 * modify the query to suit specific needs.
238 * </p>
239 * <h3>Building the Where clause</h3>
240 * <p>
241 * You can add to the where clause using Expression objects or a simple String.
242 * Note that the ExpressionList has methods to add most of the common
243 * expressions that you will need.
244 * <ul>
245 * <li>where(String addToWhereClause)</li>
246 * <li>where().add(Expression expression)</li>
247 * <li>where().eq(propertyName, value).like(propertyName , value)...</li>
248 * </ul>
249 * </p>
250 * <p>
251 * The full WHERE clause is constructed by appending together
252 * <li>original query where clause (Named query or query.setQuery(String oql))</li>
253 * <li>clauses added via query.where(String addToWhereClause)</li>
254 * <li>clauses added by Expression objects</li>
255 * </p>
256 * <p>
257 * The above is the order that these are clauses are appended to give the full
258 * WHERE clause.
259 * </p>
260 * <h3>Design Goal</h3>
261 * <p>
262 * This query language is NOT designed to be a replacement for SQL. It is
263 * designed to be a simple way to describe the "Object Graph" you want Ebean to
264 * build for you. Each find/fetch represents a node in that "Object Graph" which
265 * makes it easy to define for each node which properties you want to fetch.
266 * </p>
267 * <p>
268 * Once you hit the limits of this language such as wanting aggregate functions
269 * (sum, average, min etc) or recursive queries etc you use SQL. Ebean's goal is
270 * to make it as easy as possible to use your own SQL to populate entity beans.
271 * Refer to {@link RawSql} .
272 * </p>
273 * 
274 * @param <T>
275 *          the type of Entity bean this query will fetch.
276 */
277public interface Query<T> extends Serializable {
278
279  /**
280   * Return the RawSql that was set to use for this query.
281   */
282  RawSql getRawSql();
283
284  /**
285   * Set RawSql to use for this query.
286   */
287  Query<T> setRawSql(RawSql rawSql);
288
289  /**
290   * Perform an 'As of' query using history tables to return the object graph
291   * as of a time in the past.
292   * <p>
293   *   To perform this query the DB must have underlying history tables.
294   * </p>
295   *
296   * @param asOf the date time in the past at which you want to view the data
297   */
298  Query<T> asOf(Timestamp asOf);
299
300  /**
301   * Cancel the query execution if supported by the underlying database and
302   * driver.
303   * <p>
304   * This must be called from a different thread to the query executor.
305   * </p>
306   */
307  void cancel();
308
309  /**
310   * Return a copy of the query.
311   * <p>
312   * This is so that you can use a Query as a "prototype" for creating other
313   * query instances. You could create a Query with various where expressions
314   * and use that as a "prototype" - using this copy() method to create a new
315   * instance that you can then add other expressions then execute.
316   * </p>
317   */
318  Query<T> copy();
319
320  /**
321   * Specify the PersistenceContextScope to use for this query.
322   * <p/>
323   * When this is not set the 'default' configured on {@link com.avaje.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)}
324   * is used - this value defaults to {@link com.avaje.ebean.PersistenceContextScope#TRANSACTION}.
325   * <p/>
326   * Note that the same persistence Context is used for subsequent lazy loading and query join queries.
327   * <p/>
328   * Note that #findEach uses a 'per object graph' PersistenceContext so this scope is ignored for
329   * queries executed as #findIterate, #findEach, #findEachWhile.
330   *
331   * @param scope The scope to use for this query and subsequent lazy loading.
332   */
333  Query<T> setPersistenceContextScope(PersistenceContextScope scope);
334
335  /**
336   * Return the ExpressionFactory used by this query.
337   */
338  ExpressionFactory getExpressionFactory();
339
340  /**
341   * Returns true if this query was tuned by autoTune.
342   */
343  boolean isAutoTuned();
344
345  /**
346   * Explicitly specify whether to use AutoTune for this query.
347   * <p>
348   * If you do not call this method on a query the "Implicit AutoTune mode" is
349   * used to determine if AutoTune should be used for a given query.
350   * </p>
351   * <p>
352   * AutoTune can add additional fetch paths to the query and specify which
353   * properties are included for each path. If you have explicitly defined some
354   * fetch paths AutoTune will not remove them.
355   * </p>
356   */
357  Query<T> setAutoTune(boolean autoTune);
358
359  /**
360   * Set the default lazy loading batch size to use.
361   * <p>
362   * When lazy loading is invoked on beans loaded by this query then this sets the
363   * batch size used to load those beans.
364   *
365   * @param lazyLoadBatchSize the number of beans to lazy load in a single batch
366   */
367  Query<T> setLazyLoadBatchSize(int lazyLoadBatchSize);
368
369  /**
370   * Disable read auditing for this query.
371   * <p>
372   * This is intended to be used when the query is not a user initiated query and instead
373   * part of the internal processing in an application to load a cache or document store etc.
374   * In these cases we don't want the query to be part of read auditing.
375   * </p>
376   */
377  Query<T> setDisableReadAuditing();
378
379  /**
380   * Explicitly set a comma delimited list of the properties to fetch on the
381   * 'main' root level entity bean (aka partial object). Note that '*' means all
382   * properties.
383   * <p>
384   * You use {@link #fetch(String, String)} to specify specific properties to fetch
385   * on other non-root level paths of the object graph.
386   * </p>
387   *
388   * <pre>{@code
389   *
390   * List<Customer> customers =
391   *     ebeanServer.find(Customer.class)
392   *     // Only fetch the customer id, name and status.
393   *     // This is described as a "Partial Object"
394   *     .select("name, status")
395   *     .where.ilike("name", "rob%")
396   *     .findList();
397   *
398   * }</pre>
399   *
400   * @param fetchProperties
401   *          the properties to fetch for this bean (* = all properties).
402   */
403  Query<T> select(String fetchProperties);
404
405  /**
406   * Specify a path to <em>fetch</em> with its specific properties to include
407   * (aka partial object).
408   * <p>
409   * When you specify a join this means that property (associated bean(s)) will
410   * be fetched and populated. If you specify "*" then all the properties of the
411   * associated bean will be fetched and populated. You can specify a comma
412   * delimited list of the properties of that associated bean which means that
413   * only those properties are fetched and populated resulting in a
414   * "Partial Object" - a bean that only has some of its properties populated.
415   * </p>
416   * 
417   * <pre>{@code
418   *
419   * // query orders...
420   * List<Order> orders =
421   *     ebeanserver.find(Order.class)
422   *       // fetch the customer...
423   *       // ... getting the customers name and phone number
424   *       .fetch("customer", "name, phoneNumber")
425   * 
426   *       // ... also fetch the customers billing address (* = all properties)
427   *       .fetch("customer.billingAddress", "*")
428   *       .findList();
429   * }</pre>
430   * 
431   * <p>
432   * If columns is null or "*" then all columns/properties for that path are
433   * fetched.
434   * </p>
435   * 
436   * <pre>{@code
437   *
438   * // fetch customers (their id, name and status)
439   * List<Customer> customers =
440   *     ebeanServer.find(Customer.class)
441   *     .select("name, status")
442   *     .fetch("contacts", "firstName,lastName,email")
443   *     .findList();
444   *
445   * }</pre>
446   * 
447   * @param path
448   *          the path of an associated (1-1,1-M,M-1,M-M) bean.
449   * @param fetchProperties
450   *          properties of the associated bean that you want to include in the
451   *          fetch (* means all properties, null also means all properties).
452   */
453  Query<T> fetch(String path, String fetchProperties);
454
455  /**
456   * Additionally specify a FetchConfig to use a separate query or lazy loading
457   * to load this path.
458   *
459   * <pre>{@code
460   *
461   * // fetch customers (their id, name and status)
462   * List<Customer> customers =
463   *     ebeanServer.find(Customer.class)
464   *     .select("name, status")
465   *     .fetch("contacts", "firstName,lastName,email", new FetchConfig().lazy(10))
466   *     .findList();
467   *
468   * }</pre>
469   */
470  Query<T> fetch(String assocProperty, String fetchProperties, FetchConfig fetchConfig);
471
472  /**
473   * Specify a path to load including all its properties.
474   * <p>
475   * The same as {@link #fetch(String, String)} with the fetchProperties as "*".
476   * </p>
477   * <pre>{@code
478   *
479   * // fetch customers (their id, name and status)
480   * List<Customer> customers =
481   *     ebeanServer.find(Customer.class)
482   *     // eager fetch the contacts
483   *     .fetch("contacts")
484   *     .findList();
485   *
486   * }</pre>
487   *
488   * @param path
489   *          the property of an associated (1-1,1-M,M-1,M-M) bean.
490   */
491  Query<T> fetch(String path);
492
493  /**
494   * Additionally specify a JoinConfig to specify a "query join" and or define
495   * the lazy loading query.
496   *
497   *
498   * <pre>{@code
499   *
500   * // fetch customers (their id, name and status)
501   * List<Customer> customers =
502   *     ebeanServer.find(Customer.class)
503   *     // lazy fetch contacts with a batch size of 100
504   *     .fetch("contacts", new FetchConfig().lazy(100))
505   *     .findList();
506   *
507   * }</pre>
508   */
509  Query<T> fetch(String path, FetchConfig fetchConfig);
510
511  /**
512   * Apply the path properties replacing the select and fetch clauses.
513   * <p>
514   * This is typically used when the PathProperties is applied to both the query and the JSON output.
515   * </p>
516   */
517  Query<T> apply(PathProperties pathProperties);
518
519  /**
520   * Execute the query returning the list of Id's.
521   * <p>
522   * This query will execute against the EbeanServer that was used to create it.
523   * </p>
524   * 
525   * @see EbeanServer#findIds(Query, Transaction)
526   */
527  List<Object> findIds();
528
529  /**
530   * Execute the query iterating over the results.
531   * <p>
532   * Remember that with {@link QueryIterator} you must call
533   * {@link QueryIterator#close()} when you have finished iterating the results
534   * (typically in a finally block).
535   * </p>
536   * <p>
537   * findEach() and findEachWhile() are preferred to findIterate() as they ensure
538   * the jdbc statement and resultSet are closed at the end of the iteration.
539   * </p>
540   * <p>
541   * This query will execute against the EbeanServer that was used to create it.
542   * </p>
543   */
544  QueryIterator<T> findIterate();
545
546
547
548  /**
549   * Execute the query processing the beans one at a time.
550   * <p>
551   * This method is appropriate to process very large query results as the
552   * beans are consumed one at a time and do not need to be held in memory
553   * (unlike #findList #findSet etc)
554   * </p>
555   * <p>
556   * Note that internally Ebean can inform the JDBC driver that it is expecting larger
557   * resultSet and specifically for MySQL this hint is required to stop it's JDBC driver
558   * from buffering the entire resultSet. As such, for smaller resultSets findList() is
559   * generally preferable.
560   * </p>
561   * <p>
562   * Compared with #findEachWhile this will always process all the beans where as
563   * #findEachWhile provides a way to stop processing the query result early before
564   * all the beans have been read.
565   * </p>
566   * <p>
567   * This method is functionally equivalent to findIterate() but instead of using an
568   * iterator uses the QueryEachConsumer (SAM) interface which is better suited to use
569   * with Java8 closures.
570   * </p>
571   *
572   * <pre>{@code
573   *
574   *  ebeanServer.find(Customer.class)
575   *     .where().eq("status", Status.NEW)
576   *     .order().asc("id")
577   *     .findEach((Customer customer) -> {
578   *
579   *       // do something with customer
580   *       System.out.println("-- visit " + customer);
581   *     });
582   *
583   * }</pre>
584   *
585   * @param consumer
586   *          the consumer used to process the queried beans.
587   */
588  void findEach(QueryEachConsumer<T> consumer);
589
590  /**
591   * Execute the query using callbacks to a visitor to process the resulting
592   * beans one at a time.
593   * <p>
594   * This method is functionally equivalent to findIterate() but instead of using an
595   * iterator uses the QueryEachWhileConsumer (SAM) interface which is better suited to use
596   * with Java8 closures.
597   * </p>
598
599   *
600   * <pre>{@code
601   *
602   *  ebeanServer.find(Customer.class)
603   *     .fetch("contacts", new FetchConfig().query(2))
604   *     .where().eq("status", Status.NEW)
605   *     .order().asc("id")
606   *     .setMaxRows(2000)
607   *     .findEachWhile((Customer customer) -> {
608   *
609   *       // do something with customer
610   *       System.out.println("-- visit " + customer);
611   *
612   *       // return true to continue processing or false to stop
613   *       return (customer.getId() < 40);
614   *     });
615   *
616   * }</pre>
617   *
618   * @param consumer
619   *          the consumer used to process the queried beans.
620   */
621  void findEachWhile(QueryEachWhileConsumer<T> consumer);
622
623  /**
624   * Execute the query returning the list of objects.
625   * <p>
626   * This query will execute against the EbeanServer that was used to create it.
627   * </p>
628   *
629   * <pre>{@code
630   *
631   * List<Customer> customers =
632   *     ebeanServer.find(Customer.class)
633   *     .where().ilike("name", "rob%")
634   *     .findList();
635   *
636   * }</pre>
637   *
638   * @see EbeanServer#findList(Query, Transaction)
639   */
640  List<T> findList();
641
642  /**
643   * Execute the query returning the set of objects.
644   * <p>
645   * This query will execute against the EbeanServer that was used to create it.
646   * </p>
647   *
648   * <pre>{@code
649   *
650   * Set<Customer> customers =
651   *     ebeanServer.find(Customer.class)
652   *     .where().ilike("name", "rob%")
653   *     .findSet();
654   *
655   * }</pre>
656   *
657   * @see EbeanServer#findSet(Query, Transaction)
658   */
659  Set<T> findSet();
660
661  /**
662   * Execute the query returning a map of the objects.
663   * <p>
664   * This query will execute against the EbeanServer that was used to create it.
665   * </p>
666   * <p>
667   * You can use setMapKey() so specify the property values to be used as keys
668   * on the map. If one is not specified then the id property is used.
669   * </p>
670   * 
671   * <pre>{@code
672   *
673   * Map<?, Product> map =
674   *   ebeanServer.find(Product.class)
675   *     .setMapKey("sku")
676   *     .findMap();
677   *
678   * }</pre>
679   * 
680   * @see EbeanServer#findMap(Query, Transaction)
681   */
682  Map<?, T> findMap();
683
684  /**
685   * Return a typed map specifying the key property and type.
686   */
687  <K> Map<K, T> findMap(String keyProperty, Class<K> keyType);
688
689  /**
690   * Execute the query returning either a single bean or null (if no matching
691   * bean is found).
692   * <p>
693   * If more than 1 row is found for this query then a PersistenceException is
694   * thrown.
695   * </p>
696   * <p>
697   * This is useful when your predicates dictate that your query should only
698   * return 0 or 1 results.
699   * </p>
700   * 
701   * <pre>{@code
702   *
703   * // assuming the sku of products is unique...
704   * Product product =
705   *     ebeanServer.find(Product.class)
706   *         .where().eq("sku", "aa113")
707   *         .findUnique();
708   * ...
709   * }</pre>
710   * 
711   * <p>
712   * It is also useful with finding objects by their id when you want to specify
713   * further join information.
714   * </p>
715   * 
716   * <pre>{@code
717   *
718   * // Fetch order 1 and additionally fetch join its order details...
719   * Order order = 
720   *     ebeanServer.find(Order.class)
721   *       .setId(1)
722   *       .fetch("details")
723   *       .findUnique();
724   *
725   * // the order details were eagerly loaded
726   * List<OrderDetail> details = order.getDetails();
727   * ...
728   * }</pre>
729   */
730  @Nullable
731  T findUnique();
732
733  /**
734   * Return versions of a @History entity bean.
735   * <p>
736   *   Note that this query will work against view based history implementations
737   *   but not sql2011 standards based implementations that require a start and
738   *   end timestamp to be specified.
739   * </p>
740   * <p>
741   *   Generally this query is expected to be a find by id or unique predicates query.
742   *   It will execute the query against the history returning the versions of the bean.
743   * </p>
744   */
745  List<Version<T>> findVersions();
746
747  /**
748   * Return versions of a @History entity bean between the 2 timestamps.
749   * <p>
750   *   Generally this query is expected to be a find by id or unique predicates query.
751   *   It will execute the query against the history returning the versions of the bean.
752   * </p>
753   */
754  List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
755
756  /**
757   * Execute as a delete query deleting the 'root level' beans that match the predicates
758   * in the query.
759   * <p>
760   * Note that if the query includes joins then the generated delete statement may not be
761   * optimal depending on the database platform.
762   * </p>
763   *
764   * @return the number of beans/rows that were deleted.
765   */
766  int delete();
767
768  /**
769   * Return the count of entities this query should return.
770   * <p>
771   * This is the number of 'top level' or 'root level' entities.
772   * </p>
773   */
774  int findRowCount();
775
776  /**
777   * Execute find row count query in a background thread.
778   * <p>
779   * This returns a Future object which can be used to cancel, check the
780   * execution status (isDone etc) and get the value (with or without a
781   * timeout).
782   * </p>
783   * 
784   * @return a Future object for the row count query
785   */
786  FutureRowCount<T> findFutureRowCount();
787
788  /**
789   * Execute find Id's query in a background thread.
790   * <p>
791   * This returns a Future object which can be used to cancel, check the
792   * execution status (isDone etc) and get the value (with or without a
793   * timeout).
794   * </p>
795   * 
796   * @return a Future object for the list of Id's
797   */
798  FutureIds<T> findFutureIds();
799
800  /**
801   * Execute find list query in a background thread.
802   * <p>
803   * This query will execute in it's own PersistenceContext and using its own transaction.
804   * What that means is that it will not share any bean instances with other queries.
805   * </p>
806   *
807   * @return a Future object for the list result of the query
808   */
809  FutureList<T> findFutureList();
810
811  /**
812   * Return a PagedList for this query.
813   * <p>
814   * The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and
815   * {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to
816   * {@link Query#findFutureRowCount()} to determine total row count, total page count etc.
817   * </p>
818   * <p>
819   * Internally this works using {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} on
820   * the query. This translates into SQL that uses limit offset, rownum or row_number function to
821   * limit the result set.
822   * </p>
823   *
824   * <h4>Example: typical use including total row count</h4>
825   * <pre>{@code
826   *
827   *     // We want to find the first 100 new orders
828   *     //  ... 0 means first page
829   *     //  ... page size is 100
830   *
831   *     PagedList<Order> pagedList
832   *       = ebeanServer.find(Order.class)
833   *       .where().eq("status", Order.Status.NEW)
834   *       .order().asc("id")
835   *       .findPagedList(0, 100);
836   *
837   *     // Optional: initiate the loading of the total
838   *     // row count in a background thread
839   *     pagedList.loadRowCount();
840   *
841   *     // fetch and return the list in the foreground thread
842   *     List<Order> orders = pagedList.getList();
843   *
844   *     // get the total row count (from the future)
845   *     int totalRowCount = pagedList.getTotalRowCount();
846   *
847   * }</pre>
848   *
849   * @param pageIndex
850   *          The zero based index of the page.
851   * @param pageSize
852   *          The number of beans to return per page.
853   * @return The PagedList
854   */
855  PagedList<T> findPagedList(int pageIndex, int pageSize);
856
857  /**
858   * Set a named bind parameter. Named parameters have a colon to prefix the name.
859   * 
860   * <pre>{@code
861   *
862   * // a query with a named parameter
863   * String oql = "find order where status = :orderStatus";
864   * 
865   * Query<Order> query = ebeanServer.find(Order.class, oql);
866   * 
867   * // bind the named parameter
868   * query.bind("orderStatus", OrderStatus.NEW);
869   * List<Order> list = query.findList();
870   *
871   * }</pre>
872   * 
873   * @param name
874   *          the parameter name
875   * @param value
876   *          the parameter value
877   */
878  Query<T> setParameter(String name, Object value);
879
880  /**
881   * Set an ordered bind parameter according to its position. Note that the
882   * position starts at 1 to be consistent with JDBC PreparedStatement. You need
883   * to set a parameter value for each ? you have in the query.
884   * 
885   * <pre>{@code
886   *
887   * // a query with a positioned parameter
888   * String oql = "where status = ? order by id desc";
889   * 
890   * Query<Order> query = ebeanServer.createQuery(Order.class, oql);
891   * 
892   * // bind the parameter
893   * query.setParameter(1, OrderStatus.NEW);
894   * 
895   * List<Order> list = query.findList();
896   *
897   * }</pre>
898   * 
899   * @param position
900   *          the parameter bind position starting from 1 (not 0)
901   * @param value
902   *          the parameter bind value.
903   */
904  Query<T> setParameter(int position, Object value);
905
906  /**
907   * Set the Id value to query. This is used with findUnique().
908   * <p>
909   * You can use this to have further control over the query. For example adding
910   * fetch joins.
911   * </p>
912   * 
913   * <pre>{@code
914   *
915   * Order order =
916   *     ebeanServer.find(Order.class)
917   *     .setId(1)
918   *     .fetch("details")
919   *     .findUnique();
920   *
921   * // the order details were eagerly fetched
922   * List<OrderDetail> details = order.getDetails();
923   *
924   * }</pre>
925   */
926  Query<T> setId(Object id);
927
928  /**
929   * Return the Id value.
930   */
931  Object getId();
932
933  /**
934   * Add additional clause(s) to the where clause.
935   * <p>
936   * This typically contains named parameters which will need to be set via
937   * {@link #setParameter(String, Object)}.
938   * </p>
939   * 
940   * <pre>{@code
941   *
942   * Query<Order> query = ebeanServer.createQuery(Order.class, "top");
943   * ...
944   * if (...) {
945   *   query.where("status = :status and lower(customer.name) like :custName");
946   *   query.setParameter("status", Order.NEW);
947   *   query.setParameter("custName", "rob%");
948   * }
949   *
950   * }</pre>
951   * 
952   * <p>
953   * Internally the addToWhereClause string is processed by removing named
954   * parameters (replacing them with ?) and by converting logical property names
955   * to database column names (with table alias). The rest of the string is left
956   * as is and it is completely acceptable and expected for the addToWhereClause
957   * string to include sql functions and columns.
958   * </p>
959   * 
960   * @param addToWhereClause
961   *          the clause to append to the where clause which typically contains
962   *          named parameters.
963   * @return The query object
964   */
965  Query<T> where(String addToWhereClause);
966
967  /**
968   * Add a single Expression to the where clause returning the query.
969   * 
970   * <pre>{@code
971   *
972   * List<Order> newOrders = 
973   *     ebeanServer.find(Order.class)
974   *            .where().eq("status", Order.NEW)
975   *            .findList();
976   * ...
977   *
978   * }</pre>
979   */
980  Query<T> where(Expression expression);
981
982  /**
983   * Add Expressions to the where clause with the ability to chain on the
984   * ExpressionList. You can use this for adding multiple expressions to the
985   * where clause.
986   * 
987   * <pre>{@code
988   *
989   * List<Order> orders =
990   *     ebeanServer.find(Order.class)
991   *     .where()
992   *       .eq("status", Order.NEW)
993   *       .ilike("customer.name","rob%")
994   *     .findList();
995   *
996   * }</pre>
997   * 
998   * @see Expr
999   * @return The ExpressionList for adding expressions to.
1000   */
1001  ExpressionList<T> where();
1002
1003  /**
1004   * This applies a filter on the 'many' property list rather than the root
1005   * level objects.
1006   * <p>
1007   * Typically you will use this in a scenario where the cardinality is high on
1008   * the 'many' property you wish to join to. Say you want to fetch customers
1009   * and their associated orders... but instead of getting all the orders for
1010   * each customer you only want to get the new orders they placed since last
1011   * week. In this case you can use filterMany() to filter the orders.
1012   * </p>
1013   * 
1014   * <pre>{@code
1015   * 
1016   * List<Customer> list =
1017   *     ebeanServer.find(Customer.class)
1018   *     // .fetch("orders", new FetchConfig().lazy())
1019   *     // .fetch("orders", new FetchConfig().query())
1020   *     .fetch("orders")
1021   *     .where().ilike("name", "rob%")
1022   *     .filterMany("orders").eq("status", Order.Status.NEW).gt("orderDate", lastWeek)
1023   *     .findList();
1024   * 
1025   * }</pre>
1026   * 
1027   * <p>
1028   * Please note you have to be careful that you add expressions to the correct
1029   * expression list - as there is one for the 'root level' and one for each
1030   * filterMany that you have.
1031   * </p>
1032   * 
1033   * @param propertyName
1034   *          the name of the many property that you want to have a filter on.
1035   * 
1036   * @return the expression list that you add filter expressions for the many
1037   *         to.
1038   */
1039  ExpressionList<T> filterMany(String propertyName);
1040
1041  /**
1042   * Add Expressions to the Having clause return the ExpressionList.
1043   * <p>
1044   * Currently only beans based on raw sql will use the having clause.
1045   * </p>
1046   * <p>
1047   * Note that this returns the ExpressionList (so you can add multiple
1048   * expressions to the query in a fluent API way).
1049   * </p>
1050   * 
1051   * @see Expr
1052   * @return The ExpressionList for adding more expressions to.
1053   */
1054  ExpressionList<T> having();
1055
1056  /**
1057   * Add additional clause(s) to the having clause.
1058   * <p>
1059   * This typically contains named parameters which will need to be set via
1060   * {@link #setParameter(String, Object)}.
1061   * </p>
1062   * 
1063   * <pre>{@code
1064   *
1065   * List<ReportOrder> query =
1066   *     ebeanServer.find(ReportOrder.class)
1067   *     .having("score > :min").setParameter("min", 1)
1068   *     .findList();
1069   *
1070   * }</pre>
1071   * 
1072   * @param addToHavingClause
1073   *          the clause to append to the having clause which typically contains
1074   *          named parameters.
1075   * @return The query object
1076   */
1077  Query<T> having(String addToHavingClause);
1078
1079  /**
1080   * Add an expression to the having clause returning the query.
1081   * <p>
1082   * Currently only beans based on raw sql will use the having clause.
1083   * </p>
1084   * <p>
1085   * This is similar to {@link #having()} except it returns the query rather
1086   * than the ExpressionList. This is useful when you want to further specify
1087   * something on the query.
1088   * </p>
1089   * 
1090   * @param addExpressionToHaving
1091   *          the expression to add to the having clause.
1092   * @return the Query object
1093   */
1094  Query<T> having(Expression addExpressionToHaving);
1095
1096  /**
1097   * Set the order by clause replacing the existing order by clause if there is
1098   * one.
1099   * <p>
1100   * This follows SQL syntax using commas between each property with the
1101   * optional asc and desc keywords representing ascending and descending order
1102   * respectively.
1103   * </p>
1104   * <p>
1105   * This is EXACTLY the same as {@link #order(String)}.
1106   * </p>
1107   */
1108  Query<T> orderBy(String orderByClause);
1109
1110  /**
1111   * Set the order by clause replacing the existing order by clause if there is
1112   * one.
1113   * <p>
1114   * This follows SQL syntax using commas between each property with the
1115   * optional asc and desc keywords representing ascending and descending order
1116   * respectively.
1117   * </p>
1118   * <p>
1119   * This is EXACTLY the same as {@link #orderBy(String)}.
1120   * </p>
1121   */
1122  Query<T> order(String orderByClause);
1123
1124  /**
1125   * Return the OrderBy so that you can append an ascending or descending
1126   * property to the order by clause.
1127   * <p>
1128   * This will never return a null. If no order by clause exists then an 'empty'
1129   * OrderBy object is returned.
1130   * </p>
1131   * <p>
1132   * This is EXACTLY the same as {@link #orderBy()}.
1133   * </p>
1134   */
1135  OrderBy<T> order();
1136
1137  /**
1138   * Return the OrderBy so that you can append an ascending or descending
1139   * property to the order by clause.
1140   * <p>
1141   * This will never return a null. If no order by clause exists then an 'empty'
1142   * OrderBy object is returned.
1143   * </p>
1144   * <p>
1145   * This is EXACTLY the same as {@link #order()}.
1146   * </p>
1147   */
1148  OrderBy<T> orderBy();
1149
1150  /**
1151   * Set an OrderBy object to replace any existing OrderBy clause.
1152   * <p>
1153   * This is EXACTLY the same as {@link #setOrderBy(OrderBy)}.
1154   * </p>
1155   */
1156  Query<T> setOrder(OrderBy<T> orderBy);
1157
1158  /**
1159   * Set an OrderBy object to replace any existing OrderBy clause.
1160   * <p>
1161   * This is EXACTLY the same as {@link #setOrder(OrderBy)}.
1162   * </p>
1163   */
1164  Query<T> setOrderBy(OrderBy<T> orderBy);
1165
1166  /**
1167   * Set whether this query uses DISTINCT.
1168   * <p>
1169   * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
1170   * generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
1171   * </p>
1172   * <pre>{@code
1173   *
1174   *   List<Customer> customers =
1175   *       Ebean.find(Customer.class)
1176   *          .setDistinct(true)
1177   *          .select("name")
1178   *          .findList();
1179   *
1180   * }</pre>
1181   */
1182  Query<T> setDistinct(boolean isDistinct);
1183
1184  /**
1185   * Return the first row value.
1186   */
1187  int getFirstRow();
1188
1189  /**
1190   * Set the first row to return for this query.
1191   *
1192   * @param firstRow the first row to include in the query result.
1193   */
1194  Query<T> setFirstRow(int firstRow);
1195
1196  /**
1197   * Return the max rows for this query.
1198   */
1199  int getMaxRows();
1200
1201  /**
1202   * Set the maximum number of rows to return in the query.
1203   * 
1204   * @param maxRows
1205   *          the maximum number of rows to return in the query.
1206   */
1207  Query<T> setMaxRows(int maxRows);
1208
1209  /**
1210   * Set the property to use as keys for a map.
1211   * <p>
1212   * If no property is set then the id property is used.
1213   * </p>
1214   * 
1215   * <pre>{@code
1216   *
1217   * // Assuming sku is unique for products...
1218   *    
1219   * Map<?,Product> productMap =
1220   *     ebeanServer.find(Product.class)
1221   *     // use sku for keys...
1222   *     .setMapKey("sku")
1223   *     .findMap();
1224   *
1225   * }</pre>
1226   * 
1227   * @param mapKey
1228   *          the property to use as keys for a map.
1229   */
1230  Query<T> setMapKey(String mapKey);
1231
1232  /**
1233   * Set this to true to use the bean cache.
1234   * <p>
1235   * If the query result is in cache then by default this same instance is
1236   * returned. In this sense it should be treated as a read only object graph.
1237   * </p>
1238   */
1239  Query<T> setUseCache(boolean useBeanCache);
1240
1241  /**
1242   * Set this to true to use the query cache.
1243   */
1244  Query<T> setUseQueryCache(boolean useQueryCache);
1245
1246  /**
1247   * When set to true when you want the returned beans to be read only.
1248   */
1249  Query<T> setReadOnly(boolean readOnly);
1250
1251  /**
1252   * When set to true all the beans from this query are loaded into the bean
1253   * cache.
1254   */
1255  Query<T> setLoadBeanCache(boolean loadBeanCache);
1256
1257  /**
1258   * Set a timeout on this query.
1259   * <p>
1260   * This will typically result in a call to setQueryTimeout() on a
1261   * preparedStatement. If the timeout occurs an exception will be thrown - this
1262   * will be a SQLException wrapped up in a PersistenceException.
1263   * </p>
1264   * 
1265   * @param secs
1266   *          the query timeout limit in seconds. Zero means there is no limit.
1267   */
1268  Query<T> setTimeout(int secs);
1269
1270  /**
1271   * A hint which for JDBC translates to the Statement.fetchSize().
1272   * <p>
1273   * Gives the JDBC driver a hint as to the number of rows that should be
1274   * fetched from the database when more rows are needed for ResultSet.
1275   * </p>
1276   */
1277  Query<T> setBufferFetchSizeHint(int fetchSize);
1278
1279  /**
1280   * Return the sql that was generated for executing this query.
1281   * <p>
1282   * This is only available after the query has been executed and provided only
1283   * for informational purposes.
1284   * </p>
1285   */
1286  String getGeneratedSql();
1287
1288  /**
1289   * executed the select with "for update" which should lock the record
1290   * "on read"
1291   */
1292  Query<T> setForUpdate(boolean forUpdate);
1293
1294  /**
1295   * Return true if this query has forUpdate set.
1296   */
1297  boolean isForUpdate();
1298  
1299  /**
1300   * Set root table alias.
1301   */
1302  Query<T> alias(String alias);
1303
1304  /**
1305   * Return the type of beans being queried.
1306   */
1307  Class<T> getBeanType();
1308
1309  /**
1310   * Set true if you want to disable lazy loading.
1311   * <p>
1312   *   That is, once the object graph is returned further lazy loading is disabled.
1313   * </p>
1314   */
1315  Query<T> setDisableLazyLoading(boolean disableLazyLoading);
1316}