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 > 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}