Passed
Push — master ( 3ad940...0fb1da )
by William
03:43 queued 12s
created

CLI::getopt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * CLI interface.
4
 */
5
6
declare(strict_types=1);
7
8
namespace PhpMyAdmin\SqlParser\Utils;
9
10
use PhpMyAdmin\SqlParser\Context;
11
use PhpMyAdmin\SqlParser\Lexer;
12
use PhpMyAdmin\SqlParser\Parser;
13
use function count;
14
use function getopt;
15
use function implode;
16
use function in_array;
17
use function rtrim;
18
use function stream_get_contents;
19
use function stream_select;
20
use function var_export;
21
use const STDIN;
22
23
/**
24
 * CLI interface.
25
 */
26
class CLI
27
{
28
    /**
29
     * @param string[]|false[] $params
30
     * @param string[]         $longopts
31
     *
32
     * @return void
33
     */
34 140
    public function mergeLongOpts(&$params, &$longopts)
35
    {
36 140
        foreach ($longopts as $value) {
37 140
            $value = rtrim($value, ':');
38 140
            if (isset($params[$value])) {
39 12
                $params[$value[0]] = $params[$value];
40
            }
41
        }
42 140
    }
43
44
    /**
45
     * @return void
46
     */
47 16
    public function usageHighlight()
48
    {
49 16
        echo "Usage: highlight-query --query SQL [--format html|cli|text] [--ansi]\n";
50 16
        echo "       cat file.sql | highlight-query\n";
51 16
    }
52
53
    /**
54
     * @param string $opt
55
     * @param array  $long
56
     *
57
     * @return string[]|false[]|false
58
     */
59 4
    public function getopt($opt, $long)
60
    {
61 4
        return getopt($opt, $long);
62
    }
63
64
    /**
65
     * @return mixed|false
66
     */
67 60
    public function parseHighlight()
68
    {
69 15
        $longopts = [
70 45
            'help',
71
            'query:',
72
            'format:',
73
            'ansi',
74
        ];
75 60
        $params = $this->getopt(
76 60
            'hq:f:a',
77 15
            $longopts
78
        );
79 60
        if ($params === false) {
80 8
            return false;
81
        }
82
83 52
        $this->mergeLongOpts($params, $longopts);
84 52
        if (! isset($params['f'])) {
85 28
            $params['f'] = 'cli';
86
        }
87
88 52
        if (! in_array($params['f'], ['html', 'cli', 'text'])) {
89 8
            echo "ERROR: Invalid value for format!\n";
90
91 8
            return false;
92
        }
93
94 44
        return $params;
95
    }
96
97
    /**
98
     * @return int
99
     */
100 60
    public function runHighlight()
101
    {
102 60
        $params = $this->parseHighlight();
103 60
        if ($params === false) {
104 16
            return 1;
105
        }
106
107 44
        if (isset($params['h'])) {
108 8
            $this->usageHighlight();
109
110 8
            return 0;
111
        }
112
113 36
        if (! isset($params['q'])) {
114 20
            $stdIn = $this->readStdin();
115
116 20
            if ($stdIn) {
117 12
                $params['q'] = $stdIn;
118
            }
119
        }
120
121 36
        if (isset($params['a'])) {
122
            Context::setMode('ANSI_QUOTES');
123
        }
124 36
        if (isset($params['q'])) {
125 28
            echo Formatter::format(
126 28
                $params['q'],
127 28
                ['type' => $params['f']]
128
            );
129 28
            echo "\n";
130
131 28
            return 0;
132
        }
133
134 8
        echo "ERROR: Missing parameters!\n";
135 8
        $this->usageHighlight();
136
137 8
        return 1;
138
    }
139
140
    /**
141
     * @return void
142
     */
143 16
    public function usageLint()
144
    {
145 16
        echo "Usage: lint-query --query SQL [--ansi]\n";
146 16
        echo "       cat file.sql | lint-query\n";
147 16
    }
148
149
    /**
150
     * @return mixed
151
     */
152 52
    public function parseLint()
153
    {
154 13
        $longopts = [
155 39
            'help',
156
            'query:',
157
            'context:',
158
            'ansi',
159
        ];
160 52
        $params = $this->getopt(
161 52
            'hq:c:a',
162 13
            $longopts
163
        );
164 52
        $this->mergeLongOpts($params, $longopts);
0 ignored issues
show
Bug introduced by
It seems like $params can also be of type false; however, parameter $params of PhpMyAdmin\SqlParser\Utils\CLI::mergeLongOpts() does only seem to accept array<mixed,false>|string[], maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
        $this->mergeLongOpts(/** @scrutinizer ignore-type */ $params, $longopts);
Loading history...
165
166 52
        return $params;
167
    }
168
169
    /**
170
     * @return int
171
     */
172 52
    public function runLint()
173
    {
174 52
        $params = $this->parseLint();
175 52
        if ($params === false) {
176 8
            return 1;
177
        }
178
179 44
        if (isset($params['h'])) {
180 8
            $this->usageLint();
181
182 8
            return 0;
183
        }
184
185 36
        if (isset($params['c'])) {
186 8
            Context::load($params['c']);
187
        }
188
189 36
        if (! isset($params['q'])) {
190 20
            $stdIn = $this->readStdin();
191
192 20
            if ($stdIn) {
193 12
                $params['q'] = $stdIn;
194
            }
195
        }
196 36
        if (isset($params['a'])) {
197
            Context::setMode('ANSI_QUOTES');
198
        }
199
200 36
        if (isset($params['q'])) {
201 28
            $lexer = new Lexer($params['q'], false);
202 28
            $parser = new Parser($lexer->list);
203 28
            $errors = Error::get([$lexer, $parser]);
204 28
            if (count($errors) === 0) {
205 12
                return 0;
206
            }
207
208 16
            $output = Error::format($errors);
209 16
            echo implode("\n", $output);
210 16
            echo "\n";
211
212 16
            return 10;
213
        }
214
215 8
        echo "ERROR: Missing parameters!\n";
216 8
        $this->usageLint();
217
218 8
        return 1;
219
    }
220
221
    /**
222
     * @return void
223
     */
224 16
    public function usageTokenize()
225
    {
226 16
        echo "Usage: tokenize-query --query SQL [--ansi]\n";
227 16
        echo "       cat file.sql | tokenize-query\n";
228 16
    }
229
230
    /**
231
     * @return mixed
232
     */
233 36
    public function parseTokenize()
234
    {
235 9
        $longopts = [
236 27
            'help',
237
            'query:',
238
            'ansi',
239
        ];
240 36
        $params = $this->getopt(
241 36
            'hq:a',
242 9
            $longopts
243
        );
244 36
        $this->mergeLongOpts($params, $longopts);
0 ignored issues
show
Bug introduced by
It seems like $params can also be of type false; however, parameter $params of PhpMyAdmin\SqlParser\Utils\CLI::mergeLongOpts() does only seem to accept array<mixed,false>|string[], maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

244
        $this->mergeLongOpts(/** @scrutinizer ignore-type */ $params, $longopts);
Loading history...
245
246 36
        return $params;
247
    }
248
249
    /**
250
     * @return int
251
     */
252 36
    public function runTokenize()
253
    {
254 36
        $params = $this->parseTokenize();
255 36
        if ($params === false) {
256 8
            return 1;
257
        }
258
259 28
        if (isset($params['h'])) {
260 8
            $this->usageTokenize();
261
262 8
            return 0;
263
        }
264
265 20
        if (! isset($params['q'])) {
266 12
            $stdIn = $this->readStdin();
267
268 12
            if ($stdIn) {
269 4
                $params['q'] = $stdIn;
270
            }
271
        }
272
273 20
        if (isset($params['a'])) {
274
            Context::setMode('ANSI_QUOTES');
275
        }
276 20
        if (isset($params['q'])) {
277 12
            $lexer = new Lexer($params['q'], false);
278 12
            foreach ($lexer->list->tokens as $idx => $token) {
279 12
                echo '[TOKEN ', $idx, "]\n";
280 12
                echo 'Type = ', $token->type, "\n";
281 12
                echo 'Flags = ', $token->flags, "\n";
282 12
                echo 'Value = ';
283 12
                var_export($token->value);
284 12
                echo "\n";
285 12
                echo 'Token = ';
286 12
                var_export($token->token);
287 12
                echo "\n";
288 12
                echo "\n";
289
            }
290
291 12
            return 0;
292
        }
293
294 8
        echo "ERROR: Missing parameters!\n";
295 8
        $this->usageTokenize();
296
297 8
        return 1;
298
    }
299
300
    /**
301
     * @return string|false
302
     */
303 12
    public function readStdin()
304
    {
305 12
        $read = [STDIN];
306 12
        $write = [];
307 12
        $except = [];
308
309
        // Assume there's nothing to be read from STDIN.
310 12
        $stdin = null;
311
312
        // Try to read from STDIN.  Wait 0.2 second before timing out.
313 12
        $result = stream_select($read, $write, $except, 0, 2000);
314
315 12
        if ($result > 0) {
316 12
            $stdin = stream_get_contents(STDIN);
317
        }
318
319 12
        return $stdin;
320
    }
321
}
322