1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
<?php
/** * `LOCK` statement. */
namespace PhpMyAdmin\SqlParser\Statements;
use PhpMyAdmin\SqlParser\Components\LockExpression; use PhpMyAdmin\SqlParser\Parser; use PhpMyAdmin\SqlParser\Statement; use PhpMyAdmin\SqlParser\Token; use PhpMyAdmin\SqlParser\TokensList;
/** * `LOCK` statement. * * @category Statements * * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class LockStatement extends Statement { /** * Tables with their Lock expressions. * * @var LockExpression[] */ public $locked = array();
/** * Whether it's a LOCK statement * if false, it's an UNLOCK statement */ public $isLock = true;
/** * @param Parser $parser the instance that requests parsing * @param TokensList $list the list of tokens to be parsed */ public function parse(Parser $parser, TokensList $list) { if ($list->tokens[$list->idx]->value === 'UNLOCK') { // this is in fact an UNLOCK statement $this->isLock = false; } ++$list->idx; // Skipping `LOCK`.
/** * The state of the parser. * * Below are the states of the parser. * * 0 ---------------- [ TABLES ] -----------------> 1 * 1 -------------- [ lock_expr ] ----------------> 2 * 2 ------------------ [ , ] --------------------> 1 * * @var int */ $state = 0;
/** * Previous parsed token */ $prevToken = null;
for (; $list->idx < $list->count; ++$list->idx) { /** * Token parsed at this moment. * * @var Token */ $token = $list->tokens[$list->idx];
// End of statement. if ($token->type === Token::TYPE_DELIMITER) { break; }
// Skipping whitespaces and comments. if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) { continue; }
if ($state === 0) { if ($token->type === Token::TYPE_KEYWORD) { if ($token->keyword !== 'TABLES') { $parser->error('Unexpected keyword.', $token); break; } $state = 1; continue; } else { $parser->error('Unexpected token.', $token); break; } } elseif ($state === 1) { if (!$this->isLock) { // UNLOCK statement should not have any more tokens $parser->error('Unexpected token.', $token); break; } $this->locked[] = LockExpression::parse($parser, $list); $state = 2; } elseif ($state === 2) { if ($token->value === ',') { // move over to parsing next lock expression $state = 1; } }
$prevToken = $token; }
if ($state !== 2 && $prevToken != null) { $parser->error('Unexpected end of LOCK statement.', $prevToken); } }
/** * @return string */ public function build() { return trim(($this->isLock ? 'LOCK' : 'UNLOCK') . ' TABLES ' . LockExpression::build($this->locked)); } }
|