Test Failed
Push — fix-update-with-expressions ( 0c8de2...b05a97 )
by Sergei
05:42 queued 02:26
created

SqlParser::getNextPlaceholder()   B

Complexity

Conditions 10
Paths 3

Size

Total Lines 38
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 27
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 38
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql;
6
7
use Yiisoft\Db\Syntax\SqlParser as BaseSqlParser;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Syntax\SqlParser 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...
8
9
final class SqlParser extends BaseSqlParser
10
{
11
    public function getNextPlaceholder(int|null &$position = null): string|null
12
    {
13
        $result = null;
14
        $length = $this->length - 1;
15
16
        while ($this->position < $length) {
17
            $pos = $this->position++;
18
19
            match ($this->sql[$pos]) {
20
                ':' => ($word = $this->parseWord()) === ''
21
                    ? $this->skipChars(':')
22
                    : $result = ':' . $word,
23
                '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]),
24
                'e', 'E' => $this->sql[$this->position] === "'"
25
                    ? ++$this->position && $this->skipQuotedWithEscape("'")
26
                    : $this->skipIdentifier(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->skipIdentifier() targeting Yiisoft\Db\Pgsql\SqlParser::skipIdentifier() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
27
                '$' => $this->skipQuotedWithDollar(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->skipQuotedWithDollar() targeting Yiisoft\Db\Pgsql\SqlParser::skipQuotedWithDollar() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
28
                '-' => $this->sql[$this->position] === '-'
29
                    ? ++$this->position && $this->skipToAfterChar("\n")
30
                    : null,
31
                '/' => $this->sql[$this->position] === '*'
32
                    ? ++$this->position && $this->skipToAfterString('*/')
33
                    : null,
34
                // Identifiers can contain dollar sign which can be used for quoting. Skip them.
35
                '_','a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
36
                'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
37
                'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' => $this->skipIdentifier(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->skipIdentifier() targeting Yiisoft\Db\Pgsql\SqlParser::skipIdentifier() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
38
                default => null,
39
            };
40
41
            if ($result !== null) {
42
                $position = $pos;
43
44
                return $result;
45
            }
46
        }
47
48
        return null;
49
    }
50
51
    /**
52
     * Parses and returns identifier. Equals to `[_a-zA-Z][$\w]+` in regular expressions.
53
     *
54
     * @return string Parsed identifier.
55
     */
56
    protected function parseIdentifier(): string
57
    {
58
        return match ($this->sql[$this->position]) {
59
            '_',
60
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
61
            'v', 'w', 'x', 'y', 'z',
62
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
63
            'V', 'W', 'X', 'Y', 'Z' => $this->sql[$this->position++] . $this->parseWordWithDollar(),
64
            default => '',
65
        };
66
    }
67
68
    /**
69
     * Parses and returns identifier without dollar sign. Equals to `[_a-zA-Z]\w+` in regular expressions.
70
     *
71
     * @return string Parsed identifier.
72
     */
73
    private function parseIdentifierWithoutDollar(): string
74
    {
75
        return parent::parseIdentifier();
76
    }
77
78
    /**
79
     * Parses and returns word symbols include dollar sign. Equals to `[$\w]+` in regular expressions.
80
     *
81
     * @return string Parsed word symbols.
82
     */
83
    private function parseWordWithDollar(): string
84
    {
85
        $word = '';
86
        $continue = true;
87
88
        while ($continue && $this->position < $this->length) {
89
            match ($this->sql[$this->position]) {
90
                '$', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
91
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
92
                'v', 'w', 'x', 'y', 'z',
93
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
94
                'V', 'W', 'X', 'Y', 'Z' => $word .= $this->sql[$this->position++],
95
                default => $continue = false,
96
            };
97
        }
98
99
        return $word;
100
    }
101
102
    /**
103
     * Skips dollar-quoted string.
104
     */
105
    private function skipQuotedWithDollar(): void
106
    {
107
        $pos = $this->position;
108
        $identifier = $this->parseIdentifierWithoutDollar();
109
110
        if ($this->sql[$this->position] !== '$') {
111
            $this->position = $pos;
0 ignored issues
show
Bug Best Practice introduced by
The property position does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
112
            return;
113
        }
114
115
        ++$this->position;
116
117
        $this->skipToAfterString('$' . $identifier . '$');
118
    }
119
120
    /**
121
     * Skips an identifier. Equals to `[$\w]+` in regular expressions.
122
     */
123
    private function skipIdentifier(): void
124
    {
125
        $continue = true;
126
127
        while ($continue && $this->position < $this->length) {
128
            match ($this->sql[$this->position]) {
129
                '$', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
130
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
131
                'v', 'w', 'x', 'y', 'z',
132
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
133
                'V', 'W', 'X', 'Y', 'Z' => ++$this->position,
134
                default => $continue = false,
135
            };
136
        }
137
    }
138
}
139