Completed
Push — master ( 802733...f10121 )
by Dan
03:16
created

AlterOperation::parse()   D

Complexity

Conditions 19
Paths 10

Size

Total Lines 107
Code Lines 48

Duplication

Lines 22
Ratio 20.56 %

Code Coverage

Tests 50
CRAP Score 19.4434

Importance

Changes 10
Bugs 2 Features 0
Metric Value
c 10
b 2
f 0
dl 22
loc 107
ccs 50
cts 56
cp 0.8929
rs 4.764
cc 19
eloc 48
nc 10
nop 3
crap 19.4434

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
/**
4
 * Parses an alter operation.
5
 *
6
 * @package    SqlParser
7
 * @subpackage Components
8
 */
9
namespace SqlParser\Components;
10
11
use SqlParser\Component;
12
use SqlParser\Parser;
13
use SqlParser\Token;
14
use SqlParser\TokensList;
15
16
/**
17
 * Parses an alter operation.
18
 *
19
 * @category   Components
20
 * @package    SqlParser
21
 * @subpackage Components
22
 * @author     Dan Ungureanu <[email protected]>
23
 * @license    http://opensource.org/licenses/GPL-2.0 GNU Public License
24
 */
25
class AlterOperation extends Component
26
{
27
28
    /**
29
     * All database options
30
     *
31
     * @var array
32
     */
33
    public static $DB_OPTIONS = array(
34
        'CHARACTER SET'             => array(1, 'var'),
35
        'CHARSET'                   => array(1, 'var'),
36
        'DEFAULT CHARACTER SET'     => array(1, 'var'),
37
        'DEFAULT CHARSET'           => array(1, 'var'),
38
        'UPGRADE'                   => array(1, 'var'),
39
        'COLLATE'                   => array(2, 'var'),
40
        'DEFAULT COLLATE'           => array(2, 'var'),
41
    );
42
43
    /**
44
     * All table options
45
     *
46
     * @var array
47
     */
48
    public static $TABLE_OPTIONS = array(
49
        'ENGINE'                        => array(1, 'var='),
50
        'AUTO_INCREMENT'                => array(1, 'var='),
51
        'AVG_ROW_LENGTH'                => array(1, 'var'),
52
        'MAX_ROWS'                      => array(1, 'var'),
53
        'ROW_FORMAT'                    => array(1, 'var'),
54
        'ADD'                           => 1,
55
        'ALTER'                         => 1,
56
        'ANALYZE'                       => 1,
57
        'CHANGE'                        => 1,
58
        'CHECK'                         => 1,
59
        'COALESCE'                      => 1,
60
        'CONVERT'                       => 1,
61
        'DISABLE'                       => 1,
62
        'DISCARD'                       => 1,
63
        'DROP'                          => 1,
64
        'ENABLE'                        => 1,
65
        'IMPORT'                        => 1,
66
        'MODIFY'                        => 1,
67
        'OPTIMIZE'                      => 1,
68
        'ORDER'                         => 1,
69
        'PARTITION'                     => 1,
70
        'REBUILD'                       => 1,
71
        'REMOVE'                        => 1,
72
        'RENAME'                        => 1,
73
        'REORGANIZE'                    => 1,
74
        'REPAIR'                        => 1,
75
        'UPGRADE'                       => 1,
76
77
        'COLUMN'                        => 2,
78
        'CONSTRAINT'                    => 2,
79
        'DEFAULT'                       => 2,
80
        'TO'                            => 2,
81
        'BY'                            => 2,
82
        'FOREIGN'                       => 2,
83
        'FULLTEXT'                      => 2,
84
        'KEY'                           => 2,
85
        'KEYS'                          => 2,
86
        'PARTITIONING'                  => 2,
87
        'PRIMARY KEY'                   => 2,
88
        'SPATIAL'                       => 2,
89
        'TABLESPACE'                    => 2,
90
        'INDEX'                         => 2,
91
    );
92
93
    /**
94
     * All view options
95
     *
96
     * @var array
97
     */
98
    public static $VIEW_OPTIONS = array(
99
        'AS'                            => 1,
100
    );
101
102
    /**
103
     * Options of this operation.
104
     *
105
     * @var OptionsArray
106
     */
107
    public $options;
108
109
    /**
110
     * The altered field.
111
     *
112
     * @var Expression
113
     */
114
    public $field;
115
116
    /**
117
     * Unparsed tokens.
118
     *
119
     * @var Token[]|string
120
     */
121
    public $unknown = array();
122
123
    /**
124
     * @param Parser     $parser  The parser that serves as context.
125
     * @param TokensList $list    The list of tokens that are being parsed.
126
     * @param array      $options Parameters for parsing.
127
     *
128
     * @return AlterOperation
129
     */
130 5
    public static function parse(Parser $parser, TokensList $list, array $options = array())
131
    {
132 5
        $ret = new AlterOperation();
133
134
        /**
135
         * Counts brackets.
136
         *
137
         * @var int $brackets
138
         */
139 5
        $brackets = 0;
140
141
        /**
142
         * The state of the parser.
143
         *
144
         * Below are the states of the parser.
145
         *
146
         *      0 ---------------------[ options ]---------------------> 1
147
         *
148
         *      1 ----------------------[ field ]----------------------> 2
149
         *
150
         *      2 -------------------------[ , ]-----------------------> 0
151
         *
152
         * @var int $state
153
         */
154 5
        $state = 0;
155
156 5
        for (; $list->idx < $list->count; ++$list->idx) {
1 ignored issue
show
Comprehensibility Bug introduced by
Loop incrementor ($list) jumbling with inner loop
Loading history...
157
            /**
158
             * Token parsed at this moment.
159
             *
160
             * @var Token $token
161
             */
162 5
            $token = $list->tokens[$list->idx];
163
164
            // End of statement.
165 5
            if ($token->type === Token::TYPE_DELIMITER) {
166 5
                break;
167
            }
168
169
            // Skipping comments.
170 5
            if ($token->type === Token::TYPE_COMMENT) {
171 1
                continue;
172
            }
173
174
            // Skipping whitespaces.
175 5
            if ($token->type === Token::TYPE_WHITESPACE) {
176 2
                if ($state === 2) {
177
                    // When parsing the unknown part, the whitespaces are
178
                    // included to not break anything.
179 2
                    $ret->unknown[] = $token;
180 2
                }
181 2
                continue;
182
            }
183
184 5
            if ($state === 0) {
185 5
                $ret->options = OptionsArray::parse($parser, $list, $options);
186
187 5
                if ($ret->options->has('AS')) {
188 View Code Duplication
                    for (; $list->idx < $list->count; ++$list->idx) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
189
                        if ($list->tokens[$list->idx]->type === Token::TYPE_DELIMITER) {
190
                            break;
191
                        }
192
                        $ret->unknown[] = $list->tokens[$list->idx];
193
                    }
194
                    break;
195
                }
196
197 5
                $state = 1;
198 5 View Code Duplication
            } elseif ($state === 1) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199 5
                $ret->field = Expression::parse(
200 5
                    $parser,
201 5
                    $list,
202
                    array(
203 5
                        'breakOnAlias' => true,
204 5
                        'parseField' => 'column',
205
                    )
206 5
                );
207 5
                if ($ret->field === null) {
208
                    // No field was read. We go back one token so the next
209
                    // iteration will parse the same token, but in state 2.
210 3
                    --$list->idx;
211 3
                }
212 5
                $state = 2;
213 5
            } elseif ($state === 2) {
214 4
                if ($token->type === Token::TYPE_OPERATOR) {
215 3
                    if ($token->value === '(') {
216 3
                        ++$brackets;
217 3
                    } elseif ($token->value === ')') {
218 3
                        --$brackets;
219 3
                    } elseif (($token->value === ',') && ($brackets === 0)) {
220 3
                        break;
221
                    }
222 3
                }
223 4
                $ret->unknown[] = $token;
224 4
            }
225 5
        }
226
227 5
        if ($ret->options->isEmpty()) {
228 1
            $parser->error(
229 1
                __('Unrecognized alter operation.'),
230 1
                $list->tokens[$list->idx]
231 1
            );
232 1
        }
233
234 5
        --$list->idx;
235 5
        return $ret;
236
    }
237
238
    /**
239
     * @param AlterOperation $component The component to be built.
240
     * @param array          $options   Parameters for building.
241
     *
242
     * @return string
243
     */
244 1
    public static function build($component, array $options = array())
245
    {
246 1
        $ret = $component->options . ' ';
247 1
        if ((isset($component->field)) && ($component->field !== '')) {
248 1
            $ret .= $component->field . ' ';
249 1
        }
250 1
        $ret .= TokensList::build($component->unknown);
251 1
        return $ret;
252
    }
253
}
254