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

AlterOperation   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 229
Duplicated Lines 9.61 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 90.48%

Importance

Changes 14
Bugs 6 Features 2
Metric Value
wmc 22
c 14
b 6
f 2
lcom 1
cbo 6
dl 22
loc 229
ccs 57
cts 63
cp 0.9048
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
D parse() 22 107 19
A build() 0 9 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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