Passed
Push — master ( 6c3f09...c54108 )
by William
03:43
created

SetOperation::parse()   C

Complexity

Conditions 15
Paths 8

Size

Total Lines 88
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 41
CRAP Score 15

Importance

Changes 0
Metric Value
cc 15
eloc 40
nc 8
nop 3
dl 0
loc 88
ccs 41
cts 41
cp 1
crap 15
rs 5.9166
c 0
b 0
f 0

How to fix   Long Method    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 PhpMyAdmin\SqlParser\Components;
6
7
use PhpMyAdmin\SqlParser\Component;
8
use PhpMyAdmin\SqlParser\Parser;
9
use PhpMyAdmin\SqlParser\Token;
10
use PhpMyAdmin\SqlParser\TokensList;
11
12
use function implode;
13
use function is_array;
14
use function trim;
15
16
/**
17
 * `SET` keyword parser.
18
 */
19
final class SetOperation implements Component
20
{
21
    /**
22
     * The name of the column that is being updated.
23
     *
24
     * @var string
25
     */
26
    public $column;
27
28
    /**
29
     * The new value.
30
     *
31
     * @var string
32
     */
33
    public $value;
34
35
    /**
36
     * @param string $column Field's name..
37
     * @param string $value  new value
38
     */
39 94
    public function __construct($column = '', $value = '')
40
    {
41 94
        $this->column = $column;
42 94
        $this->value = $value;
43
    }
44
45
    /**
46
     * @param Parser               $parser  the parser that serves as context
47
     * @param TokensList           $list    the list of tokens that are being parsed
48
     * @param array<string, mixed> $options parameters for parsing
49
     *
50
     * @return SetOperation[]
51
     */
52 94
    public static function parse(Parser $parser, TokensList $list, array $options = [])
53
    {
54 94
        $ret = [];
55
56 94
        $expr = new static();
57
58
        /**
59
         * The state of the parser.
60
         *
61
         * Below are the states of the parser.
62
         *
63
         *      0 ---------------------[ col_name ]--------------------> 0
64
         *      0 ------------------------[ = ]------------------------> 1
65
         *      1 -----------------------[ value ]---------------------> 1
66
         *      1 ------------------------[ , ]------------------------> 0
67
         *
68
         * @var int
69
         */
70 94
        $state = 0;
71
72
        /**
73
         * Token when the parser has seen the latest comma
74
         *
75
         * @var Token
76
         */
77 94
        $commaLastSeenAt = null;
78
79 94
        for (; $list->idx < $list->count; ++$list->idx) {
80
            /**
81
             * Token parsed at this moment.
82
             */
83 94
            $token = $list->tokens[$list->idx];
84
85
            // End of statement.
86 94
            if ($token->type === Token::TYPE_DELIMITER) {
87 80
                break;
88
            }
89
90
            // Skipping whitespaces and comments.
91 76
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
92 66
                continue;
93
            }
94
95
            // No keyword is expected.
96
            if (
97 76
                ($token->type === Token::TYPE_KEYWORD)
98 76
                && ($token->flags & Token::FLAG_KEYWORD_RESERVED)
99 76
                && ($state === 0)
100
            ) {
101 16
                break;
102
            }
103
104 76
            if ($state === 0) {
105 76
                if ($token->token === '=') {
106 76
                    $state = 1;
107 74
                } elseif ($token->value !== ',') {
108 74
                    $expr->column .= $token->token;
109 22
                } elseif ($token->value === ',') {
110 76
                    $commaLastSeenAt = $token;
111
                }
112 76
            } elseif ($state === 1) {
113 76
                $tmp = Expression::parse(
114 76
                    $parser,
115 76
                    $list,
116 76
                    ['breakOnAlias' => true]
117 76
                );
118 76
                if ($tmp === null) {
119 2
                    $parser->error('Missing expression.', $token);
120 2
                    break;
121
                }
122
123 74
                $expr->column = trim($expr->column);
124 74
                $expr->value = $tmp->expr;
125 74
                $ret[] = $expr;
126 74
                $expr = new static();
127 74
                $state = 0;
128 74
                $commaLastSeenAt = null;
129
            }
130
        }
131
132 94
        --$list->idx;
133
134
        // We saw a comma, but didn't see a column-value pair after it
135 94
        if ($commaLastSeenAt !== null) {
0 ignored issues
show
introduced by
The condition $commaLastSeenAt !== null is always false.
Loading history...
136 2
            $parser->error('Unexpected token.', $commaLastSeenAt);
137
        }
138
139 94
        return $ret;
140
    }
141
142
    /**
143
     * @param SetOperation|SetOperation[] $component the component to be built
144
     * @param array<string, mixed>        $options   parameters for building
145
     */
146 36
    public static function build($component, array $options = []): string
147
    {
148 36
        if (is_array($component)) {
149 36
            return implode(', ', $component);
150
        }
151
152 34
        return $component->column . ' = ' . $component->value;
153
    }
154
155 34
    public function __toString(): string
156
    {
157 34
        return static::build($this);
158
    }
159
}
160