LockStatement::parse()   C
last analyzed

Complexity

Conditions 15
Paths 20

Size

Total Lines 80
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 15

Importance

Changes 0
Metric Value
cc 15
eloc 33
c 0
b 0
f 0
nc 20
nop 2
dl 0
loc 80
ccs 34
cts 34
cp 1
crap 15
rs 5.9166

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