Passed
Push — master ( a6d95a...18308b )
by Maurício
05:14 queued 01:50
created

Limit   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 20
eloc 39
dl 0
loc 105
ccs 38
cts 38
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C parse() 0 64 17
A build() 0 3 1
A __toString() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Components;
6
7
use PhpMyAdmin\SqlParser\Component;
8
use PhpMyAdmin\SqlParser\Parser;
9
use PhpMyAdmin\SqlParser\Token;
10
use PhpMyAdmin\SqlParser\TokensList;
11
use PhpMyAdmin\SqlParser\TokenType;
12
13
/**
14
 * `LIMIT` keyword parser.
15
 */
16
final class Limit implements Component
17
{
18
    /**
19
     * The number of rows skipped.
20
     *
21
     * @var int|string
22
     */
23
    public $offset;
24
25
    /**
26
     * The number of rows to be returned.
27
     *
28
     * @var int|string
29
     */
30
    public $rowCount;
31
32
    /**
33
     * @param int|string $rowCount the row count
34
     * @param int|string $offset   the offset
35
     */
36 66
    public function __construct($rowCount = 0, $offset = 0)
37
    {
38 66
        $this->rowCount = $rowCount;
39 66
        $this->offset = $offset;
40
    }
41
42
    /**
43
     * @param Parser               $parser  the parser that serves as context
44
     * @param TokensList           $list    the list of tokens that are being parsed
45
     * @param array<string, mixed> $options parameters for parsing
46
     */
47 60
    public static function parse(Parser $parser, TokensList $list, array $options = []): Limit
48
    {
49 60
        $ret = new static();
50
51 60
        $offset = false;
52
53 60
        for (; $list->idx < $list->count; ++$list->idx) {
54
            /**
55
             * Token parsed at this moment.
56
             */
57 60
            $token = $list->tokens[$list->idx];
58
59
            // End of statement.
60 60
            if ($token->type === TokenType::Delimiter) {
61 50
                break;
62
            }
63
64
            // Skipping whitespaces and comments.
65 60
            if (($token->type === TokenType::Whitespace) || ($token->type === TokenType::Comment)) {
66 60
                continue;
67
            }
68
69 60
            if (($token->type === TokenType::Keyword) && ($token->flags & Token::FLAG_KEYWORD_RESERVED)) {
70 6
                break;
71
            }
72
73 60
            if ($token->type === TokenType::Keyword && $token->keyword === 'OFFSET') {
74 10
                if ($offset) {
75 2
                    $parser->error('An offset was expected.', $token);
76
                }
77
78 10
                $offset = true;
79 10
                continue;
80
            }
81
82 60
            if (($token->type === TokenType::Operator) && ($token->value === ',')) {
83 46
                $ret->offset = $ret->rowCount;
84 46
                $ret->rowCount = 0;
85 46
                continue;
86
            }
87
88
            // Skip if not a number or a bind parameter (?)
89
            if (
90 60
                ! ($token->type === TokenType::Number
91 60
                    || ($token->type === TokenType::Symbol && ($token->flags & Token::FLAG_SYMBOL_PARAMETER)))
92
            ) {
93 6
                break;
94
            }
95
96 60
            if ($offset) {
97 8
                $ret->offset = $token->value;
98 8
                $offset = false;
99
            } else {
100 60
                $ret->rowCount = $token->value;
101
            }
102
        }
103
104 60
        if ($offset) {
0 ignored issues
show
introduced by
The condition $offset is always false.
Loading history...
105 2
            $parser->error('An offset was expected.', $list->tokens[$list->idx - 1]);
106
        }
107
108 60
        --$list->idx;
109
110 60
        return $ret;
111
    }
112
113 28
    public function build(): string
114
    {
115 28
        return $this->offset . ', ' . $this->rowCount;
116
    }
117
118 2
    public function __toString(): string
119
    {
120 2
        return $this->build();
121
    }
122
}
123