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