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.Collection;
009import java.util.List;
010import java.util.Map;
011import java.util.Set;
012
013/**
014 * List of Expressions that make up a where or having clause.
015 * <p>
016 * An ExpressionList is returned from {@link Query#where()}.
017 * </p>
018 * <p>
019 * The ExpressionList has a list of convenience methods that create the standard
020 * expressions and add them to this list.
021 * </p>
022 * <p>
023 * The ExpressionList also duplicates methods that are found on the Query such
024 * as findList() and orderBy(). The purpose of these methods is provide a fluid
025 * API. The upside of this approach is that you can build and execute a query
026 * via chained methods. The down side is that this ExpressionList object has
027 * more methods than you would initially expect (the ones duplicated from
028 * Query).
029 * </p>
030 * 
031 * @see Query#where()
032 */
033public interface ExpressionList<T> extends Serializable {
034
035  /**
036   * Return the query that owns this expression list.
037   * <p>
038   * This is a convenience method solely to support a fluid API where the
039   * methods are chained together. Adding expressions returns this expression
040   * list and this method can be used after that to return back the original
041   * query so that further things can be added to it.
042   * </p>
043   */
044  Query<T> query();
045
046  /**
047   * Set the order by clause replacing the existing order by clause if there is
048   * one.
049   * <p>
050   * This follows SQL syntax using commas between each property with the
051   * optional asc and desc keywords representing ascending and descending order
052   * respectively.
053   * </p>
054   * <p>
055   * This is EXACTLY the same as {@link #orderBy(String)}.
056   * </p>
057   */
058  Query<T> order(String orderByClause);
059
060  /**
061   * Return the OrderBy so that you can append an ascending or descending
062   * property to the order by clause.
063   * <p>
064   * This will never return a null. If no order by clause exists then an 'empty'
065   * OrderBy object is returned.
066   * </p>
067   */
068  OrderBy<T> order();
069
070  /**
071   * Return the OrderBy so that you can append an ascending or descending
072   * property to the order by clause.
073   * <p>
074   * This will never return a null. If no order by clause exists then an 'empty'
075   * OrderBy object is returned.
076   * </p>
077   */
078  OrderBy<T> orderBy();
079
080  /**
081   * Add an orderBy clause to the query.
082   * 
083   * @see Query#orderBy(String)
084   */
085  Query<T> orderBy(String orderBy);
086
087  /**
088   * Add an orderBy clause to the query.
089   * 
090   * @see Query#orderBy(String)
091   */
092  Query<T> setOrderBy(String orderBy);
093
094  /**
095   * Apply the path properties to the query replacing the select and fetch clauses.
096   */
097  Query<T> apply(PathProperties pathProperties);
098
099  /**
100   * Perform an 'As of' query using history tables to return the object graph
101   * as of a time in the past.
102   * <p>
103   *   To perform this query the DB must have underlying history tables.
104   * </p>
105   *
106   * @param asOf the date time in the past at which you want to view the data
107   */
108  Query<T> asOf(Timestamp asOf);
109
110  /**
111   * Execute as a delete query deleting the 'root level' beans that match the predicates
112   * in the query.
113   * <p>
114   * Note that if the query includes joins then the generated delete statement may not be
115   * optimal depending on the database platform.
116   * </p>
117   *
118   * @return the number of beans/rows that were deleted.
119   */
120  int delete();
121
122  /**
123   * Execute the query iterating over the results.
124   * 
125   * @see Query#findIterate()
126   */
127  QueryIterator<T> findIterate();
128
129  /**
130   * Execute the query process the beans one at a time.
131   *
132   * @see Query#findEach(QueryEachConsumer)
133   */
134  void findEach(QueryEachConsumer<T> consumer);
135
136  /**
137   * Execute the query processing the beans one at a time with the ability to
138   * stop processing before reading all the beans.
139   *
140   * @see Query#findEachWhile(QueryEachWhileConsumer)
141   */
142  void findEachWhile(QueryEachWhileConsumer<T> consumer);
143
144  /**
145   * Execute the query returning a list.
146   * 
147   * @see Query#findList()
148   */
149  List<T> findList();
150
151  /**
152   * Execute the query returning the list of Id's.
153   * 
154   * @see Query#findIds()
155   */
156  List<Object> findIds();
157
158  /**
159   * Return the count of entities this query should return.
160   * <p>
161   * This is the number of 'top level' or 'root level' entities.
162   * </p>
163   */
164  int findRowCount();
165
166  /**
167   * Execute the query returning a set.
168   * 
169   * @see Query#findSet()
170   */
171  Set<T> findSet();
172
173  /**
174   * Execute the query returning a map.
175   * 
176   * @see Query#findMap()
177   */
178  Map<?, T> findMap();
179
180  /**
181   * Return a typed map specifying the key property and type.
182   */
183  <K> Map<K, T> findMap(String keyProperty, Class<K> keyType);
184
185  /**
186   * Execute the query returning a single bean.
187   * 
188   * @see Query#findUnique()
189   */
190  @Nullable
191  T findUnique();
192
193  /**
194   * Execute find row count query in a background thread.
195   * <p>
196   * This returns a Future object which can be used to cancel, check the
197   * execution status (isDone etc) and get the value (with or without a
198   * timeout).
199   * </p>
200   * 
201   * @return a Future object for the row count query
202   */
203  FutureRowCount<T> findFutureRowCount();
204
205  /**
206   * Execute find Id's query in a background thread.
207   * <p>
208   * This returns a Future object which can be used to cancel, check the
209   * execution status (isDone etc) and get the value (with or without a
210   * timeout).
211   * </p>
212   * 
213   * @return a Future object for the list of Id's
214   */
215  FutureIds<T> findFutureIds();
216
217  /**
218   * Execute find list query in a background thread.
219   * <p>
220   * This returns a Future object which can be used to cancel, check the
221   * execution status (isDone etc) and get the value (with or without a
222   * timeout).
223   * </p>
224   * 
225   * @return a Future object for the list result of the query
226   */
227  FutureList<T> findFutureList();
228
229  /**
230   * Return a PagedList for this query.
231   * <p>
232   * The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and
233   * {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to
234   * {@link Query#findFutureRowCount()} to determine total row count, total page count etc.
235   * </p>
236   * <p>
237   * Internally this works using {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} on
238   * the query. This translates into SQL that uses limit offset, rownum or row_number
239   * function to limit the result set.
240   * </p>
241   * 
242   * @param pageIndex
243   *          The zero based index of the page.
244   * @param pageSize
245   *          The number of beans to return per page.
246   * @return The PagedList
247   */
248  PagedList<T> findPagedList(int pageIndex, int pageSize);
249
250  /**
251   * Return versions of a @History entity bean.
252   * <p>
253   *   Generally this query is expected to be a find by id or unique predicates query.
254   *   It will execute the query against the history returning the versions of the bean.
255   * </p>
256   */
257  List<Version<T>> findVersions();
258
259  /**
260   * Return versions of a @History entity bean between the 2 timestamps.
261   * <p>
262   *   Generally this query is expected to be a find by id or unique predicates query.
263   *   It will execute the query against the history returning the versions of the bean.
264   * </p>
265   */
266  List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
267
268  /**
269   * Add some filter predicate expressions to the many property.
270   */
271  ExpressionList<T> filterMany(String prop);
272
273  /**
274   * Specify specific properties to fetch on the main/root bean (aka partial
275   * object).
276   * 
277   * @see Query#select(String)
278   */
279  Query<T> select(String properties);
280
281  /**
282   * Set whether this query uses DISTINCT.
283   * <p>
284   * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
285   * generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
286   * </p>
287   * <pre>{@code
288   *
289   *   List<Customer> customers =
290   *       Ebean.find(Customer.class)
291   *          .setDistinct(true)
292   *          .select("name")     // only select the customer name
293   *          .findList();
294   *
295   * }</pre>
296   */
297  Query<T> setDistinct(boolean distinct);
298
299  /**
300   * Set the first row to fetch.
301   * 
302   * @see Query#setFirstRow(int)
303   */
304  Query<T> setFirstRow(int firstRow);
305
306  /**
307   * Set the maximum number of rows to fetch.
308   * 
309   * @see Query#setMaxRows(int)
310   */
311  Query<T> setMaxRows(int maxRows);
312
313  /**
314   * Set the name of the property which values become the key of a map.
315   * 
316   * @see Query#setMapKey(String)
317   */
318  Query<T> setMapKey(String mapKey);
319
320  /**
321   * Set to true to use the query for executing this query.
322   * 
323   * @see Query#setUseCache(boolean)
324   */
325  Query<T> setUseCache(boolean useCache);
326
327  /**
328   * Set to true to use the query for executing this query.
329   *
330   * @see Query#setUseQueryCache(boolean)
331   */
332  Query<T> setUseQueryCache(boolean useCache);
333
334  /**
335   * Add expressions to the having clause.
336   * <p>
337   * The having clause is only used for queries based on raw sql (via SqlSelect
338   * annotation etc).
339   * </p>
340   */
341  ExpressionList<T> having();
342
343  /**
344   * Add another expression to the where clause.
345   */
346  ExpressionList<T> where();
347
348  /**
349   * Path exists - for the given path in a JSON document.
350   *
351   * <pre>{@code
352   *
353   *   where().jsonExists("content", "path.other")
354   *
355   * }</pre>
356   *
357   * @param propertyName the property that holds a JSON document
358   * @param path the nested path in the JSON document in dot notation
359   */
360  ExpressionList<T> jsonExists(String propertyName, String path);
361
362  /**
363   * Path does not exist - for the given path in a JSON document.
364   *
365   * <pre>{@code
366   *
367   *   where().jsonNotExists("content", "path.other")
368   *
369   * }</pre>
370   *
371   * @param propertyName the property that holds a JSON document
372   * @param path the nested path in the JSON document in dot notation
373   */
374  ExpressionList<T> jsonNotExists(String propertyName, String path);
375
376  /**
377   * Equal to expression for the value at the given path in the JSON document.
378   *
379   * <pre>{@code
380   *
381   *   where().jsonEqualTo("content", "path.other", 34)
382   *
383   * }</pre>
384   *
385   * @param propertyName the property that holds a JSON document
386   * @param path the nested path in the JSON document in dot notation
387   * @param value the value used to test against the document path's value
388   */
389  ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value);
390
391  /**
392   * Not Equal to - for the given path in a JSON document.
393   *
394   * <pre>{@code
395   *
396   *   where().jsonNotEqualTo("content", "path.other", 34)
397   *
398   * }</pre>
399   *
400   * @param propertyName the property that holds a JSON document
401   * @param path the nested path in the JSON document in dot notation
402   * @param value the value used to test against the document path's value
403   */
404  ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object value);
405
406  /**
407   * Greater than - for the given path in a JSON document.
408   *
409   * <pre>{@code
410   *
411   *   where().jsonGreaterThan("content", "path.other", 34)
412   *
413   * }</pre>
414   */
415  ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object value);
416
417  /**
418   * Greater than or equal to - for the given path in a JSON document.
419   *
420   * <pre>{@code
421   *
422   *   where().jsonGreaterOrEqual("content", "path.other", 34)
423   *
424   * }</pre>
425   */
426  ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object value);
427
428  /**
429   * Less than - for the given path in a JSON document.
430   *
431   * <pre>{@code
432   *
433   *   where().jsonLessThan("content", "path.other", 34)
434   *
435   * }</pre>
436   */
437  ExpressionList<T> jsonLessThan(String propertyName, String path, Object value);
438
439  /**
440   * Less than or equal to - for the given path in a JSON document.
441   *
442   * <pre>{@code
443   *
444   *   where().jsonLessOrEqualTo("content", "path.other", 34)
445   *
446   * }</pre>
447   */
448  ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object value);
449
450  /**
451   * Between - for the given path in a JSON document.
452   *
453   * <pre>{@code
454   *
455   *   where().jsonBetween("content", "orderDate", lowerDateTime, upperDateTime)
456   *
457   * }</pre>
458   */
459  ExpressionList<T> jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
460
461  /**
462   * Add an Expression to the list.
463   * <p>
464   * This returns the list so that add() can be chained.
465   * </p>
466   *
467   * <pre>{@code
468   *
469   * Query<Customer> query = Ebean.find(Customer.class);
470   * query.where()
471   *     .like("name","Rob%")
472   *     .eq("status", Customer.ACTIVE);
473   *
474   * List<Customer> list = query.findList();
475   * ...
476   *
477   * }</pre>
478   */
479  ExpressionList<T> add(Expression expr);
480
481  /**
482   * Add a list of Expressions to this ExpressionList.s
483   */
484  ExpressionList<T> addAll(ExpressionList<T> exprList);
485
486  /**
487   * Equal To - property is equal to a given value.
488   */
489  ExpressionList<T> eq(String propertyName, Object value);
490
491  /**
492   * Not Equal To - property not equal to the given value.
493   */
494  ExpressionList<T> ne(String propertyName, Object value);
495
496  /**
497   * Case Insensitive Equal To - property equal to the given value (typically
498   * using a lower() function to make it case insensitive).
499   */
500  ExpressionList<T> ieq(String propertyName, String value);
501
502  /**
503   * Between - property between the two given values.
504   */
505  ExpressionList<T> between(String propertyName, Object value1, Object value2);
506
507  /**
508   * Between - value between the two properties.
509   */
510  ExpressionList<T> betweenProperties(String lowProperty, String highProperty, Object value);
511
512  /**
513   * Greater Than - property greater than the given value.
514   */
515  ExpressionList<T> gt(String propertyName, Object value);
516
517  /**
518   * Greater Than or Equal to - property greater than or equal to the given
519   * value.
520   */
521  ExpressionList<T> ge(String propertyName, Object value);
522
523  /**
524   * Less Than - property less than the given value.
525   */
526  ExpressionList<T> lt(String propertyName, Object value);
527
528  /**
529   * Less Than or Equal to - property less than or equal to the given value.
530   */
531  ExpressionList<T> le(String propertyName, Object value);
532
533  /**
534   * Is Null - property is null.
535   */
536  ExpressionList<T> isNull(String propertyName);
537
538  /**
539   * Is Not Null - property is not null.
540   */
541  ExpressionList<T> isNotNull(String propertyName);
542
543  /**
544   * A "Query By Example" type of expression.
545   * <p>
546   * Pass in an example entity and for each non-null scalar properties an
547   * expression is added.
548   * </p>
549   * <p>
550   * By Default this case sensitive, will ignore numeric zero values and will
551   * use a Like for string values (you must put in your own wildcards).
552   * </p>
553   * <p>
554   * To get control over the options you can create an ExampleExpression and set
555   * those options such as case insensitive etc.
556   * </p>
557   * 
558   * <pre>{@code
559   *
560   * // create an example bean and set the properties
561   * // with the query parameters you want
562   * Customer example = new Customer();
563   * example.setName("Rob%");
564   * example.setNotes("%something%");
565   * 
566   * List&lt;Customer&gt; list = Ebean.find(Customer.class).where()
567   *     // pass the bean into the where() clause
568   *     .exampleLike(example)
569   *     // you can add other expressions to the same query
570   *     .gt("id", 2).findList();
571   * 
572   * }</pre>
573   * 
574   * Similarly you can create an ExampleExpression
575   * 
576   * <pre>{@code
577   *
578   * Customer example = new Customer();
579   * example.setName("Rob%");
580   * example.setNotes("%something%");
581   * 
582   * // create a ExampleExpression with more control
583   * ExampleExpression qbe = new ExampleExpression(example, true, LikeType.EQUAL_TO).includeZeros();
584   * 
585   * List<Customer> list = Ebean.find(Customer.class).where().add(qbe).findList();
586   *
587   * }</pre>
588   */
589  ExpressionList<T> exampleLike(Object example);
590
591  /**
592   * Case insensitive version of {@link #exampleLike(Object)}
593   */
594  ExpressionList<T> iexampleLike(Object example);
595
596  /**
597   * Like - property like value where the value contains the SQL wild card
598   * characters % (percentage) and _ (underscore).
599   */
600  ExpressionList<T> like(String propertyName, String value);
601
602  /**
603   * Case insensitive Like - property like value where the value contains the
604   * SQL wild card characters % (percentage) and _ (underscore). Typically uses
605   * a lower() function to make the expression case insensitive.
606   */
607  ExpressionList<T> ilike(String propertyName, String value);
608
609  /**
610   * Starts With - property like value%.
611   */
612  ExpressionList<T> startsWith(String propertyName, String value);
613
614  /**
615   * Case insensitive Starts With - property like value%. Typically uses a
616   * lower() function to make the expression case insensitive.
617   */
618  ExpressionList<T> istartsWith(String propertyName, String value);
619
620  /**
621   * Ends With - property like %value.
622   */
623  ExpressionList<T> endsWith(String propertyName, String value);
624
625  /**
626   * Case insensitive Ends With - property like %value. Typically uses a lower()
627   * function to make the expression case insensitive.
628   */
629  ExpressionList<T> iendsWith(String propertyName, String value);
630
631  /**
632   * Contains - property like %value%.
633   */
634  ExpressionList<T> contains(String propertyName, String value);
635
636  /**
637   * Case insensitive Contains - property like %value%. Typically uses a lower()
638   * function to make the expression case insensitive.
639   */
640  ExpressionList<T> icontains(String propertyName, String value);
641
642  /**
643   * In - using a subQuery.
644   */
645  ExpressionList<T> in(String propertyName, Query<?> subQuery);
646
647  /**
648   * In - property has a value in the array of values.
649   */
650  ExpressionList<T> in(String propertyName, Object... values);
651
652  /**
653   * In - property has a value in the collection of values.
654   */
655  ExpressionList<T> in(String propertyName, Collection<?> values);
656
657  /**
658   * Not In - property has a value in the array of values.
659   */
660  ExpressionList<T> notIn(String propertyName, Object... values);
661
662  /**
663   * Not In - property has a value in the collection of values.
664   */
665  ExpressionList<T> notIn(String propertyName, Collection<?> values);
666
667  /**
668   * Not In - using a subQuery.
669   */
670  ExpressionList<T> notIn(String propertyName, Query<?> subQuery);
671
672  /**
673   * Exists expression
674   */
675  ExpressionList<T> exists(Query<?> subQuery);
676  
677  /**
678   * Not exists expression
679   */
680  ExpressionList<T> notExists(Query<?> subQuery);
681
682  /**
683   * Id IN a list of id values.
684   */
685  ExpressionList<T> idIn(List<?> idValues);
686
687  /**
688   * Id Equal to - ID property is equal to the value.
689   */
690  ExpressionList<T> idEq(Object value);
691
692  /**
693   * All Equal - Map containing property names and their values.
694   * <p>
695   * Expression where all the property names in the map are equal to the
696   * corresponding value.
697   * </p>
698   * 
699   * @param propertyMap
700   *          a map keyed by property names.
701   */
702  ExpressionList<T> allEq(Map<String, Object> propertyMap);
703
704  /**
705   * Add raw expression with a single parameter.
706   * <p>
707   * The raw expression should contain a single ? at the location of the
708   * parameter.
709   * </p>
710   * <p>
711   * When properties in the clause are fully qualified as table-column names
712   * then they are not translated. logical property name names (not fully
713   * qualified) will still be translated to their physical name.
714   * </p>
715   *
716   * <h4>Example:</h4>
717   * <pre>{@code
718   *
719   *   // use a database function
720   *   raw("add_days(orderDate, 10) < ?", someDate)
721   *
722   * }</pre>
723   */
724  ExpressionList<T> raw(String raw, Object value);
725
726  /**
727   * Add raw expression with an array of parameters.
728   * <p>
729   * The raw expression should contain the same number of ? as there are
730   * parameters.
731   * </p>
732   * <p>
733   * When properties in the clause are fully qualified as table-column names
734   * then they are not translated. logical property name names (not fully
735   * qualified) will still be translated to their physical name.
736   * </p>
737   */
738  ExpressionList<T> raw(String raw, Object[] values);
739
740  /**
741   * Add raw expression with no parameters.
742   * <p>
743   * When properties in the clause are fully qualified as table-column names
744   * then they are not translated. logical property name names (not fully
745   * qualified) will still be translated to their physical name.
746   * </p>
747   *
748   * <pre>{@code
749   *
750   *   raw("orderQty < shipQty")
751   *
752   * }</pre>
753   */
754  ExpressionList<T> raw(String raw);
755
756  /**
757   * And - join two expressions with a logical and.
758   */
759  ExpressionList<T> and(Expression expOne, Expression expTwo);
760
761  /**
762   * Or - join two expressions with a logical or.
763   */
764  ExpressionList<T> or(Expression expOne, Expression expTwo);
765
766  /**
767   * Negate the expression (prefix it with NOT).
768   */
769  ExpressionList<T> not(Expression exp);
770
771  /**
772   * Return a list of expressions that will be joined by AND's.
773   */
774  Junction<T> conjunction();
775
776  /**
777   * Return a list of expressions that will be joined by OR's.
778   */
779  Junction<T> disjunction();
780
781  /**
782   * End a Conjunction or Disjunction returning the parent expression list.
783   * <p>
784   * Alternatively you can always use where() to return the top level expression
785   * list.
786   * </p>
787   */
788  ExpressionList<T> endJunction();
789
790}