ExpressionBuilder.php 8.86 KB
Newer Older
1 2 3 4 5
<?php

namespace Doctrine\DBAL\Query\Expression;

use Doctrine\DBAL\Connection;
6

7
use function func_get_arg;
8
use function func_get_args;
9
use function func_num_args;
10
use function implode;
11
use function sprintf;
12 13 14 15 16 17

/**
 * ExpressionBuilder class is responsible to dynamically create SQL query parts.
 */
class ExpressionBuilder
{
18 19 20 21 22 23
    public const EQ  = '=';
    public const NEQ = '<>';
    public const LT  = '<';
    public const LTE = '<=';
    public const GT  = '>';
    public const GTE = '>=';
24

25
    /**
Benjamin Morel's avatar
Benjamin Morel committed
26 27
     * The DBAL Connection.
     *
28
     * @var Connection
29
     */
Benjamin Morel's avatar
Benjamin Morel committed
30
    private $connection;
31 32 33 34

    /**
     * Initializes a new <tt>ExpressionBuilder</tt>.
     *
35
     * @param Connection $connection The DBAL Connection.
36 37 38 39 40
     */
    public function __construct(Connection $connection)
    {
        $this->connection = $connection;
    }
41

42
    /**
43
     * Creates a conjunction of the given expressions.
44
     *
45 46
     * @param string|CompositeExpression $expression
     * @param string|CompositeExpression ...$expressions
47
     */
48
    public function and($expression, ...$expressions): CompositeExpression
49
    {
50
        return CompositeExpression::and($expression, ...$expressions);
51 52 53 54
    }

    /**
     * Creates a disjunction of the given expressions.
55
     *
56 57
     * @param string|CompositeExpression $expression
     * @param string|CompositeExpression ...$expressions
58
     */
59
    public function or($expression, ...$expressions): CompositeExpression
60
    {
61
        return CompositeExpression::or($expression, ...$expressions);
62 63 64 65
    }

    /**
     * @deprecated Use `and()` instead.
66 67 68
     *
     * @param mixed $x Optional clause. Defaults = null, but requires
     *                 at least one defined when converting to string.
Benjamin Morel's avatar
Benjamin Morel committed
69
     *
70
     * @return CompositeExpression
71 72 73
     */
    public function andX($x = null)
    {
74
        return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
75 76 77
    }

    /**
78
     * @deprecated Use `or()` instead.
79 80 81
     *
     * @param mixed $x Optional clause. Defaults = null, but requires
     *                 at least one defined when converting to string.
Benjamin Morel's avatar
Benjamin Morel committed
82
     *
83
     * @return CompositeExpression
84 85 86
     */
    public function orX($x = null)
    {
87
        return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args());
88 89 90 91
    }

    /**
     * Creates a comparison expression.
92
     *
Benjamin Morel's avatar
Benjamin Morel committed
93
     * @param mixed  $x        The left expression.
94
     * @param string $operator One of the ExpressionBuilder::* constants.
Benjamin Morel's avatar
Benjamin Morel committed
95 96
     * @param mixed  $y        The right expression.
     *
97 98 99 100 101 102
     * @return string
     */
    public function comparison($x, $operator, $y)
    {
        return $x . ' ' . $operator . ' ' . $y;
    }
103

104 105 106 107 108 109 110 111 112 113
    /**
     * Creates an equality comparison expression with the given arguments.
     *
     * First argument is considered the left expression and the second is the right expression.
     * When converted to string, it will generated a <left expr> = <right expr>. Example:
     *
     *     [php]
     *     // u.id = ?
     *     $expr->eq('u.id', '?');
     *
Benjamin Morel's avatar
Benjamin Morel committed
114 115 116
     * @param mixed $x The left expression.
     * @param mixed $y The right expression.
     *
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
     * @return string
     */
    public function eq($x, $y)
    {
        return $this->comparison($x, self::EQ, $y);
    }

    /**
     * Creates a non equality comparison expression with the given arguments.
     * First argument is considered the left expression and the second is the right expression.
     * When converted to string, it will generated a <left expr> <> <right expr>. Example:
     *
     *     [php]
     *     // u.id <> 1
     *     $q->where($q->expr()->neq('u.id', '1'));
     *
Benjamin Morel's avatar
Benjamin Morel committed
133 134 135
     * @param mixed $x The left expression.
     * @param mixed $y The right expression.
     *
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
     * @return string
     */
    public function neq($x, $y)
    {
        return $this->comparison($x, self::NEQ, $y);
    }

    /**
     * Creates a lower-than comparison expression with the given arguments.
     * First argument is considered the left expression and the second is the right expression.
     * When converted to string, it will generated a <left expr> < <right expr>. Example:
     *
     *     [php]
     *     // u.id < ?
     *     $q->where($q->expr()->lt('u.id', '?'));
     *
Benjamin Morel's avatar
Benjamin Morel committed
152 153 154
     * @param mixed $x The left expression.
     * @param mixed $y The right expression.
     *
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
     * @return string
     */
    public function lt($x, $y)
    {
        return $this->comparison($x, self::LT, $y);
    }

    /**
     * Creates a lower-than-equal comparison expression with the given arguments.
     * First argument is considered the left expression and the second is the right expression.
     * When converted to string, it will generated a <left expr> <= <right expr>. Example:
     *
     *     [php]
     *     // u.id <= ?
     *     $q->where($q->expr()->lte('u.id', '?'));
     *
Benjamin Morel's avatar
Benjamin Morel committed
171 172 173
     * @param mixed $x The left expression.
     * @param mixed $y The right expression.
     *
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
     * @return string
     */
    public function lte($x, $y)
    {
        return $this->comparison($x, self::LTE, $y);
    }

    /**
     * Creates a greater-than comparison expression with the given arguments.
     * First argument is considered the left expression and the second is the right expression.
     * When converted to string, it will generated a <left expr> > <right expr>. Example:
     *
     *     [php]
     *     // u.id > ?
     *     $q->where($q->expr()->gt('u.id', '?'));
     *
Benjamin Morel's avatar
Benjamin Morel committed
190 191 192
     * @param mixed $x The left expression.
     * @param mixed $y The right expression.
     *
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
     * @return string
     */
    public function gt($x, $y)
    {
        return $this->comparison($x, self::GT, $y);
    }

    /**
     * Creates a greater-than-equal comparison expression with the given arguments.
     * First argument is considered the left expression and the second is the right expression.
     * When converted to string, it will generated a <left expr> >= <right expr>. Example:
     *
     *     [php]
     *     // u.id >= ?
     *     $q->where($q->expr()->gte('u.id', '?'));
     *
Benjamin Morel's avatar
Benjamin Morel committed
209 210 211
     * @param mixed $x The left expression.
     * @param mixed $y The right expression.
     *
212 213 214 215 216 217 218 219 220 221
     * @return string
     */
    public function gte($x, $y)
    {
        return $this->comparison($x, self::GTE, $y);
    }

    /**
     * Creates an IS NULL expression with the given arguments.
     *
Benjamin Morel's avatar
Benjamin Morel committed
222
     * @param string $x The field in string format to be restricted by IS NULL.
223
     *
224 225 226 227 228 229 230 231 232 233
     * @return string
     */
    public function isNull($x)
    {
        return $x . ' IS NULL';
    }

    /**
     * Creates an IS NOT NULL expression with the given arguments.
     *
Benjamin Morel's avatar
Benjamin Morel committed
234
     * @param string $x The field in string format to be restricted by IS NOT NULL.
235
     *
236 237 238 239 240 241 242 243 244 245 246
     * @return string
     */
    public function isNotNull($x)
    {
        return $x . ' IS NOT NULL';
    }

    /**
     * Creates a LIKE() comparison expression with the given arguments.
     *
     * @param string $x Field in string format to be inspected by LIKE() comparison.
Benjamin Morel's avatar
Benjamin Morel committed
247
     * @param mixed  $y Argument to be used in LIKE() comparison.
248
     *
249 250
     * @return string
     */
251
    public function like($x, $y/*, ?string $escapeChar = null */)
252
    {
253
        return $this->comparison($x, 'LIKE', $y) .
254
            (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : '');
255
    }
Steve Müller's avatar
Steve Müller committed
256

257 258 259 260
    /**
     * Creates a NOT LIKE() comparison expression with the given arguments.
     *
     * @param string $x Field in string format to be inspected by NOT LIKE() comparison.
261
     * @param mixed  $y Argument to be used in NOT LIKE() comparison.
262 263 264
     *
     * @return string
     */
265
    public function notLike($x, $y/*, ?string $escapeChar = null */)
266
    {
267
        return $this->comparison($x, 'NOT LIKE', $y) .
268
            (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : '');
269
    }
270

271 272 273
    /**
     * Creates a IN () comparison expression with the given arguments.
     *
274 275
     * @param string          $x The field in string format to be inspected by IN() comparison.
     * @param string|string[] $y The placeholder or the array of values to be used by IN() comparison.
276 277 278
     *
     * @return string
     */
279
    public function in($x, $y)
280
    {
281
        return $this->comparison($x, 'IN', '(' . implode(', ', (array) $y) . ')');
282 283 284 285 286
    }

    /**
     * Creates a NOT IN () comparison expression with the given arguments.
     *
287 288
     * @param string          $x The field in string format to be inspected by NOT IN() comparison.
     * @param string|string[] $y The placeholder or the array of values to be used by NOT IN() comparison.
289 290 291
     *
     * @return string
     */
292
    public function notIn($x, $y)
293
    {
294
        return $this->comparison($x, 'NOT IN', '(' . implode(', ', (array) $y) . ')');
295 296
    }

297 298
    /**
     * Quotes a given input parameter.
299
     *
Sergei Morozov's avatar
Sergei Morozov committed
300 301
     * @param mixed    $input The parameter to be quoted.
     * @param int|null $type  The type of the parameter.
302
     *
303 304 305 306 307 308
     * @return string
     */
    public function literal($input, $type = null)
    {
        return $this->connection->quote($input, $type);
    }
Benjamin Eberlei's avatar
Benjamin Eberlei committed
309
}