Passed
Pull Request — master (#408)
by
unknown
03:08
created

AlterStatement::parse()   C

Complexity

Conditions 14
Paths 12

Size

Total Lines 65
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 14.031

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 14
eloc 33
c 1
b 1
f 0
nc 12
nop 2
dl 0
loc 65
ccs 35
cts 37
cp 0.9459
crap 14.031
rs 6.2666

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\Statements;
6
7
use PhpMyAdmin\SqlParser\Components\AlterOperation;
8
use PhpMyAdmin\SqlParser\Components\Expression;
9
use PhpMyAdmin\SqlParser\Components\OptionsArray;
10
use PhpMyAdmin\SqlParser\Parser;
11
use PhpMyAdmin\SqlParser\Statement;
12
use PhpMyAdmin\SqlParser\Token;
13
use PhpMyAdmin\SqlParser\TokensList;
14
15
use function array_merge;
16
use function implode;
17
18
/**
19
 * `ALTER` statement.
20
 */
21
class AlterStatement extends Statement
22
{
23
    /**
24
     * Table affected.
25
     *
26
     * @var Expression|null
27
     */
28
    public $table;
29
30
    /**
31
     * Column affected by this statement.
32
     *
33
     * @var AlterOperation[]|null
34
     */
35
    public $altered = [];
36
37
    /**
38
     * Options of this statement.
39
     *
40
     * @var array<string, int|array<int, int|string>>
41
     * @psalm-var array<string, (positive-int|array{positive-int, ('var'|'var='|'expr'|'expr=')})>
42
     */
43
    public static $OPTIONS = [
44
        'ONLINE' => 1,
45
        'OFFLINE' => 1,
46
        'IGNORE' => 2,
47
48
        'DATABASE' => 3,
49
        'EVENT' => 3,
50
        'FUNCTION' => 3,
51
        'PROCEDURE' => 3,
52
        'SERVER' => 3,
53
        'TABLE' => 3,
54
        'TABLESPACE' => 3,
55
        'USER' => 3,
56
        'VIEW' => 3,
57
    ];
58
59
    /**
60
     * @param Parser     $parser the instance that requests parsing
61
     * @param TokensList $list   the list of tokens to be parsed
62
     */
63 172
    public function parse(Parser $parser, TokensList $list)
64
    {
65 172
        ++$list->idx; // Skipping `ALTER`.
66 172
        $this->options = OptionsArray::parse($parser, $list, static::$OPTIONS);
67 172
        ++$list->idx;
68
69
        // Parsing affected table.
70 172
        $this->table = Expression::parse(
71 172
            $parser,
72 172
            $list,
73 172
            [
74 172
                'parseField' => 'table',
75 172
                'breakOnAlias' => true,
76 172
            ]
77 172
        );
78 172
        ++$list->idx; // Skipping field.
79
80
        /**
81
         * The state of the parser.
82
         *
83
         * Below are the states of the parser.
84
         *
85
         *      0 -----------------[ alter operation ]-----------------> 1
86
         *
87
         *      1 -------------------------[ , ]-----------------------> 0
88
         *
89
         * @var int
90
         */
91 172
        $state = 0;
92
93 172
        for (; $list->idx < $list->count; ++$list->idx) {
94
            /**
95
             * Token parsed at this moment.
96
             */
97 172
            $token = $list->tokens[$list->idx];
98
99
            // End of statement.
100 172
            if ($token->type === Token::TYPE_DELIMITER) {
101 168
                break;
102
            }
103
104
            // Skipping whitespaces and comments.
105 172
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
106 40
                continue;
107
            }
108
109 172
            if ($state === 0) {
110 172
                $options = [];
111 172
                if ($this->options->has('DATABASE')) {
112 4
                    $options = AlterOperation::$DB_OPTIONS;
113 168
                } elseif ($this->options->has('TABLE')) {
114 128
                    $options = AlterOperation::$TABLE_OPTIONS;
115 40
                } elseif ($this->options->has('VIEW')) {
116 4
                    $options = AlterOperation::$VIEW_OPTIONS;
117 36
                } elseif ($this->options->has('USER')) {
118 36
                    $options = AlterOperation::$USER_OPTIONS;
119
                } elseif ($this->options->has('EVENT')) {
120
                    $options = array_merge(AlterOperation::$EVENT_OPTIONS, ['EVENT' => 0]);
121
                }
122
123 172
                $this->altered[] = AlterOperation::parse($parser, $list, $options);
124 172
                $state = 1;
125 32
            } elseif ($state === 1) {
126 32
                if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) {
127 20
                    $state = 0;
128
                }
129
            }
130
        }
131
    }
132
133
    /**
134
     * @return string
135
     */
136 12
    public function build()
137
    {
138 12
        $tmp = [];
139 12
        foreach ($this->altered as $altered) {
140 12
            $tmp[] = $altered::build($altered);
141
        }
142
143 12
        return 'ALTER ' . OptionsArray::build($this->options)
144 12
            . ' ' . Expression::build($this->table)
145 12
            . ' ' . implode(', ', $tmp);
146
    }
147
}
148