Completed
Pull Request — 2.1 (#15718)
by Alex
17:00
created

InConditionBuilder   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 56
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 3
dl 0
loc 56
ccs 0
cts 30
cp 0
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A build() 0 9 2
B splitCondition() 0 27 6
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\db\oci\conditions;
9
10
use yii\db\conditions\InCondition;
11
use yii\db\ExpressionInterface;
12
13
/**
14
 * {@inheritdoc}
15
 */
16
class InConditionBuilder extends \yii\db\conditions\InConditionBuilder
17
{
18
    /**
19
     * Method builds the raw SQL from the $expression that will not be additionally
20
     * escaped or quoted.
21
     *
22
     * @param ExpressionInterface|InCondition $expression the expression to be built.
23
     * @param array $params the binding parameters.
24
     * @return string the raw SQL that will not be additionally escaped or quoted.
25
     */
26
    public function build(ExpressionInterface $expression, array &$params = [])
27
    {
28
        $splitCondition = $this->splitCondition($expression, $params);
0 ignored issues
show
Compatibility introduced by
$expression of type object<yii\db\ExpressionInterface> is not a sub-type of object<yii\db\conditions\InCondition>. It seems like you assume a concrete implementation of the interface yii\db\ExpressionInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
29
        if ($splitCondition !== null) {
30
            return $splitCondition;
31
        }
32
33
        return parent::build($expression, $params);
34
    }
35
36
    /**
37
     * Oracle DBMS does not support more than 1000 parameters in `IN` condition.
38
     * This method splits long `IN` condition into series of smaller ones.
39
     *
40
     * @param ExpressionInterface|InCondition $condition the expression to be built.
41
     * @param array $params the binding parameters.
42
     * @return null|string null when split is not required. Otherwise - built SQL condition.
43
     */
44
    protected function splitCondition(InCondition $condition, &$params)
45
    {
46
        $operator = $condition->getOperator();
47
        $values = $condition->getValues();
48
        $column = $condition->getColumn();
49
50
        if ($values instanceof \Traversable) {
51
            $values = iterator_to_array($values);
52
        }
53
54
        if (!is_array($values)) {
55
            return null;
56
        }
57
58
        $maxParameters = 1000;
59
        $count = count($values);
60
        if ($count <= $maxParameters) {
61
            return null;
62
        }
63
64
        $slices = [];
65
        for ($i = 0; $i < $count; $i += $maxParameters) {
66
            $slices[] = $this->queryBuilder->createConditionFromArray([$operator, $column, array_slice($values, $i, $maxParameters)]);
67
        }
68
69
        return $this->queryBuilder->buildCondition([($operator === 'IN') ? 'OR' : 'AND', $slices], $params);
70
    }
71
}
72