Test Failed
Pull Request — dev (#48)
by Wilmer
25:37 queued 08:28
created

InConditionBuilder::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Oracle\Builder;
6
7
use Yiisoft\Db\Exception\Exception;
8
use Yiisoft\Db\Exception\InvalidArgumentException;
9
use Yiisoft\Db\Exception\InvalidConfigException;
10
use Yiisoft\Db\Exception\NotSupportedException;
11
use Yiisoft\Db\Expression\ExpressionInterface;
12
use Yiisoft\Db\Query\Conditions\Builder\InConditionBuilder as AbstractInConditionBuilder;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Query\Conditi...lder\InConditionBuilder 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\Query\Conditions\InCondition;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Query\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\Query\QueryBuilderInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Query\QueryBuilderInterface 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
final class InConditionBuilder extends AbstractInConditionBuilder
17
{
18
    public function __construct(private QueryBuilderInterface $queryBuilder)
19
    {
20
        parent::__construct($queryBuilder);
21
    }
22
23
    /**
24
     * Method builds the raw SQL from the $expression that will not be additionally
25
     * escaped or quoted.
26
     *
27
     * @param ExpressionInterface $expression the expression to be built.
28
     * @param array $params the binding parameters.
29
     *
30
     * @return string the raw SQL that will not be additionally escaped or quoted.
31
     */
32
    public function build(ExpressionInterface $expression, array &$params = []): string
33
    {
34
        /** @var Incondition $expression */
35
        $splitCondition = $this->splitCondition($expression, $params);
36
37
        if ($splitCondition !== null) {
38
            return $splitCondition;
39
        }
40
41
        return parent::build($expression, $params);
42
    }
43
44
    /**
45
     * Oracle DBMS does not support more than 1000 parameters in `IN` condition.
46
     * This method splits long `IN` condition into series of smaller ones.
47
     *
48
     * @param InCondition $condition
49
     * @param array $params the binding parameters.
50
     *
51
     * @throws Exception|InvalidArgumentException|InvalidConfigException|NotSupportedException
52
     *
53
     * @return string|null null when split is not required. Otherwise - built SQL condition.
54
     */
55
    protected function splitCondition(InCondition $condition, array &$params): ?string
56
    {
57
        $operator = $condition->getOperator();
58
        $values = $condition->getValues();
59
        $column = $condition->getColumn();
60
61
        if (!is_array($values)) {
62
            return null;
63
        }
64
65
        $maxParameters = 1000;
66
        $count = count($values);
67
68
        if ($count <= $maxParameters) {
69
            return null;
70
        }
71
72
        $slices = [];
73
74
        for ($i = 0; $i < $count; $i += $maxParameters) {
75
            $slices[] = $this->queryBuilder->createConditionFromArray([$operator, $column, array_slice($values, $i, $maxParameters)]);
76
        }
77
78
        array_unshift($slices, ($operator === 'IN') ? 'OR' : 'AND');
79
80
        return $this->queryBuilder->buildCondition($slices, $params);
81
    }
82
}
83