Passed
Pull Request — master (#223)
by Def
03:33
created

DQLQueryBuilder   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 16
c 2
b 0
f 0
dl 0
loc 66
ccs 21
cts 21
cp 1
rs 10
wmc 11

4 Methods

Rating   Name   Duplication   Size   Complexity  
B buildLimit() 0 23 7
A hasOffset() 0 5 2
A defaultExpressionBuilders() 0 6 1
A hasLimit() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Mysql;
6
7
use Yiisoft\Db\Expression\ExpressionBuilder;
8
use Yiisoft\Db\Expression\ExpressionInterface;
9
use Yiisoft\Db\Expression\JsonExpression;
10
use Yiisoft\Db\Mysql\Builder\JsonExpressionBuilder;
11
use Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder;
12
13
use function array_merge;
14
use function ctype_digit;
15
16
final class DQLQueryBuilder extends AbstractDQLQueryBuilder
17
{
18 238
    public function buildLimit(ExpressionInterface|int|null $limit, ExpressionInterface|int|null $offset): string
19
    {
20 238
        $sql = '';
21
22 238
        if ($this->hasLimit($limit)) {
23 16
            $sql = 'LIMIT ' . ($limit instanceof ExpressionInterface ? $this->buildExpression($limit) : (string)$limit);
24
25 16
            if ($this->hasOffset($offset)) {
26 16
                $sql .= ' OFFSET ' . ($offset instanceof ExpressionInterface ? $this->buildExpression($offset) : (string)$offset);
27
            }
28 228
        } elseif ($this->hasOffset($offset)) {
29
            /**
30
             * limit is not optional in MySQL.
31
             *
32
             * http://stackoverflow.com/a/271650/1106908
33
             * http://dev.mysql.com/doc/refman/5.0/en/select.html#idm47619502796240
34
             */
35 1
            $sql = 'LIMIT ' .
36 1
                ($offset instanceof ExpressionInterface ? $this->buildExpression($offset) : (string)$offset) .
37 1
                ', 18446744073709551615'; // 2^64-1
38
        }
39
40 238
        return $sql;
41
    }
42
43
    /**
44
     * Checks to see if the given limit is effective.
45
     *
46
     * @param mixed $limit The given limit.
47
     *
48
     * @return bool Whether the limit is effective.
49
     */
50 238
    protected function hasLimit(mixed $limit): bool
51
    {
52
        /** In MySQL limit argument must be non-negative integer constant */
53 238
        return ctype_digit((string) $limit);
54
    }
55
56
    /**
57
     * Checks to see if the given offset is effective.
58
     *
59
     * @param mixed $offset The given offset.
60
     *
61
     * @return bool Whether the offset is effective.
62
     */
63 238
    protected function hasOffset(mixed $offset): bool
64
    {
65
        /** In MySQL offset argument must be non-negative integer constant */
66 238
        $offset = (string) $offset;
67 238
        return ctype_digit($offset) && $offset !== '0';
68
    }
69
70
    /**
71
     * Contains array of default expression builders. Extend this method and override it, if you want to change default
72
     * expression builders for this query builder.
73
     *
74
     * See {@see ExpressionBuilder} docs for details.
75
     */
76 507
    protected function defaultExpressionBuilders(): array
77
    {
78 507
        return array_merge(
79 507
            parent::defaultExpressionBuilders(),
80 507
            [
81 507
                JsonExpression::class => JsonExpressionBuilder::class,
82 507
            ]
83 507
        );
84
    }
85
}
86