Passed
Push — master ( 9b125d...f5b0c0 )
by Alexander
11:25 queued 07:35
created

DQLQueryBuilder::buildOrderByAndLimit()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 4
c 1
b 0
f 0
nc 3
nop 5
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 4
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Mssql;
6
7
use Yiisoft\Db\Exception\Exception;
8
use Yiisoft\Db\Exception\InvalidArgumentException;
9
use Yiisoft\Db\Expression\Expression;
10
use Yiisoft\Db\Mssql\Builder\InConditionBuilder;
11
use Yiisoft\Db\Mssql\Builder\LikeConditionBuilder;
12
use Yiisoft\Db\QueryBuilder\DQLQueryBuilder as AbstractDQLQueryBuilder;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\QueryBuilder\DQLQueryBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Yiisoft\Db\QueryBuilder\Conditions\InCondition;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\QueryBuilder\Conditions\InCondition was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Yiisoft\Db\QueryBuilder\Conditions\LikeCondition;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\QueryBuilder\Conditions\LikeCondition was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
16
use function array_merge;
17
use function preg_match;
18
19
final class DQLQueryBuilder extends AbstractDQLQueryBuilder
20
{
21 171
    public function buildOrderByAndLimit(string $sql, array $orderBy, $limit, $offset, array &$params = []): string
22
    {
23 171
        if (!$this->hasOffset($offset) && !$this->hasLimit($limit)) {
24 162
            $orderByString = $this->buildOrderBy($orderBy, $params);
25
26 162
            return $orderByString === '' ? $sql : $sql . $this->separator . $orderByString;
27
        }
28
29 13
        return $this->newBuildOrderByAndLimit($sql, $orderBy, $limit, $offset, $params);
30
    }
31
32 1
    public function selectExists(string $rawSql): string
33
    {
34 1
        return 'SELECT CASE WHEN EXISTS(' . $rawSql . ') THEN 1 ELSE 0 END';
35
    }
36
37 386
    protected function defaultExpressionBuilders(): array
38
    {
39 386
        return array_merge(parent::defaultExpressionBuilders(), [
40
            InCondition::class => InConditionBuilder::class,
41
            LikeCondition::class => LikeConditionBuilder::class,
42
        ]);
43
    }
44
45
    /**
46
     * Builds the ORDER BY/LIMIT/OFFSET clauses for SQL SERVER 2012 or newer.
47
     *
48
     * @param string $sql the existing SQL (without ORDER BY/LIMIT/OFFSET).
49
     * @param array $orderBy the order by columns. See {@see Query::orderBy} for more details on how to specify
50
     * this parameter.
51
     * @param Expression|int|null $limit the limit number. See {@see Query::limit} for more details.
52
     * @param Expression|int|null $offset the offset number. See {@see Query::offset} for more details.
53
     * @param array $params the binding parameters to be populated.
54
     *
55
     * @throws Exception|InvalidArgumentException
56
     *
57
     * @return string the SQL completed with ORDER BY/LIMIT/OFFSET (if any).
58
     */
59 13
    protected function newBuildOrderByAndLimit(
60
        string $sql,
61
        array $orderBy,
62
        Expression|int|null $limit,
63
        Expression|int|null $offset,
64
        array &$params = []
65
    ): string {
66 13
        $orderByString = $this->buildOrderBy($orderBy, $params);
67
68 13
        if ($orderByString === '') {
69
            /** ORDER BY clause is required when FETCH and OFFSET are in the SQL */
70 10
            $orderByString = 'ORDER BY (SELECT NULL)';
71
        }
72
73 13
        $sql .= $this->separator . $orderByString;
74
75
        /**
76
         * {@see http://technet.microsoft.com/en-us/library/gg699618.aspx}
77
         */
78 13
        $offsetString = $this->hasOffset($offset) ? (string) $offset : '0';
79 13
        $sql .= $this->separator . 'OFFSET ' . $offsetString . ' ROWS';
80
81 13
        if ($this->hasLimit($limit)) {
82 12
            $sql .= $this->separator . 'FETCH NEXT ' . (string) $limit . ' ROWS ONLY';
83
        }
84
85 13
        return $sql;
86
    }
87
88
    /**
89
     * Extracts table alias if there is one or returns false
90
     *
91
     * @param string $table
92
     *
93
     * @return array|bool
94
     *
95
     * @psalm-return string[]|bool
96
     */
97 62
    protected function extractAlias(string $table): array|bool
98
    {
99 62
        if (preg_match('/^\[.*]$/', $table)) {
100
            return false;
101
        }
102
103 62
        return parent::extractAlias($table);
104
    }
105
}
106