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 *            .endAnd()
063 *          .and()
064 *            .eq("status", Customer.Status.ACTIVE)
065 *            .gt("id", 0)
066 *            .endAnd()
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 ", "", false),
088
089    /**
090     * OR group.
091     */
092    OR(" or ", "", false),
093
094    /**
095     * NOT group.
096     */
097    NOT(" and ", "not ", false),
098
099    /**
100     * Text search AND group.
101     */
102    MUST("must", "", true),
103
104    /**
105     * Text search NOT group.
106     */
107    MUST_NOT("must_not", "", true),
108
109    /**
110     * Text search OR group.
111     */
112    SHOULD("should", "", true);
113
114    private String prefix;
115    private String literal;
116    private boolean text;
117
118    Type(String literal, String prefix, boolean text) {
119      this.literal = literal;
120      this.prefix = prefix;
121      this.text = text;
122    }
123
124    /**
125     * Return the literal value for this type.
126     */
127    public String literal() {
128      return literal;
129    }
130
131    /**
132     * Return the prefix value for this type.
133     */
134    public String prefix() {
135      return prefix;
136    }
137
138    /**
139     * Return true if this is a text type.
140     */
141    public boolean isText() {
142      return text;
143    }
144
145  }
146
147}