001package com.avaje.ebean;
002
003/**
004 * Represents a Conjunction or a Disjunction.
005 * <p>
006 * Basically with a Conjunction you join together many expressions with AND, and
007 * with a Disjunction you join together many expressions with OR.
008 * </p>
009 * <p>
010 * Note: where() always takes you to the top level WHERE expression list.
011 * </p>
012 *
013 * <pre>{@code
014 * Query q =
015 *     Ebean.find(Person.class)
016 *       .where()
017 *         .or()
018 *           .like("name", "Rob%")
019 *           .eq("status", Status.NEW)
020 *
021 *       // where() returns us to the top level expression list
022 *       .where().gt("id", 10);
023 *
024 * // read as...
025 * // where ( ((name like Rob%) or (status = NEW)) AND (id &gt; 10) )
026 * }</pre>
027 *
028 * <p>
029 * Note: endJunction() takes you to the parent expression list
030 * </p>
031 *
032 * <pre>{@code
033 * Query q =
034 *     Ebean.find(Person.class)
035 *       .where()
036 *         .or()
037 *           .like("name", "Rob%")
038 *           .eq("status", Status.NEW)
039 *           .endJunction()
040 *
041 *           // endJunction().. takes us to the 'parent' expression list
042 *           // which in this case is the top level (same as where())
043 *
044 *         .gt("id", 10);
045 *
046 * // read as...
047 * // where ( ((name like Rob%) or (status = NEW)) AND (id > 10) )
048 * }</pre>
049 *
050 * <p>
051 * Example of a nested disjunction.
052 * </p>
053 *
054 * <pre>{@code
055 * Query<Customer> q =
056 *  Ebean.find(Customer.class)
057 *      .where()
058 *        .or()
059 *          .and()
060 *            .startsWith("name", "r")
061 *            .eq("anniversary", onAfter)
062 *            .endJunction()
063 *          .and()
064 *            .eq("status", Customer.Status.ACTIVE)
065 *            .gt("id", 0)
066 *            .endJunction()
067 *      .order().asc("name");
068 *
069 * q.findList();
070 * String s = q.getGeneratedSql();
071 *
072 *  // this produces an expression like:
073 *  ( name like ? and c.anniversary = ? ) or (c.status = ?  and c.id > ? )
074 *
075 * }</pre>
076 */
077public interface Junction<T> extends Expression, ExpressionList<T> {
078
079  /**
080   * The type of Junction used in full text expressions.
081   */
082  enum Type {
083
084    /**
085     * AND group.
086     */
087    AND(" and ", ""),
088
089    /**
090     * OR group.
091     */
092    OR(" or ", ""),
093
094    /**
095     * NOT group.
096     */
097    NOT(" and ", "not "),
098
099    /**
100     * Text search AND group.
101     */
102    MUST("must", ""),
103
104    /**
105     * Text search NOT group.
106     */
107    MUST_NOT("must_not", ""),
108
109    /**
110     * Text search OR group.
111     */
112    SHOULD("should", "");
113
114    String prefix;
115    String literal;
116
117    Type(String literal, String prefix) {
118      this.literal = literal;
119      this.prefix = prefix;
120    }
121
122    /**
123     * Return the literal value for this type.
124     */
125    public String literal() {
126      return literal;
127    }
128
129    /**
130     * Return the prefix value for this type.
131     */
132    public String prefix() {
133      return prefix;
134    }
135  }
136
137}