Complex classes like AbstractQueryBuilder 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 AbstractQueryBuilder, and based on these observations, apply Extract Interface, too.
1 | <?php declare(strict_types=1); |
||
24 | abstract class AbstractQueryBuilder { |
||
25 | |||
26 | // -------------------------------------------------------------------------- |
||
27 | // ! Constants |
||
28 | // -------------------------------------------------------------------------- |
||
29 | |||
30 | const KEY = 0; |
||
31 | const VALUE = 1; |
||
32 | const BOTH = 2; |
||
33 | |||
34 | // -------------------------------------------------------------------------- |
||
35 | // ! SQL Clause Strings |
||
36 | // -------------------------------------------------------------------------- |
||
37 | |||
38 | /** |
||
39 | * Compiled 'select' clause |
||
40 | * @var string |
||
41 | */ |
||
42 | protected $selectString = ''; |
||
43 | |||
44 | /** |
||
45 | * Compiled 'from' clause |
||
46 | * @var string |
||
47 | */ |
||
48 | protected $fromString = ''; |
||
49 | |||
50 | /** |
||
51 | * Compiled arguments for insert / update |
||
52 | * @var string |
||
53 | */ |
||
54 | protected $setString; |
||
55 | |||
56 | /** |
||
57 | * Order by clause |
||
58 | * @var string |
||
59 | */ |
||
60 | protected $orderString; |
||
61 | |||
62 | /** |
||
63 | * Group by clause |
||
64 | * @var string |
||
65 | */ |
||
66 | protected $groupString; |
||
67 | |||
68 | // -------------------------------------------------------------------------- |
||
69 | // ! SQL Clause Arrays |
||
70 | // -------------------------------------------------------------------------- |
||
71 | |||
72 | /** |
||
73 | * Keys for insert/update statement |
||
74 | * @var array |
||
75 | */ |
||
76 | protected $setArrayKeys = []; |
||
77 | |||
78 | /** |
||
79 | * Key/val pairs for order by clause |
||
80 | * @var array |
||
81 | */ |
||
82 | protected $orderArray = []; |
||
83 | |||
84 | /** |
||
85 | * Key/val pairs for group by clause |
||
86 | * @var array |
||
87 | */ |
||
88 | protected $groupArray = []; |
||
89 | |||
90 | // -------------------------------------------------------------------------- |
||
91 | // ! Other Class vars |
||
92 | // -------------------------------------------------------------------------- |
||
93 | |||
94 | /** |
||
95 | * Values to apply to prepared statements |
||
96 | * @var array |
||
97 | */ |
||
98 | protected $values = []; |
||
99 | |||
100 | /** |
||
101 | * Values to apply to where clauses in prepared statements |
||
102 | * @var array |
||
103 | */ |
||
104 | protected $whereValues = []; |
||
105 | |||
106 | /** |
||
107 | * Value for limit string |
||
108 | * @var string |
||
109 | */ |
||
110 | protected $limit; |
||
111 | |||
112 | /** |
||
113 | * Value for offset in limit string |
||
114 | * @var integer |
||
115 | */ |
||
116 | protected $offset; |
||
117 | |||
118 | /** |
||
119 | * Query component order mapping |
||
120 | * for complex select queries |
||
121 | * |
||
122 | * Format: |
||
123 | * array( |
||
124 | * 'type' => 'where', |
||
125 | * 'conjunction' => ' AND ', |
||
126 | * 'string' => 'k=?' |
||
127 | * ) |
||
128 | * |
||
129 | * @var array |
||
130 | */ |
||
131 | protected $queryMap = []; |
||
132 | |||
133 | /** |
||
134 | * Map for having clause |
||
135 | * @var array |
||
136 | */ |
||
137 | protected $havingMap; |
||
138 | |||
139 | /** |
||
140 | * Convenience property for connection management |
||
141 | * @var string |
||
142 | */ |
||
143 | public $connName = ""; |
||
144 | |||
145 | /** |
||
146 | * List of queries executed |
||
147 | * @var array |
||
148 | */ |
||
149 | public $queries; |
||
150 | |||
151 | /** |
||
152 | * Whether to do only an explain on the query |
||
153 | * @var boolean |
||
154 | */ |
||
155 | protected $explain; |
||
156 | |||
157 | /** |
||
158 | * The current database driver |
||
159 | * @var \Query\Drivers\DriverInterface |
||
160 | */ |
||
161 | public $db; |
||
162 | |||
163 | /** |
||
164 | * Query parser class instance |
||
165 | * @var QueryParser |
||
166 | */ |
||
167 | public $parser; |
||
168 | |||
169 | /** |
||
170 | * Alias to driver util class |
||
171 | * @var \Query\Drivers\AbstractUtil |
||
172 | */ |
||
173 | public $util; |
||
174 | |||
175 | /** |
||
176 | * Alias to driver sql class |
||
177 | * @var \Query\Drivers\SQLInterface |
||
178 | */ |
||
179 | public $sql; |
||
180 | |||
181 | // -------------------------------------------------------------------------- |
||
182 | // Methods |
||
183 | // -------------------------------------------------------------------------- |
||
184 | |||
185 | /** |
||
186 | * Set values in the class, with either an array or key value pair |
||
187 | * |
||
188 | * @param array $var |
||
189 | * @param mixed $key |
||
190 | * @param mixed $val |
||
191 | * @param int $valType |
||
192 | * @return array |
||
193 | */ |
||
194 | protected function _mixedSet(array &$var, $key, $val=NULL, int $valType=self::BOTH): array |
||
216 | |||
217 | /** |
||
218 | * Method to simplify select_ methods |
||
219 | * |
||
220 | * @param string $field |
||
221 | * @param string|bool $as |
||
222 | * @return string |
||
223 | */ |
||
224 | protected function _select(string $field, $as = FALSE): string |
||
237 | |||
238 | /** |
||
239 | * Helper function for returning sql strings |
||
240 | * |
||
241 | * @param string $type |
||
242 | * @param string $table |
||
243 | * @param bool $reset |
||
244 | * @return string |
||
245 | */ |
||
246 | protected function _getCompile(string $type, string $table, bool $reset): string |
||
258 | |||
259 | /** |
||
260 | * Simplify 'like' methods |
||
261 | * |
||
262 | * @param string $field |
||
263 | * @param mixed $val |
||
264 | * @param string $pos |
||
265 | * @param string $like |
||
266 | * @param string $conj |
||
267 | * @return QueryBuilderInterface |
||
268 | */ |
||
269 | protected function _like(string $field, $val, string $pos, string $like='LIKE', string $conj='AND'): QueryBuilderInterface |
||
297 | |||
298 | /** |
||
299 | * Simplify building having clauses |
||
300 | * |
||
301 | * @param mixed $key |
||
302 | * @param mixed $val |
||
303 | * @param string $conj |
||
304 | * @return QueryBuilderInterface |
||
305 | */ |
||
306 | protected function _having($key, $val=[], string $conj='AND'): QueryBuilderInterface |
||
331 | |||
332 | /** |
||
333 | * Do all the redundant stuff for where/having type methods |
||
334 | * |
||
335 | * @param mixed $key |
||
336 | * @param mixed $val |
||
337 | * @return array |
||
338 | */ |
||
339 | protected function _where($key, $val=[]): array |
||
346 | |||
347 | /** |
||
348 | * Simplify generating where string |
||
349 | * |
||
350 | * @param mixed $key |
||
351 | * @param mixed $val |
||
352 | * @param string $defaultConj |
||
353 | * @return QueryBuilderInterface |
||
354 | */ |
||
355 | protected function _whereString($key, $val=[], string $defaultConj='AND'): QueryBuilderInterface |
||
390 | |||
391 | /** |
||
392 | * Simplify where_in methods |
||
393 | * |
||
394 | * @param mixed $key |
||
395 | * @param mixed $val |
||
396 | * @param string $in - The (not) in fragment |
||
397 | * @param string $conj - The where in conjunction |
||
398 | * @return QueryBuilderInterface |
||
399 | */ |
||
400 | protected function _whereIn($key, $val=[], string $in='IN', string $conj='AND'): QueryBuilderInterface |
||
417 | |||
418 | /** |
||
419 | * Executes the compiled query |
||
420 | * |
||
421 | * @param string $type |
||
422 | * @param string $table |
||
423 | * @param string $sql |
||
424 | * @param array|null $vals |
||
425 | * @param boolean $reset |
||
426 | * @return PDOStatement |
||
427 | */ |
||
428 | protected function _run(string $type, string $table, $sql=NULL, $vals=NULL, bool $reset=TRUE): PDOStatement |
||
460 | |||
461 | /** |
||
462 | * Add an additional set of mapping pairs to a internal map |
||
463 | * |
||
464 | * @param string $conjunction |
||
465 | * @param string $string |
||
466 | * @param string $type |
||
467 | * @return void |
||
468 | */ |
||
469 | protected function _appendMap(string $conjunction = '', string $string = '', string $type = '') |
||
477 | |||
478 | /** |
||
479 | * Convert the prepared statement into readable sql |
||
480 | * |
||
481 | * @param array $vals |
||
482 | * @param string $sql |
||
483 | * @param int $totalTime |
||
484 | * @return void |
||
485 | */ |
||
486 | protected function _appendQuery($vals, string $sql, int $totalTime) |
||
512 | |||
513 | /** |
||
514 | * Sub-method for generating sql strings |
||
515 | * |
||
516 | * @param string $type |
||
517 | * @param string $table |
||
518 | * @return string |
||
519 | */ |
||
520 | protected function _compileType(string $type='', string $table=''): string |
||
560 | |||
561 | /** |
||
562 | * String together the sql statements for sending to the db |
||
563 | * |
||
564 | * @param string $type |
||
565 | * @param string $table |
||
566 | * @return string |
||
567 | */ |
||
568 | protected function _compile(string $type='', string $table=''): string |
||
612 | } |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.