Complex classes like Db 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 Db, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | abstract class Db { |
||
14 | /// Constants /// |
||
15 | |||
16 | const QUERY_DEFINE = 'define'; |
||
17 | const QUERY_READ = 'read'; |
||
18 | const QUERY_WRITE = 'write'; |
||
19 | |||
20 | const INDEX_PK = 'primary'; |
||
21 | const INDEX_IX = 'index'; |
||
22 | const INDEX_UNIQUE = 'unique'; |
||
23 | |||
24 | const OPTION_REPLACE = 'replace'; |
||
25 | const OPTION_IGNORE = 'ignore'; |
||
26 | const OPTION_UPSERT = 'upsert'; |
||
27 | const OPTION_TRUNCATE = 'truncate'; |
||
28 | const OPTION_DROP = 'drop'; |
||
29 | const OPTION_MODE = 'mode'; |
||
30 | |||
31 | const OP_EQ = '='; |
||
32 | const OP_GT = '>'; |
||
33 | const OP_GTE = '>='; |
||
34 | const OP_IN = 'in'; |
||
35 | const OP_LIKE = 'like'; |
||
36 | const OP_LT = '<'; |
||
37 | const OP_LTE = '<='; |
||
38 | const OP_NE = '<>'; |
||
39 | |||
40 | const OP_AND = 'and'; |
||
41 | const OP_OR = 'or'; |
||
42 | |||
43 | const ORDER_ASC = 'asc'; |
||
44 | const ORDER_DESC = 'desc'; |
||
45 | |||
46 | const FETCH_TABLENAMES = 0x1; |
||
47 | const FETCH_COLUMNS = 0x2; |
||
48 | const FETCH_INDEXES = 0x4; |
||
49 | |||
50 | const MODE_EXEC = 0x1; |
||
51 | const MODE_ECHO = 0x2; |
||
52 | const MODE_SQL = 0x4; |
||
53 | const MODE_PDO = 0x8; |
||
54 | |||
55 | /// Properties /// |
||
56 | |||
57 | /** |
||
58 | * @var string The database prefix. |
||
59 | */ |
||
60 | protected $px = 'gdn_'; |
||
61 | |||
62 | /** |
||
63 | * @var int The query execution mode. |
||
64 | */ |
||
65 | protected $mode = Db::MODE_EXEC; |
||
66 | |||
67 | /** |
||
68 | * @var array A cached copy of the table schemas. |
||
69 | */ |
||
70 | protected $tables = []; |
||
71 | |||
72 | /** |
||
73 | * @var int Whether or not all the tables have been fetched. |
||
74 | */ |
||
75 | protected $allTablesFetched = 0; |
||
76 | |||
77 | /** |
||
78 | * @var int The number of rows that were affected by the last query. |
||
79 | */ |
||
80 | protected $rowCount; |
||
81 | |||
82 | /// Methods /// |
||
83 | |||
84 | /** |
||
85 | * Create the appropriate db driver given a config. |
||
86 | * |
||
87 | * @param array $config The configuration used to initialize the object. |
||
88 | * The config must have a driver key which names the db class to create. |
||
89 | * @throws \Exception Throws an exception when the config isn't complete. |
||
90 | */ |
||
91 | public static function create($config) { |
||
111 | |||
112 | /** |
||
113 | * Add a table to the database. |
||
114 | * |
||
115 | * @param string $tablename The name of the table. |
||
116 | * @param array $tabledef The table definition. |
||
117 | * @param array $options An array of additional options when adding the table. |
||
118 | */ |
||
119 | abstract protected function createTable($tablename, array $tabledef, array $options = []); |
||
120 | |||
121 | /** |
||
122 | * Alter a table in the database. |
||
123 | * |
||
124 | * When altering a table you pass an array with three optional keys: add, drop, and alter. |
||
125 | * Each value is consists of a table definition in a format that would be passed to {@link Db::setTableDef()}. |
||
126 | * |
||
127 | * @param string $tablename The name of the table. |
||
128 | * @param array $alterdef The alter definition. |
||
129 | * @param array $options An array of additional options when adding the table. |
||
130 | */ |
||
131 | abstract protected function alterTable($tablename, array $alterdef, array $options = []); |
||
132 | |||
133 | /** |
||
134 | * Drop a table. |
||
135 | * |
||
136 | * @param string $tablename The name of the table to drop. |
||
137 | * @param array $options An array of additional options when adding the table. |
||
138 | */ |
||
139 | abstract public function dropTable($tablename, array $options = []); |
||
140 | |||
141 | /** |
||
142 | * Get a table definition. |
||
143 | * |
||
144 | * @param string $tablename The name of the table. |
||
145 | * @return array|null Returns the table definition or null if the table does not exist. |
||
146 | */ |
||
147 | 44 | public function getTableDef($tablename) { |
|
165 | |||
166 | /** |
||
167 | * Get all of the tables in the database. |
||
168 | * |
||
169 | * @param bool $withDefs Whether or not to return the full table definitions or just the table names. |
||
170 | * @return array Returns an array of either the table definitions or the table names. |
||
171 | */ |
||
172 | 2 | public function getAllTables($withDefs = false) { |
|
181 | |||
182 | /** |
||
183 | * Set a table definition to the database. |
||
184 | * |
||
185 | * @param string $tablename The name of the table. |
||
186 | * @param array $tableDef The table definition. |
||
187 | * @param array $options An array of additional options when adding the table. |
||
188 | */ |
||
189 | 44 | public function setTableDef($tablename, array $tableDef, array $options = []) { |
|
256 | |||
257 | /** |
||
258 | * Move the primary key index into the correct place for database drivers. |
||
259 | * |
||
260 | * @param string $tablename The name of the table. |
||
261 | * @param array &$tableDef The table definition. |
||
262 | * @param array|null $curTableDef The current database table def used to resolve conflicts in some names. |
||
263 | * @throws \Exception Throws an exception when there is a mismatch between the primary index and the primary key |
||
264 | * defined on the columns themselves. |
||
265 | */ |
||
266 | 44 | protected function fixIndexes($tablename, array &$tableDef, $curTableDef = null) { |
|
306 | |||
307 | /** |
||
308 | * Get the database prefix. |
||
309 | * |
||
310 | * @return string Returns the current db prefix. |
||
311 | */ |
||
312 | public function getPx() { |
||
315 | |||
316 | /** |
||
317 | * Set the database prefix. |
||
318 | * |
||
319 | * @param string $px The new database prefix. |
||
320 | */ |
||
321 | public function setPx($px) { |
||
324 | |||
325 | /** |
||
326 | * Compare two index definitions to see if they have the same columns and same type. |
||
327 | * |
||
328 | * @param array $a The first index. |
||
329 | * @param array $b The second index. |
||
330 | * @return int Returns an integer less than, equal to, or greater than zero if {@link $a} is |
||
331 | * considered to be respectively less than, equal to, or greater than {@link $b}. |
||
332 | */ |
||
333 | 36 | public function indexCompare(array $a, array $b) { |
|
342 | |||
343 | /** |
||
344 | * Get data from the database. |
||
345 | * |
||
346 | * @param string $tablename The name of the table to get the data from. |
||
347 | * @param array $where An array of where conditions. |
||
348 | * @param array $options An array of additional options. |
||
349 | * @return mixed Returns the result set. |
||
350 | */ |
||
351 | abstract public function get($tablename, array $where, array $options = []); |
||
352 | |||
353 | /** |
||
354 | * Get a single row from the database. |
||
355 | * |
||
356 | * This is a conveinience method that calls {@link Db::get()} and shifts off the first row. |
||
357 | * |
||
358 | * @param string $tablename The name of the table to get the data from. |
||
359 | * @param array $where An array of where conditions. |
||
360 | * @param array $options An array of additional options. |
||
361 | * @return array|false Returns the row or false if there is no row. |
||
362 | */ |
||
363 | 12 | public function getOne($tablename, array $where, array $options = []) { |
|
368 | |||
369 | /** |
||
370 | * Insert a row into a table. |
||
371 | * |
||
372 | * @param string $tablename The name of the table to insert into. |
||
373 | * @param array $row The row of data to insert. |
||
374 | * @param array $options An array of options for the insert. |
||
375 | * |
||
376 | * Db::OPTION_IGNORE |
||
377 | * : Whether or not to ignore inserts that lead to a duplicate key. *default false* |
||
378 | * Db::OPTION_REPLACE |
||
379 | * : Whether or not to replace duplicate keys. *default false* |
||
380 | * Db::OPTION_UPSERT |
||
381 | * : Whether or not to update the existing data when duplicate keys exist. |
||
382 | * |
||
383 | * @return mixed Should return the id of the inserted record. |
||
384 | * @see Db::load() |
||
385 | */ |
||
386 | abstract public function insert($tablename, array $row, array $options = []); |
||
387 | |||
388 | /** |
||
389 | * Load many rows into a table. |
||
390 | * |
||
391 | * @param string $tablename The name of the table to insert into. |
||
392 | * @param \Traversable|array $rows A dataset to insert. |
||
393 | * Note that all rows must contain the same columns. |
||
394 | * The first row will be looked at for the structure of the insert and the rest of the rows will use this structure. |
||
395 | * @param array $options An array of options for the inserts. See {@link Db::insert()} for details. |
||
396 | * @return mixed |
||
397 | * @see Db::insert() |
||
398 | */ |
||
399 | abstract public function load($tablename, $rows, array $options = []); |
||
400 | |||
401 | |||
402 | /** |
||
403 | * Update a row or rows in a table. |
||
404 | * |
||
405 | * @param string $tablename The name of the table to update. |
||
406 | * @param array $set The values to set. |
||
407 | * @param array $where The where filter for the update. |
||
408 | * @param array $options An array of options for the update. |
||
409 | * @return mixed |
||
410 | */ |
||
411 | abstract public function update($tablename, array $set, array $where, array $options = []); |
||
412 | |||
413 | /** |
||
414 | * Delete rows from a table. |
||
415 | * |
||
416 | * @param string $tablename The name of the table to delete from. |
||
417 | * @param array $where The where filter of the delete. |
||
418 | * @param array $options An array of options. |
||
419 | * |
||
420 | * Db:OPTION_TRUNCATE |
||
421 | * : Truncate the table instead of deleting rows. In this case {@link $where} must be blank. |
||
422 | * @return mixed |
||
423 | */ |
||
424 | abstract public function delete($tablename, array $where, array $options = []); |
||
425 | |||
426 | /** |
||
427 | * Reset the internal table definition cache. |
||
428 | * |
||
429 | * @return Db Returns $this for fluent calls. |
||
430 | */ |
||
431 | 8 | public function reset() { |
|
437 | |||
438 | /** |
||
439 | * Build a standardized index name from an index definition. |
||
440 | * |
||
441 | * @param string $tablename The name of the table the index is in. |
||
442 | * @param array $indexDef The index definition. |
||
443 | * @return string Returns the index name. |
||
444 | */ |
||
445 | 44 | protected function buildIndexName($tablename, array $indexDef) { |
|
456 | } |
||
457 |