Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like SqlFormatter often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SqlFormatter, and based on these observations, apply Extract Interface, too.
1 | <?php namespace EvolutionCMS\Support\Formatter; |
||
20 | class SqlFormatter |
||
21 | { |
||
22 | /** |
||
23 | * KEYWORDS1. |
||
24 | * |
||
25 | * @var string |
||
26 | */ |
||
27 | const KEYWORDS1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE'; |
||
28 | |||
29 | /** |
||
30 | * KEYWORDS2. |
||
31 | * |
||
32 | * @var string |
||
33 | */ |
||
34 | const KEYWORDS2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|[RI]?LIKE|REGEXP|TRUE|FALSE'; |
||
35 | |||
36 | // Constants for token types |
||
37 | const TOKEN_TYPE_WHITESPACE = 0; |
||
38 | const TOKEN_TYPE_WORD = 1; |
||
39 | const TOKEN_TYPE_QUOTE = 2; |
||
40 | const TOKEN_TYPE_BACKTICK_QUOTE = 3; |
||
41 | const TOKEN_TYPE_RESERVED = 4; |
||
42 | const TOKEN_TYPE_RESERVED_TOPLEVEL = 5; |
||
43 | const TOKEN_TYPE_RESERVED_NEWLINE = 6; |
||
44 | const TOKEN_TYPE_BOUNDARY = 7; |
||
45 | const TOKEN_TYPE_COMMENT = 8; |
||
46 | const TOKEN_TYPE_BLOCK_COMMENT = 9; |
||
47 | const TOKEN_TYPE_NUMBER = 10; |
||
48 | const TOKEN_TYPE_ERROR = 11; |
||
49 | const TOKEN_TYPE_VARIABLE = 12; |
||
50 | |||
51 | // Constants for different components of a token |
||
52 | const TOKEN_TYPE = 0; |
||
53 | const TOKEN_VALUE = 1; |
||
54 | |||
55 | // Reserved words (for syntax highlighting) |
||
56 | protected static $reserved = array( |
||
57 | 'ACCESSIBLE', |
||
58 | 'ACTION', |
||
59 | 'AGAINST', |
||
60 | 'AGGREGATE', |
||
61 | 'ALGORITHM', |
||
62 | 'ALL', |
||
63 | 'ALTER', |
||
64 | 'ANALYSE', |
||
65 | 'ANALYZE', |
||
66 | 'AS', |
||
67 | 'ASC', |
||
68 | 'AUTOCOMMIT', |
||
69 | 'AUTO_INCREMENT', |
||
70 | 'BACKUP', |
||
71 | 'BEGIN', |
||
72 | 'BETWEEN', |
||
73 | 'BINLOG', |
||
74 | 'BOTH', |
||
75 | 'CASCADE', |
||
76 | 'CASE', |
||
77 | 'CHANGE', |
||
78 | 'CHANGED', |
||
79 | 'CHARACTER SET', |
||
80 | 'CHARSET', |
||
81 | 'CHECK', |
||
82 | 'CHECKSUM', |
||
83 | 'COLLATE', |
||
84 | 'COLLATION', |
||
85 | 'COLUMN', |
||
86 | 'COLUMNS', |
||
87 | 'COMMENT', |
||
88 | 'COMMIT', |
||
89 | 'COMMITTED', |
||
90 | 'COMPRESSED', |
||
91 | 'CONCURRENT', |
||
92 | 'CONSTRAINT', |
||
93 | 'CONTAINS', |
||
94 | 'CONVERT', |
||
95 | 'CREATE', |
||
96 | 'CROSS', |
||
97 | 'CURRENT_TIMESTAMP', |
||
98 | 'DATABASE', |
||
99 | 'DATABASES', |
||
100 | 'DAY', |
||
101 | 'DAY_HOUR', |
||
102 | 'DAY_MINUTE', |
||
103 | 'DAY_SECOND', |
||
104 | 'DEFAULT', |
||
105 | 'DEFINER', |
||
106 | 'DELAYED', |
||
107 | 'DELETE', |
||
108 | 'DESC', |
||
109 | 'DESCRIBE', |
||
110 | 'DETERMINISTIC', |
||
111 | 'DISTINCT', |
||
112 | 'DISTINCTROW', |
||
113 | 'DIV', |
||
114 | 'DO', |
||
115 | 'DUMPFILE', |
||
116 | 'DUPLICATE', |
||
117 | 'DYNAMIC', |
||
118 | 'ELSE', |
||
119 | 'ENCLOSED', |
||
120 | 'END', |
||
121 | 'ENGINE', |
||
122 | 'ENGINE_TYPE', |
||
123 | 'ENGINES', |
||
124 | 'ESCAPE', |
||
125 | 'ESCAPED', |
||
126 | 'EVENTS', |
||
127 | 'EXEC', |
||
128 | 'EXECUTE', |
||
129 | 'EXISTS', |
||
130 | 'EXPLAIN', |
||
131 | 'EXTENDED', |
||
132 | 'FAST', |
||
133 | 'FIELDS', |
||
134 | 'FILE', |
||
135 | 'FIRST', |
||
136 | 'FIXED', |
||
137 | 'FLUSH', |
||
138 | 'FOR', |
||
139 | 'FORCE', |
||
140 | 'FOREIGN', |
||
141 | 'FULL', |
||
142 | 'FULLTEXT', |
||
143 | 'FUNCTION', |
||
144 | 'GLOBAL', |
||
145 | 'GRANT', |
||
146 | 'GRANTS', |
||
147 | 'GROUP_CONCAT', |
||
148 | 'HEAP', |
||
149 | 'HIGH_PRIORITY', |
||
150 | 'HOSTS', |
||
151 | 'HOUR', |
||
152 | 'HOUR_MINUTE', |
||
153 | 'HOUR_SECOND', |
||
154 | 'IDENTIFIED', |
||
155 | 'IF', |
||
156 | 'IFNULL', |
||
157 | 'IGNORE', |
||
158 | 'IN', |
||
159 | 'INDEX', |
||
160 | 'INDEXES', |
||
161 | 'INFILE', |
||
162 | 'INSERT', |
||
163 | 'INSERT_ID', |
||
164 | 'INSERT_METHOD', |
||
165 | 'INTERVAL', |
||
166 | 'INTO', |
||
167 | 'INVOKER', |
||
168 | 'IS', |
||
169 | 'ISOLATION', |
||
170 | 'KEY', |
||
171 | 'KEYS', |
||
172 | 'KILL', |
||
173 | 'LAST_INSERT_ID', |
||
174 | 'LEADING', |
||
175 | 'LEVEL', |
||
176 | 'LIKE', |
||
177 | 'LINEAR', |
||
178 | 'LINES', |
||
179 | 'LOAD', |
||
180 | 'LOCAL', |
||
181 | 'LOCK', |
||
182 | 'LOCKS', |
||
183 | 'LOGS', |
||
184 | 'LOW_PRIORITY', |
||
185 | 'MARIA', |
||
186 | 'MASTER', |
||
187 | 'MASTER_CONNECT_RETRY', |
||
188 | 'MASTER_HOST', |
||
189 | 'MASTER_LOG_FILE', |
||
190 | 'MATCH', |
||
191 | 'MAX_CONNECTIONS_PER_HOUR', |
||
192 | 'MAX_QUERIES_PER_HOUR', |
||
193 | 'MAX_ROWS', |
||
194 | 'MAX_UPDATES_PER_HOUR', |
||
195 | 'MAX_USER_CONNECTIONS', |
||
196 | 'MEDIUM', |
||
197 | 'MERGE', |
||
198 | 'MINUTE', |
||
199 | 'MINUTE_SECOND', |
||
200 | 'MIN_ROWS', |
||
201 | 'MODE', |
||
202 | 'MODIFY', |
||
203 | 'MONTH', |
||
204 | 'MRG_MYISAM', |
||
205 | 'MYISAM', |
||
206 | 'NAMES', |
||
207 | 'NATURAL', |
||
208 | 'NOT', |
||
209 | 'NOW()', |
||
210 | 'NULL', |
||
211 | 'OFFSET', |
||
212 | 'ON', |
||
213 | 'OPEN', |
||
214 | 'OPTIMIZE', |
||
215 | 'OPTION', |
||
216 | 'OPTIONALLY', |
||
217 | 'ON UPDATE', |
||
218 | 'ON DELETE', |
||
219 | 'OUTFILE', |
||
220 | 'PACK_KEYS', |
||
221 | 'PAGE', |
||
222 | 'PARTIAL', |
||
223 | 'PARTITION', |
||
224 | 'PARTITIONS', |
||
225 | 'PASSWORD', |
||
226 | 'PRIMARY', |
||
227 | 'PRIVILEGES', |
||
228 | 'PROCEDURE', |
||
229 | 'PROCESS', |
||
230 | 'PROCESSLIST', |
||
231 | 'PURGE', |
||
232 | 'QUICK', |
||
233 | 'RANGE', |
||
234 | 'RAID0', |
||
235 | 'RAID_CHUNKS', |
||
236 | 'RAID_CHUNKSIZE', |
||
237 | 'RAID_TYPE', |
||
238 | 'READ', |
||
239 | 'READ_ONLY', |
||
240 | 'READ_WRITE', |
||
241 | 'REFERENCES', |
||
242 | 'REGEXP', |
||
243 | 'RELOAD', |
||
244 | 'RENAME', |
||
245 | 'REPAIR', |
||
246 | 'REPEATABLE', |
||
247 | 'REPLACE', |
||
248 | 'REPLICATION', |
||
249 | 'RESET', |
||
250 | 'RESTORE', |
||
251 | 'RESTRICT', |
||
252 | 'RETURN', |
||
253 | 'RETURNS', |
||
254 | 'REVOKE', |
||
255 | 'RLIKE', |
||
256 | 'ROLLBACK', |
||
257 | 'ROW', |
||
258 | 'ROWS', |
||
259 | 'ROW_FORMAT', |
||
260 | 'SECOND', |
||
261 | 'SECURITY', |
||
262 | 'SEPARATOR', |
||
263 | 'SERIALIZABLE', |
||
264 | 'SESSION', |
||
265 | 'SHARE', |
||
266 | 'SHOW', |
||
267 | 'SHUTDOWN', |
||
268 | 'SLAVE', |
||
269 | 'SONAME', |
||
270 | 'SOUNDS', |
||
271 | 'SQL', |
||
272 | 'SQL_AUTO_IS_NULL', |
||
273 | 'SQL_BIG_RESULT', |
||
274 | 'SQL_BIG_SELECTS', |
||
275 | 'SQL_BIG_TABLES', |
||
276 | 'SQL_BUFFER_RESULT', |
||
277 | 'SQL_CALC_FOUND_ROWS', |
||
278 | 'SQL_LOG_BIN', |
||
279 | 'SQL_LOG_OFF', |
||
280 | 'SQL_LOG_UPDATE', |
||
281 | 'SQL_LOW_PRIORITY_UPDATES', |
||
282 | 'SQL_MAX_JOIN_SIZE', |
||
283 | 'SQL_QUOTE_SHOW_CREATE', |
||
284 | 'SQL_SAFE_UPDATES', |
||
285 | 'SQL_SELECT_LIMIT', |
||
286 | 'SQL_SLAVE_SKIP_COUNTER', |
||
287 | 'SQL_SMALL_RESULT', |
||
288 | 'SQL_WARNINGS', |
||
289 | 'SQL_CACHE', |
||
290 | 'SQL_NO_CACHE', |
||
291 | 'START', |
||
292 | 'STARTING', |
||
293 | 'STATUS', |
||
294 | 'STOP', |
||
295 | 'STORAGE', |
||
296 | 'STRAIGHT_JOIN', |
||
297 | 'STRING', |
||
298 | 'STRIPED', |
||
299 | 'SUPER', |
||
300 | 'TABLE', |
||
301 | 'TABLES', |
||
302 | 'TEMPORARY', |
||
303 | 'TERMINATED', |
||
304 | 'THEN', |
||
305 | 'TO', |
||
306 | 'TRAILING', |
||
307 | 'TRANSACTIONAL', |
||
308 | 'TRUE', |
||
309 | 'TRUNCATE', |
||
310 | 'TYPE', |
||
311 | 'TYPES', |
||
312 | 'UNCOMMITTED', |
||
313 | 'UNIQUE', |
||
314 | 'UNLOCK', |
||
315 | 'UNSIGNED', |
||
316 | 'USAGE', |
||
317 | 'USE', |
||
318 | 'USING', |
||
319 | 'VARIABLES', |
||
320 | 'VIEW', |
||
321 | 'WHEN', |
||
322 | 'WITH', |
||
323 | 'WORK', |
||
324 | 'WRITE', |
||
325 | 'YEAR_MONTH' |
||
326 | ); |
||
327 | |||
328 | // For SQL formatting |
||
329 | // These keywords will all be on their own line |
||
330 | /** |
||
331 | * @var array |
||
332 | */ |
||
333 | protected static $reserved_toplevel = array( |
||
334 | 'SELECT', |
||
335 | 'FROM', |
||
336 | 'WHERE', |
||
337 | 'SET', |
||
338 | 'ORDER BY', |
||
339 | 'GROUP BY', |
||
340 | 'LIMIT', |
||
341 | 'DROP', |
||
342 | 'VALUES', |
||
343 | 'UPDATE', |
||
344 | 'HAVING', |
||
345 | 'ADD', |
||
346 | 'AFTER', |
||
347 | 'ALTER TABLE', |
||
348 | 'DELETE FROM', |
||
349 | 'UNION ALL', |
||
350 | 'UNION', |
||
351 | 'EXCEPT', |
||
352 | 'INTERSECT' |
||
353 | ); |
||
354 | |||
355 | /** |
||
356 | * @var array |
||
357 | */ |
||
358 | protected static $reserved_newline = array( |
||
359 | 'LEFT OUTER JOIN', |
||
360 | 'RIGHT OUTER JOIN', |
||
361 | 'LEFT JOIN', |
||
362 | 'RIGHT JOIN', |
||
363 | 'OUTER JOIN', |
||
364 | 'INNER JOIN', |
||
365 | 'JOIN', |
||
366 | 'XOR', |
||
367 | 'OR', |
||
368 | 'AND' |
||
369 | ); |
||
370 | |||
371 | /** |
||
372 | * @var array |
||
373 | */ |
||
374 | protected static $functions = array( |
||
375 | 'ABS', |
||
376 | 'ACOS', |
||
377 | 'ADDDATE', |
||
378 | 'ADDTIME', |
||
379 | 'AES_DECRYPT', |
||
380 | 'AES_ENCRYPT', |
||
381 | 'AREA', |
||
382 | 'ASBINARY', |
||
383 | 'ASCII', |
||
384 | 'ASIN', |
||
385 | 'ASTEXT', |
||
386 | 'ATAN', |
||
387 | 'ATAN2', |
||
388 | 'AVG', |
||
389 | 'BDMPOLYFROMTEXT', |
||
390 | 'BDMPOLYFROMWKB', |
||
391 | 'BDPOLYFROMTEXT', |
||
392 | 'BDPOLYFROMWKB', |
||
393 | 'BENCHMARK', |
||
394 | 'BIN', |
||
395 | 'BIT_AND', |
||
396 | 'BIT_COUNT', |
||
397 | 'BIT_LENGTH', |
||
398 | 'BIT_OR', |
||
399 | 'BIT_XOR', |
||
400 | 'BOUNDARY', |
||
401 | 'BUFFER', |
||
402 | 'CAST', |
||
403 | 'CEIL', |
||
404 | 'CEILING', |
||
405 | 'CENTROID', |
||
406 | 'CHAR', |
||
407 | 'CHARACTER_LENGTH', |
||
408 | 'CHARSET', |
||
409 | 'CHAR_LENGTH', |
||
410 | 'COALESCE', |
||
411 | 'COERCIBILITY', |
||
412 | 'COLLATION', |
||
413 | 'COMPRESS', |
||
414 | 'CONCAT', |
||
415 | 'CONCAT_WS', |
||
416 | 'CONNECTION_ID', |
||
417 | 'CONTAINS', |
||
418 | 'CONV', |
||
419 | 'CONVERT', |
||
420 | 'CONVERT_TZ', |
||
421 | 'CONVEXHULL', |
||
422 | 'COS', |
||
423 | 'COT', |
||
424 | 'COUNT', |
||
425 | 'CRC32', |
||
426 | 'CROSSES', |
||
427 | 'CURDATE', |
||
428 | 'CURRENT_DATE', |
||
429 | 'CURRENT_TIME', |
||
430 | 'CURRENT_TIMESTAMP', |
||
431 | 'CURRENT_USER', |
||
432 | 'CURTIME', |
||
433 | 'DATABASE', |
||
434 | 'DATE', |
||
435 | 'DATEDIFF', |
||
436 | 'DATE_ADD', |
||
437 | 'DATE_DIFF', |
||
438 | 'DATE_FORMAT', |
||
439 | 'DATE_SUB', |
||
440 | 'DAY', |
||
441 | 'DAYNAME', |
||
442 | 'DAYOFMONTH', |
||
443 | 'DAYOFWEEK', |
||
444 | 'DAYOFYEAR', |
||
445 | 'DECODE', |
||
446 | 'DEFAULT', |
||
447 | 'DEGREES', |
||
448 | 'DES_DECRYPT', |
||
449 | 'DES_ENCRYPT', |
||
450 | 'DIFFERENCE', |
||
451 | 'DIMENSION', |
||
452 | 'DISJOINT', |
||
453 | 'DISTANCE', |
||
454 | 'ELT', |
||
455 | 'ENCODE', |
||
456 | 'ENCRYPT', |
||
457 | 'ENDPOINT', |
||
458 | 'ENVELOPE', |
||
459 | 'EQUALS', |
||
460 | 'EXP', |
||
461 | 'EXPORT_SET', |
||
462 | 'EXTERIORRING', |
||
463 | 'EXTRACT', |
||
464 | 'EXTRACTVALUE', |
||
465 | 'FIELD', |
||
466 | 'FIND_IN_SET', |
||
467 | 'FLOOR', |
||
468 | 'FORMAT', |
||
469 | 'FOUND_ROWS', |
||
470 | 'FROM_DAYS', |
||
471 | 'FROM_UNIXTIME', |
||
472 | 'GEOMCOLLFROMTEXT', |
||
473 | 'GEOMCOLLFROMWKB', |
||
474 | 'GEOMETRYCOLLECTION', |
||
475 | 'GEOMETRYCOLLECTIONFROMTEXT', |
||
476 | 'GEOMETRYCOLLECTIONFROMWKB', |
||
477 | 'GEOMETRYFROMTEXT', |
||
478 | 'GEOMETRYFROMWKB', |
||
479 | 'GEOMETRYN', |
||
480 | 'GEOMETRYTYPE', |
||
481 | 'GEOMFROMTEXT', |
||
482 | 'GEOMFROMWKB', |
||
483 | 'GET_FORMAT', |
||
484 | 'GET_LOCK', |
||
485 | 'GLENGTH', |
||
486 | 'GREATEST', |
||
487 | 'GROUP_CONCAT', |
||
488 | 'GROUP_UNIQUE_USERS', |
||
489 | 'HEX', |
||
490 | 'HOUR', |
||
491 | 'IF', |
||
492 | 'IFNULL', |
||
493 | 'INET_ATON', |
||
494 | 'INET_NTOA', |
||
495 | 'INSERT', |
||
496 | 'INSTR', |
||
497 | 'INTERIORRINGN', |
||
498 | 'INTERSECTION', |
||
499 | 'INTERSECTS', |
||
500 | 'INTERVAL', |
||
501 | 'ISCLOSED', |
||
502 | 'ISEMPTY', |
||
503 | 'ISNULL', |
||
504 | 'ISRING', |
||
505 | 'ISSIMPLE', |
||
506 | 'IS_FREE_LOCK', |
||
507 | 'IS_USED_LOCK', |
||
508 | 'LAST_DAY', |
||
509 | 'LAST_INSERT_ID', |
||
510 | 'LCASE', |
||
511 | 'LEAST', |
||
512 | 'LEFT', |
||
513 | 'LENGTH', |
||
514 | 'LINEFROMTEXT', |
||
515 | 'LINEFROMWKB', |
||
516 | 'LINESTRING', |
||
517 | 'LINESTRINGFROMTEXT', |
||
518 | 'LINESTRINGFROMWKB', |
||
519 | 'LN', |
||
520 | 'LOAD_FILE', |
||
521 | 'LOCALTIME', |
||
522 | 'LOCALTIMESTAMP', |
||
523 | 'LOCATE', |
||
524 | 'LOG', |
||
525 | 'LOG10', |
||
526 | 'LOG2', |
||
527 | 'LOWER', |
||
528 | 'LPAD', |
||
529 | 'LTRIM', |
||
530 | 'MAKEDATE', |
||
531 | 'MAKETIME', |
||
532 | 'MAKE_SET', |
||
533 | 'MASTER_POS_WAIT', |
||
534 | 'MAX', |
||
535 | 'MBRCONTAINS', |
||
536 | 'MBRDISJOINT', |
||
537 | 'MBREQUAL', |
||
538 | 'MBRINTERSECTS', |
||
539 | 'MBROVERLAPS', |
||
540 | 'MBRTOUCHES', |
||
541 | 'MBRWITHIN', |
||
542 | 'MD5', |
||
543 | 'MICROSECOND', |
||
544 | 'MID', |
||
545 | 'MIN', |
||
546 | 'MINUTE', |
||
547 | 'MLINEFROMTEXT', |
||
548 | 'MLINEFROMWKB', |
||
549 | 'MOD', |
||
550 | 'MONTH', |
||
551 | 'MONTHNAME', |
||
552 | 'MPOINTFROMTEXT', |
||
553 | 'MPOINTFROMWKB', |
||
554 | 'MPOLYFROMTEXT', |
||
555 | 'MPOLYFROMWKB', |
||
556 | 'MULTILINESTRING', |
||
557 | 'MULTILINESTRINGFROMTEXT', |
||
558 | 'MULTILINESTRINGFROMWKB', |
||
559 | 'MULTIPOINT', |
||
560 | 'MULTIPOINTFROMTEXT', |
||
561 | 'MULTIPOINTFROMWKB', |
||
562 | 'MULTIPOLYGON', |
||
563 | 'MULTIPOLYGONFROMTEXT', |
||
564 | 'MULTIPOLYGONFROMWKB', |
||
565 | 'NAME_CONST', |
||
566 | 'NULLIF', |
||
567 | 'NUMGEOMETRIES', |
||
568 | 'NUMINTERIORRINGS', |
||
569 | 'NUMPOINTS', |
||
570 | 'OCT', |
||
571 | 'OCTET_LENGTH', |
||
572 | 'OLD_PASSWORD', |
||
573 | 'ORD', |
||
574 | 'OVERLAPS', |
||
575 | 'PASSWORD', |
||
576 | 'PERIOD_ADD', |
||
577 | 'PERIOD_DIFF', |
||
578 | 'PI', |
||
579 | 'POINT', |
||
580 | 'POINTFROMTEXT', |
||
581 | 'POINTFROMWKB', |
||
582 | 'POINTN', |
||
583 | 'POINTONSURFACE', |
||
584 | 'POLYFROMTEXT', |
||
585 | 'POLYFROMWKB', |
||
586 | 'POLYGON', |
||
587 | 'POLYGONFROMTEXT', |
||
588 | 'POLYGONFROMWKB', |
||
589 | 'POSITION', |
||
590 | 'POW', |
||
591 | 'POWER', |
||
592 | 'QUARTER', |
||
593 | 'QUOTE', |
||
594 | 'RADIANS', |
||
595 | 'RAND', |
||
596 | 'RELATED', |
||
597 | 'RELEASE_LOCK', |
||
598 | 'REPEAT', |
||
599 | 'REPLACE', |
||
600 | 'REVERSE', |
||
601 | 'RIGHT', |
||
602 | 'ROUND', |
||
603 | 'ROW_COUNT', |
||
604 | 'RPAD', |
||
605 | 'RTRIM', |
||
606 | 'SCHEMA', |
||
607 | 'SECOND', |
||
608 | 'SEC_TO_TIME', |
||
609 | 'SESSION_USER', |
||
610 | 'SHA', |
||
611 | 'SHA1', |
||
612 | 'SIGN', |
||
613 | 'SIN', |
||
614 | 'SLEEP', |
||
615 | 'SOUNDEX', |
||
616 | 'SPACE', |
||
617 | 'SQRT', |
||
618 | 'SRID', |
||
619 | 'STARTPOINT', |
||
620 | 'STD', |
||
621 | 'STDDEV', |
||
622 | 'STDDEV_POP', |
||
623 | 'STDDEV_SAMP', |
||
624 | 'STRCMP', |
||
625 | 'STR_TO_DATE', |
||
626 | 'SUBDATE', |
||
627 | 'SUBSTR', |
||
628 | 'SUBSTRING', |
||
629 | 'SUBSTRING_INDEX', |
||
630 | 'SUBTIME', |
||
631 | 'SUM', |
||
632 | 'SYMDIFFERENCE', |
||
633 | 'SYSDATE', |
||
634 | 'SYSTEM_USER', |
||
635 | 'TAN', |
||
636 | 'TIME', |
||
637 | 'TIMEDIFF', |
||
638 | 'TIMESTAMP', |
||
639 | 'TIMESTAMPADD', |
||
640 | 'TIMESTAMPDIFF', |
||
641 | 'TIME_FORMAT', |
||
642 | 'TIME_TO_SEC', |
||
643 | 'TOUCHES', |
||
644 | 'TO_DAYS', |
||
645 | 'TRIM', |
||
646 | 'TRUNCATE', |
||
647 | 'UCASE', |
||
648 | 'UNCOMPRESS', |
||
649 | 'UNCOMPRESSED_LENGTH', |
||
650 | 'UNHEX', |
||
651 | 'UNIQUE_USERS', |
||
652 | 'UNIX_TIMESTAMP', |
||
653 | 'UPDATEXML', |
||
654 | 'UPPER', |
||
655 | 'USER', |
||
656 | 'UTC_DATE', |
||
657 | 'UTC_TIME', |
||
658 | 'UTC_TIMESTAMP', |
||
659 | 'UUID', |
||
660 | 'VARIANCE', |
||
661 | 'VAR_POP', |
||
662 | 'VAR_SAMP', |
||
663 | 'VERSION', |
||
664 | 'WEEK', |
||
665 | 'WEEKDAY', |
||
666 | 'WEEKOFYEAR', |
||
667 | 'WITHIN', |
||
668 | 'X', |
||
669 | 'Y', |
||
670 | 'YEAR', |
||
671 | 'YEARWEEK' |
||
672 | ); |
||
673 | |||
674 | // Punctuation that can be used as a boundary between other tokens |
||
675 | protected static $boundaries = array( |
||
676 | ',', |
||
677 | ';', |
||
678 | ':', |
||
679 | ')', |
||
680 | '(', |
||
681 | '.', |
||
682 | '=', |
||
683 | '<', |
||
684 | '>', |
||
685 | '+', |
||
686 | '-', |
||
687 | '*', |
||
688 | '/', |
||
689 | '!', |
||
690 | '^', |
||
691 | '%', |
||
692 | '|', |
||
693 | '&', |
||
694 | '#' |
||
695 | ); |
||
696 | |||
697 | // For HTML syntax highlighting |
||
698 | // Styles applied to different token types |
||
699 | public static $quote_attributes = 'style="color: blue;"'; |
||
700 | public static $backtick_quote_attributes = 'style="color: purple;"'; |
||
701 | public static $reserved_attributes = 'style="font-weight:bold;"'; |
||
702 | public static $boundary_attributes = ''; |
||
703 | public static $number_attributes = 'style="color: green;"'; |
||
704 | public static $word_attributes = 'style="color: #333;"'; |
||
705 | public static $error_attributes = 'style="background-color: red;"'; |
||
706 | public static $comment_attributes = 'style="color: #aaa;"'; |
||
707 | public static $variable_attributes = 'style="color: orange;"'; |
||
708 | public static $pre_attributes = 'style="color: black; background-color: white;"'; |
||
709 | |||
710 | // Boolean - whether or not the current environment is the CLI |
||
711 | // This affects the type of syntax highlighting |
||
712 | // If not defined, it will be determined automatically |
||
713 | public static $cli; |
||
714 | |||
715 | // For CLI syntax highlighting |
||
716 | public static $cli_quote = "\x1b[34;1m"; |
||
717 | public static $cli_backtick_quote = "\x1b[35;1m"; |
||
718 | public static $cli_reserved = "\x1b[37m"; |
||
719 | public static $cli_boundary = ""; |
||
720 | public static $cli_number = "\x1b[32;1m"; |
||
721 | public static $cli_word = ""; |
||
722 | public static $cli_error = "\x1b[31;1;7m"; |
||
723 | public static $cli_comment = "\x1b[30;1m"; |
||
724 | public static $cli_functions = "\x1b[37m"; |
||
725 | public static $cli_variable = "\x1b[36;1m"; |
||
726 | |||
727 | // The tab character to use when formatting SQL |
||
728 | public static $tab = ' '; |
||
729 | |||
730 | // This flag tells us if queries need to be enclosed in <pre> tags |
||
731 | public static $use_pre = true; |
||
732 | |||
733 | // This flag tells us if SqlFormatted has been initialized |
||
734 | protected static $init; |
||
735 | |||
736 | // Regular expressions for tokenizing |
||
737 | protected static $regex_boundaries; |
||
738 | protected static $regex_reserved; |
||
739 | protected static $regex_reserved_newline; |
||
740 | protected static $regex_reserved_toplevel; |
||
741 | protected static $regex_function; |
||
742 | |||
743 | // Cache variables |
||
744 | // Only tokens shorter than this size will be cached. Somewhere between 10 and 20 seems to work well for most cases. |
||
745 | public static $max_cachekey_size = 15; |
||
746 | protected static $token_cache = array(); |
||
747 | protected static $cache_hits = 0; |
||
748 | protected static $cache_misses = 0; |
||
749 | |||
750 | /** |
||
751 | * Get stats about the token cache |
||
752 | * @return Array An array containing the keys 'hits', 'misses', 'entries', and 'size' in bytes |
||
|
|||
753 | */ |
||
754 | public static function getCacheStats() |
||
763 | |||
764 | /** |
||
765 | * Stuff that only needs to be done once. Builds regular expressions and sorts the reserved words. |
||
766 | */ |
||
767 | protected static function init() |
||
791 | |||
792 | /** |
||
793 | * Return the next token and token type in a SQL string. |
||
794 | * Quoted strings, comments, reserved words, whitespace, and punctuation are all their own tokens. |
||
795 | * |
||
796 | * @param String $string The SQL string |
||
797 | * @param array $previous The result of the previous getNextToken() call |
||
798 | * |
||
799 | * @return Array An associative array containing the type and value of the token. |
||
800 | */ |
||
801 | protected static function getNextToken($string, $previous = null) |
||
932 | |||
933 | /** |
||
934 | * @param $string |
||
935 | * @return null |
||
936 | */ |
||
937 | protected static function getQuotedString($string) |
||
953 | |||
954 | /** |
||
955 | * Takes a SQL string and breaks it into tokens. |
||
956 | * Each token is an associative array with type and value. |
||
957 | * |
||
958 | * @param String $string The SQL string |
||
959 | * |
||
960 | * @return Array An array of tokens. |
||
961 | */ |
||
962 | protected static function tokenize($string) |
||
1023 | |||
1024 | /** |
||
1025 | * Format the whitespace in a SQL string to make it easier to read. |
||
1026 | * |
||
1027 | * @param String $string The SQL string |
||
1028 | * @param boolean $highlight If true, syntax highlighting will also be performed |
||
1029 | * |
||
1030 | * @return String The SQL string with HTML styles and formatting wrapped in a <pre> tag |
||
1031 | */ |
||
1032 | public static function format($string, $highlight = true) |
||
1317 | |||
1318 | /** |
||
1319 | * Add syntax highlighting to a SQL string |
||
1320 | * |
||
1321 | * @param String $string The SQL string |
||
1322 | * |
||
1323 | * @return String The SQL string with HTML styles applied |
||
1324 | */ |
||
1325 | public static function highlight($string) |
||
1337 | |||
1338 | /** |
||
1339 | * Split a SQL string into multiple queries. |
||
1340 | * Uses ";" as a query delimiter. |
||
1341 | * |
||
1342 | * @param String $string The SQL string |
||
1343 | * |
||
1344 | * @return Array An array of individual query strings without trailing semicolons |
||
1345 | */ |
||
1346 | public static function splitQuery($string) |
||
1379 | |||
1380 | /** |
||
1381 | * Remove all comments from a SQL string |
||
1382 | * |
||
1383 | * @param String $string The SQL string |
||
1384 | * |
||
1385 | * @return String The SQL string without comments |
||
1386 | */ |
||
1387 | public static function removeComments($string) |
||
1405 | |||
1406 | /** |
||
1407 | * Compress a query by collapsing white space and removing comments |
||
1408 | * |
||
1409 | * @param String $string The SQL string |
||
1410 | * |
||
1411 | * @return String The SQL string without comments |
||
1412 | */ |
||
1413 | public static function compress($string) |
||
1447 | |||
1448 | /** |
||
1449 | * Highlights a token depending on its type. |
||
1450 | * |
||
1451 | * @param Array $token An associative array containing type and value. |
||
1452 | * |
||
1453 | * @return String HTML code of the highlighted token. |
||
1454 | */ |
||
1455 | protected static function highlightToken($token) |
||
1493 | |||
1494 | /** |
||
1495 | * Highlights a quoted string |
||
1496 | * |
||
1497 | * @param String $value The token's value |
||
1498 | * |
||
1499 | * @return String HTML code of the highlighted token. |
||
1500 | */ |
||
1501 | protected static function highlightQuote($value) |
||
1509 | |||
1510 | /** |
||
1511 | * Highlights a backtick quoted string |
||
1512 | * |
||
1513 | * @param String $value The token's value |
||
1514 | * |
||
1515 | * @return String HTML code of the highlighted token. |
||
1516 | */ |
||
1517 | protected static function highlightBacktickQuote($value) |
||
1525 | |||
1526 | /** |
||
1527 | * Highlights a reserved word |
||
1528 | * |
||
1529 | * @param String $value The token's value |
||
1530 | * |
||
1531 | * @return String HTML code of the highlighted token. |
||
1532 | */ |
||
1533 | protected static function highlightReservedWord($value) |
||
1541 | |||
1542 | /** |
||
1543 | * Highlights a boundary token |
||
1544 | * |
||
1545 | * @param String $value The token's value |
||
1546 | * |
||
1547 | * @return String HTML code of the highlighted token. |
||
1548 | */ |
||
1549 | protected static function highlightBoundary($value) |
||
1561 | |||
1562 | /** |
||
1563 | * Highlights a number |
||
1564 | * |
||
1565 | * @param String $value The token's value |
||
1566 | * |
||
1567 | * @return String HTML code of the highlighted token. |
||
1568 | */ |
||
1569 | protected static function highlightNumber($value) |
||
1577 | |||
1578 | /** |
||
1579 | * Highlights an error |
||
1580 | * |
||
1581 | * @param String $value The token's value |
||
1582 | * |
||
1583 | * @return String HTML code of the highlighted token. |
||
1584 | */ |
||
1585 | protected static function highlightError($value) |
||
1593 | |||
1594 | /** |
||
1595 | * Highlights a comment |
||
1596 | * |
||
1597 | * @param String $value The token's value |
||
1598 | * |
||
1599 | * @return String HTML code of the highlighted token. |
||
1600 | */ |
||
1601 | protected static function highlightComment($value) |
||
1609 | |||
1610 | /** |
||
1611 | * Highlights a word token |
||
1612 | * |
||
1613 | * @param String $value The token's value |
||
1614 | * |
||
1615 | * @return String HTML code of the highlighted token. |
||
1616 | */ |
||
1617 | protected static function highlightWord($value) |
||
1625 | |||
1626 | /** |
||
1627 | * Highlights a variable token |
||
1628 | * |
||
1629 | * @param String $value The token's value |
||
1630 | * |
||
1631 | * @return String HTML code of the highlighted token. |
||
1632 | */ |
||
1633 | protected static function highlightVariable($value) |
||
1641 | |||
1642 | /** |
||
1643 | * Helper function for building regular expressions for reserved words and boundary characters |
||
1644 | * |
||
1645 | * @param String $a The string to be quoted |
||
1646 | * |
||
1647 | * @return String The quoted string |
||
1648 | */ |
||
1649 | private static function quote_regex($a) |
||
1653 | |||
1654 | /** |
||
1655 | * Helper function for building string output |
||
1656 | * |
||
1657 | * @param String $string The string to be quoted |
||
1658 | * |
||
1659 | * @return String The quoted string |
||
1660 | */ |
||
1661 | private static function output($string) |
||
1674 | |||
1675 | /** |
||
1676 | * @return bool |
||
1677 | */ |
||
1678 | private static function is_cli() |
||
1686 | |||
1687 | /** |
||
1688 | * Returns syntax highlighted SQL command. |
||
1689 | * |
||
1690 | * |
||
1691 | * @param string $sql |
||
1692 | * @param array $bindings |
||
1693 | * @param \PDO $pdo |
||
1694 | * @return string |
||
1695 | */ |
||
1696 | public static function prepare($sql, array $bindings = [], PDO $pdo = null) |
||
1758 | |||
1759 | /** |
||
1760 | * perform quer analysis hint. |
||
1761 | * |
||
1762 | * @param string $sql |
||
1763 | * @param string $version |
||
1764 | * @param float $driver |
||
1765 | * @return array |
||
1766 | */ |
||
1767 | public static function performQueryAnalysis($sql, $version = null, $driver = null) |
||
1800 | |||
1801 | /** |
||
1802 | * explain sql. |
||
1803 | * |
||
1804 | * @param PDO $pdo |
||
1805 | * @param string $sql |
||
1806 | * @param array $bindings |
||
1807 | * @return array |
||
1808 | */ |
||
1809 | public static function explain(PDO $pdo, $sql, $bindings = []) |
||
1820 | } |
||
1821 |
This check looks for the generic type
array
as a return type and suggests a more specific type. This type is inferred from the actual code.