1<?php 2 3namespace Doctrine\DBAL\Query\Expression; 4 5use Doctrine\DBAL\Connection; 6 7use function func_get_arg; 8use function func_get_args; 9use function func_num_args; 10use function implode; 11use function sprintf; 12 13/** 14 * ExpressionBuilder class is responsible to dynamically create SQL query parts. 15 */ 16class ExpressionBuilder 17{ 18 public const EQ = '='; 19 public const NEQ = '<>'; 20 public const LT = '<'; 21 public const LTE = '<='; 22 public const GT = '>'; 23 public const GTE = '>='; 24 25 /** 26 * The DBAL Connection. 27 * 28 * @var Connection 29 */ 30 private $connection; 31 32 /** 33 * Initializes a new <tt>ExpressionBuilder</tt>. 34 * 35 * @param Connection $connection The DBAL Connection. 36 */ 37 public function __construct(Connection $connection) 38 { 39 $this->connection = $connection; 40 } 41 42 /** 43 * Creates a conjunction of the given boolean expressions. 44 * 45 * Example: 46 * 47 * [php] 48 * // (u.type = ?) AND (u.role = ?) 49 * $expr->andX('u.type = ?', 'u.role = ?')); 50 * 51 * @param mixed $x Optional clause. Defaults = null, but requires 52 * at least one defined when converting to string. 53 * 54 * @return CompositeExpression 55 */ 56 public function andX($x = null) 57 { 58 return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); 59 } 60 61 /** 62 * Creates a disjunction of the given boolean expressions. 63 * 64 * Example: 65 * 66 * [php] 67 * // (u.type = ?) OR (u.role = ?) 68 * $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?')); 69 * 70 * @param mixed $x Optional clause. Defaults = null, but requires 71 * at least one defined when converting to string. 72 * 73 * @return CompositeExpression 74 */ 75 public function orX($x = null) 76 { 77 return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args()); 78 } 79 80 /** 81 * Creates a comparison expression. 82 * 83 * @param mixed $x The left expression. 84 * @param string $operator One of the ExpressionBuilder::* constants. 85 * @param mixed $y The right expression. 86 * 87 * @return string 88 */ 89 public function comparison($x, $operator, $y) 90 { 91 return $x . ' ' . $operator . ' ' . $y; 92 } 93 94 /** 95 * Creates an equality comparison expression with the given arguments. 96 * 97 * First argument is considered the left expression and the second is the right expression. 98 * When converted to string, it will generated a <left expr> = <right expr>. Example: 99 * 100 * [php] 101 * // u.id = ? 102 * $expr->eq('u.id', '?'); 103 * 104 * @param mixed $x The left expression. 105 * @param mixed $y The right expression. 106 * 107 * @return string 108 */ 109 public function eq($x, $y) 110 { 111 return $this->comparison($x, self::EQ, $y); 112 } 113 114 /** 115 * Creates a non equality comparison expression with the given arguments. 116 * First argument is considered the left expression and the second is the right expression. 117 * When converted to string, it will generated a <left expr> <> <right expr>. Example: 118 * 119 * [php] 120 * // u.id <> 1 121 * $q->where($q->expr()->neq('u.id', '1')); 122 * 123 * @param mixed $x The left expression. 124 * @param mixed $y The right expression. 125 * 126 * @return string 127 */ 128 public function neq($x, $y) 129 { 130 return $this->comparison($x, self::NEQ, $y); 131 } 132 133 /** 134 * Creates a lower-than comparison expression with the given arguments. 135 * First argument is considered the left expression and the second is the right expression. 136 * When converted to string, it will generated a <left expr> < <right expr>. Example: 137 * 138 * [php] 139 * // u.id < ? 140 * $q->where($q->expr()->lt('u.id', '?')); 141 * 142 * @param mixed $x The left expression. 143 * @param mixed $y The right expression. 144 * 145 * @return string 146 */ 147 public function lt($x, $y) 148 { 149 return $this->comparison($x, self::LT, $y); 150 } 151 152 /** 153 * Creates a lower-than-equal comparison expression with the given arguments. 154 * First argument is considered the left expression and the second is the right expression. 155 * When converted to string, it will generated a <left expr> <= <right expr>. Example: 156 * 157 * [php] 158 * // u.id <= ? 159 * $q->where($q->expr()->lte('u.id', '?')); 160 * 161 * @param mixed $x The left expression. 162 * @param mixed $y The right expression. 163 * 164 * @return string 165 */ 166 public function lte($x, $y) 167 { 168 return $this->comparison($x, self::LTE, $y); 169 } 170 171 /** 172 * Creates a greater-than comparison expression with the given arguments. 173 * First argument is considered the left expression and the second is the right expression. 174 * When converted to string, it will generated a <left expr> > <right expr>. Example: 175 * 176 * [php] 177 * // u.id > ? 178 * $q->where($q->expr()->gt('u.id', '?')); 179 * 180 * @param mixed $x The left expression. 181 * @param mixed $y The right expression. 182 * 183 * @return string 184 */ 185 public function gt($x, $y) 186 { 187 return $this->comparison($x, self::GT, $y); 188 } 189 190 /** 191 * Creates a greater-than-equal comparison expression with the given arguments. 192 * First argument is considered the left expression and the second is the right expression. 193 * When converted to string, it will generated a <left expr> >= <right expr>. Example: 194 * 195 * [php] 196 * // u.id >= ? 197 * $q->where($q->expr()->gte('u.id', '?')); 198 * 199 * @param mixed $x The left expression. 200 * @param mixed $y The right expression. 201 * 202 * @return string 203 */ 204 public function gte($x, $y) 205 { 206 return $this->comparison($x, self::GTE, $y); 207 } 208 209 /** 210 * Creates an IS NULL expression with the given arguments. 211 * 212 * @param string $x The expression to be restricted by IS NULL. 213 * 214 * @return string 215 */ 216 public function isNull($x) 217 { 218 return $x . ' IS NULL'; 219 } 220 221 /** 222 * Creates an IS NOT NULL expression with the given arguments. 223 * 224 * @param string $x The expression to be restricted by IS NOT NULL. 225 * 226 * @return string 227 */ 228 public function isNotNull($x) 229 { 230 return $x . ' IS NOT NULL'; 231 } 232 233 /** 234 * Creates a LIKE() comparison expression with the given arguments. 235 * 236 * @param string $x Field in string format to be inspected by LIKE() comparison. 237 * @param mixed $y Argument to be used in LIKE() comparison. 238 * 239 * @return string 240 */ 241 public function like($x, $y/*, ?string $escapeChar = null */) 242 { 243 return $this->comparison($x, 'LIKE', $y) . 244 (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : ''); 245 } 246 247 /** 248 * Creates a NOT LIKE() comparison expression with the given arguments. 249 * 250 * @param string $x Field in string format to be inspected by NOT LIKE() comparison. 251 * @param mixed $y Argument to be used in NOT LIKE() comparison. 252 * 253 * @return string 254 */ 255 public function notLike($x, $y/*, ?string $escapeChar = null */) 256 { 257 return $this->comparison($x, 'NOT LIKE', $y) . 258 (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : ''); 259 } 260 261 /** 262 * Creates a IN () comparison expression with the given arguments. 263 * 264 * @param string $x The field in string format to be inspected by IN() comparison. 265 * @param string|string[] $y The placeholder or the array of values to be used by IN() comparison. 266 * 267 * @return string 268 */ 269 public function in($x, $y) 270 { 271 return $this->comparison($x, 'IN', '(' . implode(', ', (array) $y) . ')'); 272 } 273 274 /** 275 * Creates a NOT IN () comparison expression with the given arguments. 276 * 277 * @param string $x The expression to be inspected by NOT IN() comparison. 278 * @param string|string[] $y The placeholder or the array of values to be used by NOT IN() comparison. 279 * 280 * @return string 281 */ 282 public function notIn($x, $y) 283 { 284 return $this->comparison($x, 'NOT IN', '(' . implode(', ', (array) $y) . ')'); 285 } 286 287 /** 288 * Quotes a given input parameter. 289 * 290 * @param mixed $input The parameter to be quoted. 291 * @param int|null $type The type of the parameter. 292 * 293 * @return string 294 */ 295 public function literal($input, $type = null) 296 { 297 return $this->connection->quote($input, $type); 298 } 299} 300