This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * php-sql-creator.php. |
||
5 | * |
||
6 | * A pure PHP SQL creator, which generates SQL from the output of SQLParser. |
||
7 | * |
||
8 | * Copyright (c) 2012, André Rothe <[email protected], [email protected]> |
||
9 | * |
||
10 | * All rights reserved. |
||
11 | * |
||
12 | * Redistribution and use in source and binary forms, with or without modification, |
||
13 | * are permitted provided that the following conditions are met: |
||
14 | * |
||
15 | * * Redistributions of source code must retain the above copyright notice, |
||
16 | * this list of conditions and the following disclaimer. |
||
17 | * * Redistributions in binary form must reproduce the above copyright notice, |
||
18 | * this list of conditions and the following disclaimer in the documentation |
||
19 | * and/or other materials provided with the distribution. |
||
20 | * |
||
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY |
||
22 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||
23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
||
24 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
||
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
||
27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
||
29 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
||
30 | * DAMAGE. |
||
31 | */ |
||
32 | namespace SQLParser; |
||
33 | |||
34 | class PHPSQLCreator |
||
35 | { |
||
36 | public function __construct($parsed = false) |
||
37 | { |
||
38 | if ($parsed) { |
||
39 | $this->create($parsed); |
||
40 | } |
||
41 | } |
||
42 | |||
43 | public function create($parsed) |
||
44 | { |
||
45 | $k = key($parsed); |
||
46 | switch ($k) { |
||
47 | |||
48 | case 'UNION': |
||
49 | case 'UNION ALL': |
||
50 | throw new UnsupportedFeatureException($k); |
||
51 | break; |
||
0 ignored issues
–
show
|
|||
52 | case 'SELECT': |
||
53 | $this->created = $this->processSelectStatement($parsed); |
||
0 ignored issues
–
show
The property
created does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
54 | break; |
||
55 | case 'INSERT': |
||
56 | $this->created = $this->processInsertStatement($parsed); |
||
57 | break; |
||
58 | case 'DELETE': |
||
59 | $this->created = $this->processDeleteStatement($parsed); |
||
60 | break; |
||
61 | case 'UPDATE': |
||
62 | $this->created = $this->processUpdateStatement($parsed); |
||
63 | break; |
||
64 | default: |
||
65 | throw new UnsupportedFeatureException($k); |
||
66 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
67 | } |
||
68 | |||
69 | return $this->created; |
||
70 | } |
||
71 | |||
72 | protected function processSelectStatement($parsed) |
||
73 | { |
||
74 | $sql = $this->processSELECT($parsed['SELECT']).' '.$this->processFROM($parsed['FROM']); |
||
75 | if (isset($parsed['WHERE'])) { |
||
76 | $sql .= ' '.$this->processWHERE($parsed['WHERE']); |
||
77 | } |
||
78 | if (isset($parsed['GROUP'])) { |
||
79 | $sql .= ' '.$this->processGROUP($parsed['GROUP']); |
||
80 | } |
||
81 | if (isset($parsed['ORDER'])) { |
||
82 | $sql .= ' '.$this->processORDER($parsed['ORDER']); |
||
83 | } |
||
84 | if (isset($parsed['LIMIT'])) { |
||
85 | $sql .= ' '.$this->processLIMIT($parsed['LIMIT']); |
||
86 | } |
||
87 | |||
88 | return $sql; |
||
89 | } |
||
90 | |||
91 | protected function processInsertStatement($parsed) |
||
92 | { |
||
93 | return $this->processINSERT($parsed['INSERT']).' '.$this->processVALUES($parsed['VALUES']); |
||
94 | # TODO: subquery? |
||
95 | } |
||
96 | |||
97 | protected function processDeleteStatement($parsed) |
||
98 | { |
||
99 | return $this->processDELETE($parsed['DELETE']).' '.$this->processFROM($parsed['FROM']).' ' |
||
100 | .$this->processWHERE($parsed['WHERE']); |
||
101 | } |
||
102 | |||
103 | protected function processUpdateStatement($parsed) |
||
104 | { |
||
105 | $sql = $this->processUPDATE($parsed['UPDATE']).' '.$this->processSET($parsed['SET']); |
||
106 | if (isset($parsed['WHERE'])) { |
||
107 | $sql .= ' '.$this->processWHERE($parsed['WHERE']); |
||
108 | } |
||
109 | |||
110 | return $sql; |
||
111 | } |
||
112 | |||
113 | protected function processDELETE($parsed) |
||
114 | { |
||
115 | $sql = 'DELETE'; |
||
116 | foreach ($parsed['TABLES'] as $k => $v) { |
||
117 | $sql .= $v.','; |
||
118 | } |
||
119 | |||
120 | return substr($sql, 0, -1); |
||
121 | } |
||
122 | |||
123 | View Code Duplication | protected function processSELECT($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
124 | { |
||
125 | $sql = ''; |
||
126 | foreach ($parsed as $k => $v) { |
||
127 | $len = strlen($sql); |
||
128 | $sql .= $this->processColRef($v); |
||
129 | $sql .= $this->processSelectExpression($v); |
||
130 | $sql .= $this->processFunction($v); |
||
131 | $sql .= $this->processConstant($v); |
||
132 | |||
133 | if ($len == strlen($sql)) { |
||
134 | throw new UnableToCreateSQLException('SELECT', $k, $v, 'expr_type'); |
||
135 | } |
||
136 | |||
137 | $sql .= ','; |
||
138 | } |
||
139 | $sql = substr($sql, 0, -1); |
||
140 | |||
141 | return 'SELECT '.$sql; |
||
142 | } |
||
143 | |||
144 | View Code Duplication | protected function processFROM($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
145 | { |
||
146 | $sql = ''; |
||
147 | foreach ($parsed as $k => $v) { |
||
148 | $len = strlen($sql); |
||
149 | $sql .= $this->processTable($v, $k); |
||
150 | $sql .= $this->processTableExpression($v, $k); |
||
151 | $sql .= $this->processSubquery($v, $k); |
||
152 | |||
153 | if ($len == strlen($sql)) { |
||
154 | throw new UnableToCreateSQLException('FROM', $k, $v, 'expr_type'); |
||
155 | } |
||
156 | |||
157 | $sql .= ' '; |
||
158 | } |
||
159 | |||
160 | return 'FROM '.substr($sql, 0, -1); |
||
161 | } |
||
162 | |||
163 | protected function processORDER($parsed) |
||
164 | { |
||
165 | $sql = ''; |
||
166 | foreach ($parsed as $k => $v) { |
||
167 | $len = strlen($sql); |
||
168 | $sql .= $this->processOrderByAlias($v); |
||
169 | $sql .= $this->processColRef($v); |
||
170 | |||
171 | if ($len == strlen($sql)) { |
||
172 | throw new UnableToCreateSQLException('ORDER', $k, $v, 'expr_type'); |
||
173 | } |
||
174 | |||
175 | $sql .= ','; |
||
176 | } |
||
177 | $sql = substr($sql, 0, -1); |
||
178 | |||
179 | return 'ORDER BY '.$sql; |
||
180 | } |
||
181 | |||
182 | protected function processLIMIT($parsed) |
||
183 | { |
||
184 | $sql = ($parsed['offset'] ? $parsed['offset'].', ' : '').$parsed['rowcount']; |
||
185 | if ($sql === '') { |
||
186 | throw new UnableToCreateSQLException('LIMIT', 'rowcount', $parsed, 'rowcount'); |
||
187 | } |
||
188 | |||
189 | return 'LIMIT '.$sql; |
||
190 | } |
||
191 | |||
192 | View Code Duplication | protected function processGROUP($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
193 | { |
||
194 | $sql = ''; |
||
195 | foreach ($parsed as $k => $v) { |
||
196 | $len = strlen($sql); |
||
197 | $sql .= $this->processColRef($v); |
||
198 | |||
199 | if ($len == strlen($sql)) { |
||
200 | throw new UnableToCreateSQLException('GROUP', $k, $v, 'expr_type'); |
||
201 | } |
||
202 | |||
203 | $sql .= ','; |
||
204 | } |
||
205 | $sql = substr($sql, 0, -1); |
||
206 | |||
207 | return 'GROUP BY '.$sql; |
||
208 | } |
||
209 | |||
210 | protected function processRecord($parsed) |
||
211 | { |
||
212 | if ($parsed['expr_type'] !== ExpressionType::RECORD) { |
||
213 | return ''; |
||
214 | } |
||
215 | $sql = ''; |
||
216 | View Code Duplication | foreach ($parsed['data'] as $k => $v) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
217 | $len = strlen($sql); |
||
218 | $sql .= $this->processConstant($v); |
||
219 | $sql .= $this->processFunction($v); |
||
220 | $sql .= $this->processOperator($v); |
||
221 | |||
222 | if ($len == strlen($sql)) { |
||
223 | throw new UnableToCreateSQLException(ExpressionType::RECORD, $k, $v, 'expr_type'); |
||
224 | } |
||
225 | |||
226 | $sql .= ','; |
||
227 | } |
||
228 | $sql = substr($sql, 0, -1); |
||
229 | |||
230 | return '('.$sql.')'; |
||
231 | } |
||
232 | |||
233 | View Code Duplication | protected function processVALUES($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
234 | { |
||
235 | $sql = ''; |
||
236 | foreach ($parsed as $k => $v) { |
||
237 | $len = strlen($sql); |
||
238 | $sql .= $this->processRecord($v); |
||
239 | |||
240 | if ($len == strlen($sql)) { |
||
241 | throw new UnableToCreateSQLException('VALUES', $k, $v, 'expr_type'); |
||
242 | } |
||
243 | |||
244 | $sql .= ','; |
||
245 | } |
||
246 | $sql = substr($sql, 0, -1); |
||
247 | |||
248 | return 'VALUES '.$sql; |
||
249 | } |
||
250 | |||
251 | protected function processINSERT($parsed) |
||
252 | { |
||
253 | $sql = 'INSERT INTO '.$parsed['table']; |
||
254 | |||
255 | if ($parsed['columns'] === false) { |
||
256 | return $sql; |
||
257 | } |
||
258 | |||
259 | $columns = ''; |
||
260 | foreach ($parsed['columns'] as $k => $v) { |
||
261 | $len = strlen($columns); |
||
262 | $columns .= $this->processColRef($v); |
||
263 | |||
264 | if ($len == strlen($columns)) { |
||
265 | throw new UnableToCreateSQLException('INSERT[columns]', $k, $v, 'expr_type'); |
||
266 | } |
||
267 | |||
268 | $columns .= ','; |
||
269 | } |
||
270 | |||
271 | if ($columns !== '') { |
||
272 | $columns = ' ('.substr($columns, 0, -1).')'; |
||
273 | } |
||
274 | |||
275 | $sql .= $columns; |
||
276 | |||
277 | return $sql; |
||
278 | } |
||
279 | |||
280 | protected function processUPDATE($parsed) |
||
281 | { |
||
282 | return 'UPDATE '.$parsed[0]['table']; |
||
283 | } |
||
284 | |||
285 | protected function processSetExpression($parsed) |
||
286 | { |
||
287 | if ($parsed['expr_type'] !== ExpressionType::EXPRESSION) { |
||
288 | return ''; |
||
289 | } |
||
290 | $sql = ''; |
||
291 | foreach ($parsed['sub_tree'] as $k => $v) { |
||
292 | $len = strlen($sql); |
||
293 | $sql .= $this->processColRef($v); |
||
294 | $sql .= $this->processConstant($v); |
||
295 | $sql .= $this->processOperator($v); |
||
296 | $sql .= $this->processFunction($v); |
||
297 | |||
298 | if ($len == strlen($sql)) { |
||
299 | throw new UnableToCreateSQLException('SET expression subtree', $k, $v, 'expr_type'); |
||
300 | } |
||
301 | |||
302 | $sql .= ' '; |
||
303 | } |
||
304 | |||
305 | $sql = substr($sql, 0, -1); |
||
306 | |||
307 | return $sql; |
||
308 | } |
||
309 | |||
310 | View Code Duplication | protected function processSET($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
311 | { |
||
312 | $sql = ''; |
||
313 | foreach ($parsed as $k => $v) { |
||
314 | $len = strlen($sql); |
||
315 | $sql .= $this->processSetExpression($v); |
||
316 | |||
317 | if ($len == strlen($sql)) { |
||
318 | throw new UnableToCreateSQLException('SET', $k, $v, 'expr_type'); |
||
319 | } |
||
320 | |||
321 | $sql .= ','; |
||
322 | } |
||
323 | |||
324 | return 'SET '.substr($sql, 0, -1); |
||
325 | } |
||
326 | |||
327 | protected function processWHERE($parsed) |
||
328 | { |
||
329 | $sql = 'WHERE '; |
||
330 | foreach ($parsed as $k => $v) { |
||
331 | $len = strlen($sql); |
||
332 | |||
333 | $sql .= $this->processOperator($v); |
||
334 | $sql .= $this->processConstant($v); |
||
335 | $sql .= $this->processColRef($v); |
||
336 | $sql .= $this->processSubquery($v); |
||
337 | $sql .= $this->processInList($v); |
||
338 | $sql .= $this->processFunction($v); |
||
339 | $sql .= $this->processWhereExpression($v); |
||
340 | $sql .= $this->processWhereBracketExpression($v); |
||
341 | |||
342 | if (strlen($sql) == $len) { |
||
343 | throw new UnableToCreateSQLException('WHERE', $k, $v, 'expr_type'); |
||
344 | } |
||
345 | |||
346 | $sql .= ' '; |
||
347 | } |
||
348 | |||
349 | return substr($sql, 0, -1); |
||
350 | } |
||
351 | |||
352 | View Code Duplication | protected function processWhereExpression($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
353 | { |
||
354 | if ($parsed['expr_type'] !== ExpressionType::EXPRESSION) { |
||
355 | return ''; |
||
356 | } |
||
357 | $sql = ''; |
||
358 | foreach ($parsed['sub_tree'] as $k => $v) { |
||
359 | $len = strlen($sql); |
||
360 | $sql .= $this->processColRef($v); |
||
361 | $sql .= $this->processConstant($v); |
||
362 | $sql .= $this->processOperator($v); |
||
363 | $sql .= $this->processInList($v); |
||
364 | $sql .= $this->processFunction($v); |
||
365 | $sql .= $this->processWhereExpression($v); |
||
366 | $sql .= $this->processWhereBracketExpression($v); |
||
367 | |||
368 | if ($len == strlen($sql)) { |
||
369 | throw new UnableToCreateSQLException('WHERE expression subtree', $k, $v, 'expr_type'); |
||
370 | } |
||
371 | |||
372 | $sql .= ' '; |
||
373 | } |
||
374 | |||
375 | $sql = substr($sql, 0, -1); |
||
376 | |||
377 | return $sql; |
||
378 | } |
||
379 | |||
380 | View Code Duplication | protected function processWhereBracketExpression($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
381 | { |
||
382 | if ($parsed['expr_type'] !== ExpressionType::BRACKET_EXPRESSION) { |
||
383 | return ''; |
||
384 | } |
||
385 | $sql = ''; |
||
386 | foreach ($parsed['sub_tree'] as $k => $v) { |
||
387 | $len = strlen($sql); |
||
388 | $sql .= $this->processColRef($v); |
||
389 | $sql .= $this->processConstant($v); |
||
390 | $sql .= $this->processOperator($v); |
||
391 | $sql .= $this->processInList($v); |
||
392 | $sql .= $this->processFunction($v); |
||
393 | $sql .= $this->processWhereExpression($v); |
||
394 | $sql .= $this->processWhereBracketExpression($v); |
||
395 | |||
396 | if ($len == strlen($sql)) { |
||
397 | throw new UnableToCreateSQLException('WHERE expression subtree', $k, $v, 'expr_type'); |
||
398 | } |
||
399 | |||
400 | $sql .= ' '; |
||
401 | } |
||
402 | |||
403 | $sql = '('.substr($sql, 0, -1).')'; |
||
404 | |||
405 | return $sql; |
||
406 | } |
||
407 | |||
408 | protected function processOrderByAlias($parsed) |
||
409 | { |
||
410 | if ($parsed['expr_type'] !== ExpressionType::ALIAS) { |
||
411 | return ''; |
||
412 | } |
||
413 | |||
414 | return $parsed['base_expr'].$this->processDirection($parsed['direction']); |
||
415 | } |
||
416 | |||
417 | protected function processLimitRowCount($key, $value) |
||
418 | { |
||
419 | if ($key != 'rowcount') { |
||
420 | return ''; |
||
421 | } |
||
422 | |||
423 | return $value; |
||
424 | } |
||
425 | |||
426 | protected function processLimitOffset($key, $value) |
||
427 | { |
||
428 | if ($key !== 'offset') { |
||
429 | return ''; |
||
430 | } |
||
431 | |||
432 | return $value; |
||
433 | } |
||
434 | |||
435 | protected function processFunction($parsed) |
||
436 | { |
||
437 | if (($parsed['expr_type'] !== ExpressionType::AGGREGATE_FUNCTION) |
||
438 | && ($parsed['expr_type'] !== ExpressionType::SIMPLE_FUNCTION)) { |
||
439 | return ''; |
||
440 | } |
||
441 | |||
442 | if ($parsed['sub_tree'] === false) { |
||
443 | return $parsed['base_expr'].'()'; |
||
444 | } |
||
445 | |||
446 | $sql = ''; |
||
447 | foreach ($parsed['sub_tree'] as $k => $v) { |
||
448 | $len = strlen($sql); |
||
449 | $sql .= $this->processFunction($v); |
||
450 | $sql .= $this->processConstant($v); |
||
451 | $sql .= $this->processColRef($v); |
||
452 | $sql .= $this->processReserved($v); |
||
453 | |||
454 | if ($len == strlen($sql)) { |
||
455 | throw new UnableToCreateSQLException('function subtree', $k, $v, 'expr_type'); |
||
456 | } |
||
457 | |||
458 | $sql .= ($this->isReserved($v) ? ' ' : ','); |
||
459 | } |
||
460 | |||
461 | return $parsed['base_expr'].'('.substr($sql, 0, -1).')'; |
||
462 | } |
||
463 | |||
464 | protected function processSelectExpression($parsed) |
||
465 | { |
||
466 | if ($parsed['expr_type'] !== ExpressionType::EXPRESSION) { |
||
467 | return ''; |
||
468 | } |
||
469 | $sql = $this->processSubTree($parsed, ' '); |
||
470 | $sql .= $this->processAlias($parsed['alias']); |
||
471 | |||
472 | return $sql; |
||
473 | } |
||
474 | |||
475 | View Code Duplication | protected function processSelectBracketExpression($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
476 | { |
||
477 | if ($parsed['expr_type'] !== ExpressionType::BRACKET_EXPRESSION) { |
||
478 | return ''; |
||
479 | } |
||
480 | $sql = $this->processSubTree($parsed, ' '); |
||
481 | $sql = '('.$sql.')'; |
||
482 | |||
483 | return $sql; |
||
484 | } |
||
485 | |||
486 | protected function processSubTree($parsed, $delim = ' ') |
||
487 | { |
||
488 | if ($parsed['sub_tree'] === '') { |
||
489 | return ''; |
||
490 | } |
||
491 | $sql = ''; |
||
492 | foreach ($parsed['sub_tree'] as $k => $v) { |
||
493 | $len = strlen($sql); |
||
494 | $sql .= $this->processFunction($v); |
||
495 | $sql .= $this->processOperator($v); |
||
496 | $sql .= $this->processConstant($v); |
||
497 | $sql .= $this->processSubQuery($v); |
||
498 | $sql .= $this->processSelectBracketExpression($v); |
||
499 | |||
500 | if ($len == strlen($sql)) { |
||
501 | throw new UnableToCreateSQLException('expression subtree', $k, $v, 'expr_type'); |
||
502 | } |
||
503 | |||
504 | $sql .= $delim; |
||
505 | } |
||
506 | |||
507 | return substr($sql, 0, -1); |
||
508 | } |
||
509 | |||
510 | protected function processRefClause($parsed) |
||
511 | { |
||
512 | if ($parsed === false) { |
||
513 | return ''; |
||
514 | } |
||
515 | |||
516 | $sql = ''; |
||
517 | View Code Duplication | foreach ($parsed as $k => $v) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
518 | $len = strlen($sql); |
||
519 | $sql .= $this->processColRef($v); |
||
520 | $sql .= $this->processOperator($v); |
||
521 | $sql .= $this->processConstant($v); |
||
522 | |||
523 | if ($len == strlen($sql)) { |
||
524 | throw new UnableToCreateSQLException('expression ref_clause', $k, $v, 'expr_type'); |
||
525 | } |
||
526 | |||
527 | $sql .= ' '; |
||
528 | } |
||
529 | |||
530 | return '('.substr($sql, 0, -1).')'; |
||
531 | } |
||
532 | |||
533 | protected function processAlias($parsed) |
||
534 | { |
||
535 | if ($parsed === false) { |
||
536 | return ''; |
||
537 | } |
||
538 | $sql = ''; |
||
539 | if ($parsed['as']) { |
||
540 | $sql .= ' as'; |
||
541 | } |
||
542 | $sql .= ' '.$parsed['name']; |
||
543 | |||
544 | return $sql; |
||
545 | } |
||
546 | |||
547 | protected function processJoin($parsed) |
||
548 | { |
||
549 | if ($parsed === 'CROSS') { |
||
550 | return ','; |
||
551 | } |
||
552 | if ($parsed === 'JOIN') { |
||
553 | return 'INNER JOIN'; |
||
554 | } |
||
555 | if ($parsed === 'LEFT') { |
||
556 | return 'LEFT JOIN'; |
||
557 | } |
||
558 | if ($parsed === 'RIGHT') { |
||
559 | return 'RIGHT JOIN'; |
||
560 | } |
||
561 | // TODO: add more |
||
562 | throw new UnsupportedFeatureException($parsed); |
||
563 | } |
||
564 | |||
565 | protected function processRefType($parsed) |
||
566 | { |
||
567 | if ($parsed === false) { |
||
568 | return ''; |
||
569 | } |
||
570 | if ($parsed === 'ON') { |
||
571 | return ' ON '; |
||
572 | } |
||
573 | if ($parsed === 'USING') { |
||
574 | return ' USING '; |
||
575 | } |
||
576 | // TODO: add more |
||
577 | throw new UnsupportedFeatureException($parsed); |
||
578 | } |
||
579 | |||
580 | protected function processTable($parsed, $index) |
||
581 | { |
||
582 | if ($parsed['expr_type'] !== ExpressionType::TABLE) { |
||
583 | return ''; |
||
584 | } |
||
585 | |||
586 | $sql = $parsed['table']; |
||
587 | $sql .= $this->processAlias($parsed['alias']); |
||
588 | |||
589 | if ($index !== 0) { |
||
590 | $sql = $this->processJoin($parsed['join_type']).' '.$sql; |
||
591 | $sql .= $this->processRefType($parsed['ref_type']); |
||
592 | $sql .= $this->processRefClause($parsed['ref_clause']); |
||
593 | } |
||
594 | |||
595 | return $sql; |
||
596 | } |
||
597 | |||
598 | View Code Duplication | protected function processTableExpression($parsed, $index) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
599 | { |
||
600 | if ($parsed['expr_type'] !== ExpressionType::TABLE_EXPRESSION) { |
||
601 | return ''; |
||
602 | } |
||
603 | $sql = substr($this->processFROM($parsed['sub_tree']), 5); // remove FROM keyword |
||
604 | $sql = '('.$sql.')'; |
||
605 | $sql .= $this->processAlias($parsed['alias']); |
||
606 | |||
607 | if ($index !== 0) { |
||
608 | $sql = $this->processJoin($parsed['join_type']).' '.$sql; |
||
609 | $sql .= $this->processRefType($parsed['ref_type']); |
||
610 | $sql .= $this->processRefClause($parsed['ref_clause']); |
||
611 | } |
||
612 | |||
613 | return $sql; |
||
614 | } |
||
615 | |||
616 | View Code Duplication | protected function processSubQuery($parsed, $index = 0) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
617 | { |
||
618 | if ($parsed['expr_type'] !== ExpressionType::SUBQUERY) { |
||
619 | return ''; |
||
620 | } |
||
621 | |||
622 | $sql = $this->processSelectStatement($parsed['sub_tree']); |
||
623 | $sql = '('.$sql.')'; |
||
624 | |||
625 | if (isset($parsed['alias'])) { |
||
626 | $sql .= $this->processAlias($parsed['alias']); |
||
627 | } |
||
628 | |||
629 | if ($index !== 0) { |
||
630 | $sql = $this->processJoin($parsed['join_type']).' '.$sql; |
||
631 | $sql .= $this->processRefType($parsed['ref_type']); |
||
632 | $sql .= $this->processRefClause($parsed['ref_clause']); |
||
633 | } |
||
634 | |||
635 | return $sql; |
||
636 | } |
||
637 | |||
638 | protected function processOperator($parsed) |
||
639 | { |
||
640 | if ($parsed['expr_type'] !== ExpressionType::OPERATOR) { |
||
641 | return ''; |
||
642 | } |
||
643 | |||
644 | return $parsed['base_expr']; |
||
645 | } |
||
646 | |||
647 | protected function processColRef($parsed) |
||
648 | { |
||
649 | if ($parsed['expr_type'] !== ExpressionType::COLREF) { |
||
650 | return ''; |
||
651 | } |
||
652 | $sql = $parsed['base_expr']; |
||
653 | if (isset($parsed['alias'])) { |
||
654 | $sql .= $this->processAlias($parsed['alias']); |
||
655 | } |
||
656 | if (isset($parsed['direction'])) { |
||
657 | $sql .= $this->processDirection($parsed['direction']); |
||
658 | } |
||
659 | |||
660 | return $sql; |
||
661 | } |
||
662 | |||
663 | protected function processDirection($parsed) |
||
664 | { |
||
665 | $sql = ($parsed ? ' '.$parsed : ''); |
||
666 | |||
667 | return $sql; |
||
668 | } |
||
669 | |||
670 | protected function processReserved($parsed) |
||
671 | { |
||
672 | if (!$this->isReserved($parsed)) { |
||
673 | return ''; |
||
674 | } |
||
675 | |||
676 | return $parsed['base_expr']; |
||
677 | } |
||
678 | |||
679 | protected function isReserved($parsed) |
||
680 | { |
||
681 | return ($parsed['expr_type'] === ExpressionType::RESERVED); |
||
682 | } |
||
683 | |||
684 | protected function processConstant($parsed) |
||
685 | { |
||
686 | if ($parsed['expr_type'] !== ExpressionType::CONSTANT) { |
||
687 | return ''; |
||
688 | } |
||
689 | |||
690 | return $parsed['base_expr']; |
||
691 | } |
||
692 | |||
693 | View Code Duplication | protected function processInList($parsed) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
694 | { |
||
695 | if ($parsed['expr_type'] !== ExpressionType::IN_LIST) { |
||
696 | return ''; |
||
697 | } |
||
698 | $sql = $this->processSubTree($parsed, ','); |
||
699 | |||
700 | return '('.$sql.')'; |
||
701 | } |
||
702 | } // END CLASS |
||
703 | |||
704 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.