001package io.ebean;
002
003import io.ebean.search.Match;
004import io.ebean.search.MultiMatch;
005import io.ebean.search.TextCommonTerms;
006import io.ebean.search.TextQueryString;
007import io.ebean.search.TextSimple;
008
009import java.util.Collection;
010import java.util.Map;
011
012/**
013 * Expression factory for creating standard expressions.
014 * <p>
015 * Creates standard common expressions for using in a Query Where or Having
016 * clause.
017 * </p>
018 * <p>
019 * You will often not use this class directly but instead just add expressions
020 * via the methods on ExpressionList such as
021 * {@link ExpressionList#gt(String, Object)}.
022 * </p>
023 * <p>
024 * The ExpressionList is returned from {@link Query#where()}.
025 * </p>
026 * <pre>{@code
027 * // Example: fetch orders where status equals new or orderDate > lastWeek.
028 *
029 * Expression newOrLastWeek =
030 *     Expr.or(Expr.eq("status", Order.Status.NEW),
031 *             Expr.gt("orderDate", lastWeek));
032 *
033 * List<Order> list = DB.find(Order.class)
034 *   .where().add(newOrLastWeek)
035 *   .findList();
036 * ...
037 * }</pre>
038 *
039 * @see Query#where()
040 */
041public interface ExpressionFactory {
042
043  /**
044   * Path exists - for the given path in a JSON document.
045   */
046  Expression jsonExists(String propertyName, String path);
047
048  /**
049   * Path does not exist - for the given path in a JSON document.
050   */
051  Expression jsonNotExists(String propertyName, String path);
052
053  /**
054   * Equal to - for the given path in a JSON document.
055   */
056  Expression jsonEqualTo(String propertyName, String path, Object val);
057
058  /**
059   * Not Equal to - for the given path in a JSON document.
060   */
061  Expression jsonNotEqualTo(String propertyName, String path, Object val);
062
063  /**
064   * Greater than - for the given path in a JSON document.
065   */
066  Expression jsonGreaterThan(String propertyName, String path, Object val);
067
068  /**
069   * Greater than or equal to - for the given path in a JSON document.
070   */
071  Expression jsonGreaterOrEqual(String propertyName, String path, Object val);
072
073  /**
074   * Less than - for the given path in a JSON document.
075   */
076  Expression jsonLessThan(String propertyName, String path, Object val);
077
078  /**
079   * Less than or equal to - for the given path in a JSON document.
080   */
081  Expression jsonLessOrEqualTo(String propertyName, String path, Object val);
082
083  /**
084   * Between - for the given path in a JSON document.
085   */
086  Expression jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
087
088  /**
089   * Array contains all the given values.
090   * <p>
091   * Array support is effectively limited to Postgres at this time.
092   * </p>
093   */
094  Expression arrayContains(String propertyName, Object... values);
095
096  /**
097   * Array does not contain the given values.
098   * <p>
099   * Array support is effectively limited to Postgres at this time.
100   * </p>
101   */
102  Expression arrayNotContains(String propertyName, Object... values);
103
104  /**
105   * Array is empty - for the given array property.
106   * <p>
107   * Array support is effectively limited to Postgres at this time.
108   * </p>
109   */
110  Expression arrayIsEmpty(String propertyName);
111
112  /**
113   * Array is not empty - for the given array property.
114   * <p>
115   * Array support is effectively limited to Postgres at this time.
116   * </p>
117   */
118  Expression arrayIsNotEmpty(String propertyName);
119
120  /**
121   * Equal To - property equal to the given value.
122   */
123  Expression eq(String propertyName, Object value);
124
125  /**
126   * Equal To or Null - property equal to the given value or null.
127   */
128  Expression eqOrNull(String propertyName, Object value);
129
130  /**
131   * Not Equal To - property not equal to the given value.
132   */
133  Expression ne(String propertyName, Object value);
134
135  /**
136   * Case Insensitive Equal To - property equal to the given value (typically
137   * using a lower() function to make it case insensitive).
138   */
139  Expression ieq(String propertyName, String value);
140
141  /**
142   * Case Insensitive Not Equal To - property not equal to the given value (typically
143   * using a lower() function to make it case insensitive).
144   */
145  Expression ine(String propertyName, String value);
146
147  /**
148   * Case Insensitive Equal To that allows for named parameter use.
149   */
150  Expression ieqObject(String propertyName, Object value);
151
152  /**
153   * Case Insensitive Not Equal To that allows for named parameter use.
154   */
155  Expression ineObject(String propertyName, Object value);
156
157  /**
158   * In Range - {@code property >= value1 and property < value2}.
159   * <p>
160   * Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
161   * </p>
162   */
163  Expression inRange(String propertyName, Object value1, Object value2);
164
165  /**
166   * Value in Range between 2 properties.
167   *
168   * <pre>{@code
169   *
170   *    .startDate.inRangeWith(endDate, now)
171   *
172   *    // which equates to
173   *    startDate <= now and (endDate > now or endDate is null)
174   *
175   * }</pre>
176   *
177   * <p>
178   * This is a convenience expression combining a number of simple expressions.
179   * The most common use of this could be called "effective dating" where 2 date or
180   * timestamp columns represent the date range in which
181   */
182  Expression inRangeWith(String lowProperty, String highProperty, Object value);
183
184  /**
185   * Between - property between the two given values.
186   */
187  Expression between(String propertyName, Object value1, Object value2);
188
189  /**
190   * Between - value between two given properties.
191   */
192  Expression betweenProperties(String lowProperty, String highProperty, Object value);
193
194  /**
195   * Greater Than Or Null - property greater than the given value or null.
196   * <p>
197   * A convenient expression combining GT and Is Null.  Most often useful for range
198   * expressions where the top range value is nullable.
199   */
200  Expression gtOrNull(String propertyName, Object value);
201
202  /**
203   * Greater than or Equal to OR Null ({@code >= or null })
204   * <p>
205   * A convenient expression combining GE and Is Null.  Most often useful for range
206   * expressions where the top range value is nullable.
207   */
208  Expression geOrNull(String propertyName, Object value);
209
210  /**
211   * Greater Than - property greater than the given value.
212   */
213  Expression gt(String propertyName, Object value);
214
215  /**
216   * Greater Than or Equal to - property greater than or equal to the given
217   * value.
218   */
219  Expression ge(String propertyName, Object value);
220
221  /**
222   * Less Than or Null - property less than the given value or null.
223   * <p>
224   * A convenient expression combining LT and Is Null.  Most often useful for range
225   * expressions where the bottom range value is nullable.
226   */
227  Expression ltOrNull(String propertyName, Object value);
228
229  /**
230   * Less Than or Equal to OR Null ({@code <= or null })
231   * <p>
232   * A convenient expression combining LE and Is Null.  Most often useful for range
233   * expressions where the bottom range value is nullable.
234   */
235  Expression leOrNull(String propertyName, Object value);
236
237  /**
238   * Less Than - property less than the given value.
239   */
240  Expression lt(String propertyName, Object value);
241
242  /**
243   * Less Than or Equal to - property less than or equal to the given value.
244   */
245  Expression le(String propertyName, Object value);
246
247  /**
248   * Is Null - property is null.
249   */
250  Expression isNull(String propertyName);
251
252  /**
253   * Is Not Null - property is not null.
254   */
255  Expression isNotNull(String propertyName);
256
257  /**
258   * Case insensitive {@link #exampleLike(Object)}
259   */
260  ExampleExpression iexampleLike(Object example);
261
262  /**
263   * Create the query by Example expression which is case sensitive and using
264   * LikeType.RAW (you need to add you own wildcards % and _).
265   */
266  ExampleExpression exampleLike(Object example);
267
268  /**
269   * Create the query by Example expression specifying more options.
270   */
271  ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType);
272
273  /**
274   * Like with support for named parameters.
275   */
276  Expression like(String propertyName, Object value, boolean caseInsensitive, LikeType likeType);
277
278  /**
279   * Like - property like value where the value contains the SQL wild card
280   * characters % (percentage) and _ (underscore).
281   */
282  Expression like(String propertyName, String value);
283
284  /**
285   * Case insensitive Like - property like value where the value contains the
286   * SQL wild card characters % (percentage) and _ (underscore). Typically uses
287   * a lower() function to make the expression case insensitive.
288   */
289  Expression ilike(String propertyName, String value);
290
291  /**
292   * Starts With - property like value%.
293   */
294  Expression startsWith(String propertyName, String value);
295
296  /**
297   * Case insensitive Starts With - property like value%. Typically uses a
298   * lower() function to make the expression case insensitive.
299   */
300  Expression istartsWith(String propertyName, String value);
301
302  /**
303   * Ends With - property like %value.
304   */
305  Expression endsWith(String propertyName, String value);
306
307  /**
308   * Case insensitive Ends With - property like %value. Typically uses a lower()
309   * function to make the expression case insensitive.
310   */
311  Expression iendsWith(String propertyName, String value);
312
313  /**
314   * Contains - property like %value%.
315   */
316  Expression contains(String propertyName, String value);
317
318  /**
319   * Case insensitive Contains - property like %value%. Typically uses a lower()
320   * function to make the expression case insensitive.
321   */
322  Expression icontains(String propertyName, String value);
323
324  /**
325   * In expression using pairs of value objects.
326   */
327  Expression inPairs(Pairs pairs);
328
329  /**
330   * In - property has a value in the array of values.
331   */
332  Expression in(String propertyName, Object[] values);
333
334  /**
335   * In - using a subQuery.
336   */
337  Expression in(String propertyName, Query<?> subQuery);
338
339  /**
340   * In - property has a value in the collection of values.
341   */
342  Expression in(String propertyName, Collection<?> values);
343
344  /**
345   * In where null or empty values means that no predicate is added to the query.
346   * <p>
347   * That is, only add the IN predicate if the values are not null or empty.
348   * <p>
349   * Without this we typically need to code an <code>if</code> block to only add
350   * the IN predicate if the collection is not empty like:
351   * </p>
352   *
353   * <h3>Without inOrEmpty()</h3>
354   * <pre>{@code
355   *
356   *   query.where() // add some predicates
357   *     .eq("status", Status.NEW);
358   *
359   *   if (ids != null && !ids.isEmpty()) {
360   *     query.where().in("customer.id", ids);
361   *   }
362   *
363   *   query.findList();
364   *
365   * }</pre>
366   *
367   * <h3>Using inOrEmpty()</h3>
368   * <pre>{@code
369   *
370   *   query.where()
371   *     .eq("status", Status.NEW)
372   *     .inOrEmpty("customer.id", ids)
373   *     .findList();
374   *
375   * }</pre>
376   */
377  Expression inOrEmpty(String propertyName, Collection<?> values);
378
379  /**
380   * Not In - property has a value in the array of values.
381   */
382  Expression notIn(String propertyName, Object[] values);
383
384  /**
385   * Not In - property has a value in the collection of values.
386   */
387  Expression notIn(String propertyName, Collection<?> values);
388
389  /**
390   * Not In - using a subQuery.
391   */
392  Expression notIn(String propertyName, Query<?> subQuery);
393
394  /**
395   * Exists expression
396   */
397  Expression exists(Query<?> subQuery);
398
399  /**
400   * Not exists expression
401   */
402  Expression notExists(Query<?> subQuery);
403
404  /**
405   * Is empty expression for collection properties.
406   */
407  Expression isEmpty(String propertyName);
408
409  /**
410   * Is not empty expression for collection properties.
411   */
412  Expression isNotEmpty(String propertyName);
413
414  /**
415   * Id Equal to - ID property is equal to the value.
416   */
417  Expression idEq(Object value);
418
419  /**
420   * Id IN a list of Id values.
421   */
422  Expression idIn(Object... idValues);
423
424  /**
425   * Id IN a collection of Id values.
426   */
427  Expression idIn(Collection<?> idCollection);
428
429  /**
430   * All Equal - Map containing property names and their values.
431   * <p>
432   * Expression where all the property names in the map are equal to the
433   * corresponding value.
434   * </p>
435   *
436   * @param propertyMap a map keyed by property names.
437   */
438  Expression allEq(Map<String, Object> propertyMap);
439
440  /**
441   * Add expression for ANY of the given bit flags to be set.
442   *
443   * @param propertyName The property that holds the flags value
444   * @param flags        The flags we are looking for
445   */
446  Expression bitwiseAny(String propertyName, long flags);
447
448  /**
449   * Add expression for ALL of the given bit flags to be set.
450   *
451   * @param propertyName The property that holds the flags value
452   * @param flags        The flags we are looking for
453   */
454  Expression bitwiseAll(String propertyName, long flags);
455
456  /**
457   * Add bitwise AND expression of the given bit flags to compare with the match/mask.
458   *
459   * @param propertyName The property that holds the flags value
460   * @param flags        The flags we are looking for
461   */
462  Expression bitwiseAnd(String propertyName, long flags, long match);
463
464  /**
465   * Add raw expression with a single parameter.
466   * <p>
467   * The raw expression should contain a single ? at the location of the
468   * parameter.
469   * </p>
470   */
471  Expression raw(String raw, Object value);
472
473  /**
474   * Add raw expression with an array of parameters.
475   * <p>
476   * The raw expression should contain the same number of ? as there are
477   * parameters.
478   * </p>
479   */
480  Expression raw(String raw, Object[] values);
481
482  /**
483   * Add raw expression with no parameters.
484   */
485  Expression raw(String raw);
486
487  /**
488   * Create a Text Match expression (currently doc store/Elastic only).
489   */
490  Expression textMatch(String propertyName, String search, Match options);
491
492  /**
493   * Create a Text Multi match expression (currently doc store/Elastic only).
494   */
495  Expression textMultiMatch(String query, MultiMatch options);
496
497  /**
498   * Create a text simple query expression (currently doc store/Elastic only).
499   */
500  Expression textSimple(String search, TextSimple options);
501
502  /**
503   * Create a text query string expression (currently doc store/Elastic only).
504   */
505  Expression textQueryString(String search, TextQueryString options);
506
507  /**
508   * Create a text common terms expression (currently doc store/Elastic only).
509   */
510  Expression textCommonTerms(String search, TextCommonTerms options);
511
512  /**
513   * And - join two expressions with a logical and.
514   */
515  Expression and(Expression expOne, Expression expTwo);
516
517  /**
518   * Or - join two expressions with a logical or.
519   */
520  Expression or(Expression expOne, Expression expTwo);
521
522  /**
523   * Negate the expression (prefix it with NOT).
524   */
525  Expression not(Expression exp);
526
527  /**
528   * Return a list of expressions that will be joined by AND's.
529   */
530  <T> Junction<T> conjunction(Query<T> query);
531
532  /**
533   * Return a list of expressions that will be joined by OR's.
534   */
535  <T> Junction<T> disjunction(Query<T> query);
536
537  /**
538   * Return a list of expressions that will be joined by AND's.
539   */
540  <T> Junction<T> conjunction(Query<T> query, ExpressionList<T> parent);
541
542  /**
543   * Return a list of expressions that will be joined by OR's.
544   */
545  <T> Junction<T> disjunction(Query<T> query, ExpressionList<T> parent);
546
547  /**
548   * Return a Text query junction for MUST, SHOULD or MUST NOT.
549   * <p>
550   * This is doc store Elastic only.
551   * </p>
552   */
553  <T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
554
555  /**
556   * Add the expressions to the given expression list.
557   *
558   * @param where       The expression list to add the expressions to
559   * @param expressions The expressions that are parsed
560   * @param params      Bind parameters to match ? or ?1 bind positions.
561   */
562  <T> void where(ExpressionList<T> where, String expressions, Object[] params);
563}