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