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