|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* `RENAME TABLE` keyword parser. |
|
5
|
|
|
*/ |
|
6
|
|
|
|
|
7
|
|
|
namespace PhpMyAdmin\SqlParser\Components; |
|
8
|
|
|
|
|
9
|
|
|
use PhpMyAdmin\SqlParser\Component; |
|
10
|
|
|
use PhpMyAdmin\SqlParser\Parser; |
|
11
|
|
|
use PhpMyAdmin\SqlParser\Token; |
|
12
|
|
|
use PhpMyAdmin\SqlParser\TokensList; |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* `RENAME TABLE` keyword parser. |
|
16
|
|
|
* |
|
17
|
|
|
* @category Keywords |
|
18
|
|
|
* |
|
19
|
|
|
* @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ |
|
20
|
|
|
*/ |
|
21
|
|
|
class RenameOperation extends Component |
|
22
|
|
|
{ |
|
23
|
|
|
/** |
|
24
|
|
|
* The old table name. |
|
25
|
|
|
* |
|
26
|
|
|
* @var Expression |
|
27
|
|
|
*/ |
|
28
|
|
|
public $old; |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* The new table name. |
|
32
|
|
|
* |
|
33
|
|
|
* @var Expression |
|
34
|
|
|
*/ |
|
35
|
|
|
public $new; |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* @param Parser $parser the parser that serves as context |
|
39
|
|
|
* @param TokensList $list the list of tokens that are being parsed |
|
40
|
|
|
* @param array $options parameters for parsing |
|
41
|
|
|
* |
|
42
|
|
|
* @return RenameOperation[] |
|
43
|
|
|
*/ |
|
44
|
8 |
|
public static function parse(Parser $parser, TokensList $list, array $options = array()) |
|
45
|
|
|
{ |
|
46
|
8 |
|
$ret = array(); |
|
47
|
|
|
|
|
48
|
8 |
|
$expr = new self(); |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* The state of the parser. |
|
52
|
|
|
* |
|
53
|
|
|
* Below are the states of the parser. |
|
54
|
|
|
* |
|
55
|
|
|
* 0 ---------------------[ old name ]--------------------> 1 |
|
56
|
|
|
* |
|
57
|
|
|
* 1 ------------------------[ TO ]-----------------------> 2 |
|
58
|
|
|
* |
|
59
|
|
|
* 2 ---------------------[ old name ]--------------------> 3 |
|
60
|
|
|
* |
|
61
|
|
|
* 3 ------------------------[ , ]------------------------> 0 |
|
62
|
|
|
* 3 -----------------------[ else ]----------------------> (END) |
|
63
|
|
|
* |
|
64
|
|
|
* @var int |
|
65
|
|
|
*/ |
|
66
|
8 |
|
$state = 0; |
|
67
|
|
|
|
|
68
|
8 |
|
for (; $list->idx < $list->count; ++$list->idx) { |
|
69
|
|
|
/** |
|
70
|
|
|
* Token parsed at this moment. |
|
71
|
|
|
* |
|
72
|
|
|
* @var Token |
|
73
|
|
|
*/ |
|
74
|
8 |
|
$token = $list->tokens[$list->idx]; |
|
75
|
|
|
|
|
76
|
|
|
// End of statement. |
|
77
|
8 |
|
if ($token->type === Token::TYPE_DELIMITER) { |
|
78
|
6 |
|
break; |
|
79
|
|
|
} |
|
80
|
|
|
|
|
81
|
|
|
// Skipping whitespaces and comments. |
|
82
|
8 |
|
if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) { |
|
83
|
6 |
|
continue; |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
8 |
|
if ($state === 0) { |
|
87
|
8 |
|
$expr->old = Expression::parse( |
|
88
|
8 |
|
$parser, |
|
89
|
8 |
|
$list, |
|
90
|
|
|
array( |
|
91
|
8 |
|
'breakOnAlias' => true, |
|
92
|
8 |
|
'parseField' => 'table', |
|
93
|
|
|
) |
|
94
|
8 |
|
); |
|
95
|
8 |
|
if (empty($expr->old)) { |
|
96
|
1 |
|
$parser->error( |
|
97
|
1 |
|
__('The old name of the table was expected.'), |
|
98
|
|
|
$token |
|
99
|
1 |
|
); |
|
100
|
1 |
|
} |
|
101
|
8 |
|
$state = 1; |
|
102
|
8 |
|
} elseif ($state === 1) { |
|
103
|
7 |
|
if (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'TO')) { |
|
104
|
6 |
|
$state = 2; |
|
105
|
6 |
|
} else { |
|
106
|
1 |
|
$parser->error( |
|
107
|
1 |
|
__('Keyword "TO" was expected.'), |
|
108
|
|
|
$token |
|
109
|
1 |
|
); |
|
110
|
1 |
|
break; |
|
111
|
|
|
} |
|
112
|
6 |
View Code Duplication |
} elseif ($state === 2) { |
|
113
|
6 |
|
$expr->new = Expression::parse( |
|
114
|
6 |
|
$parser, |
|
115
|
6 |
|
$list, |
|
116
|
|
|
array( |
|
117
|
6 |
|
'breakOnAlias' => true, |
|
118
|
6 |
|
'parseField' => 'table', |
|
119
|
|
|
) |
|
120
|
6 |
|
); |
|
121
|
6 |
|
if (empty($expr->new)) { |
|
122
|
1 |
|
$parser->error( |
|
123
|
1 |
|
__('The new name of the table was expected.'), |
|
124
|
|
|
$token |
|
125
|
1 |
|
); |
|
126
|
1 |
|
} |
|
127
|
6 |
|
$state = 3; |
|
128
|
6 |
|
} elseif ($state === 3) { |
|
129
|
4 |
|
if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) { |
|
130
|
3 |
|
$ret[] = $expr; |
|
131
|
3 |
|
$expr = new self(); |
|
132
|
3 |
|
$state = 0; |
|
133
|
3 |
|
} else { |
|
134
|
1 |
|
break; |
|
135
|
|
|
} |
|
136
|
3 |
|
} |
|
137
|
8 |
|
} |
|
138
|
|
|
|
|
139
|
8 |
View Code Duplication |
if ($state !== 3) { |
|
140
|
2 |
|
$parser->error( |
|
141
|
2 |
|
__('A rename operation was expected.'), |
|
142
|
2 |
|
$list->tokens[$list->idx - 1] |
|
143
|
2 |
|
); |
|
144
|
2 |
|
} |
|
145
|
|
|
|
|
146
|
|
|
// Last iteration was not saved. |
|
147
|
8 |
|
if (!empty($expr->old)) { |
|
148
|
7 |
|
$ret[] = $expr; |
|
149
|
7 |
|
} |
|
150
|
|
|
|
|
151
|
8 |
|
--$list->idx; |
|
152
|
|
|
|
|
153
|
8 |
|
return $ret; |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
/** |
|
157
|
|
|
* @param RenameOperation $component the component to be built |
|
158
|
|
|
* @param array $options parameters for building |
|
159
|
|
|
* |
|
160
|
|
|
* @return string |
|
161
|
|
|
*/ |
|
162
|
1 |
View Code Duplication |
public static function build($component, array $options = array()) |
|
|
|
|
|
|
163
|
|
|
{ |
|
164
|
1 |
|
if (is_array($component)) { |
|
165
|
1 |
|
return implode(', ', $component); |
|
166
|
|
|
} else { |
|
167
|
1 |
|
return $component->old . ' TO ' . $component->new; |
|
168
|
|
|
} |
|
169
|
|
|
} |
|
170
|
|
|
} |
|
171
|
|
|
|
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.