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 db_mysql 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_mysql, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class db_mysql { |
||
14 | const TRANSACTION_SERIALIZABLE = 'SERIALIZABLE'; |
||
15 | const TRANSACTION_REPEATABLE_READ = 'REPEATABLE READ'; |
||
16 | const TRANSACTION_READ_COMMITTED = 'READ COMMITTED'; |
||
17 | const TRANSACTION_READ_UNCOMMITTED = 'READ UNCOMMITTED'; |
||
18 | |||
19 | /** |
||
20 | * Статус соеднения с MySQL |
||
21 | * |
||
22 | * @var bool |
||
23 | */ |
||
24 | public $connected = false; |
||
25 | /** |
||
26 | * Префикс названий таблиц в БД |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | public $db_prefix = ''; |
||
31 | /** |
||
32 | * Список таблиц в БД |
||
33 | * |
||
34 | * @var array |
||
35 | */ |
||
36 | public $table_list = array(); |
||
37 | |||
38 | /** |
||
39 | * Настройки БД |
||
40 | * |
||
41 | * @var array |
||
42 | */ |
||
43 | protected $dbsettings = array(); |
||
44 | /** |
||
45 | * Драйвер для прямого обращения к MySQL |
||
46 | * |
||
47 | * @var db_mysql_v5 $driver |
||
48 | */ |
||
49 | public $driver = null; |
||
50 | |||
51 | /** |
||
52 | * Общее время запросов |
||
53 | * |
||
54 | * @var float $time_mysql_total |
||
55 | */ |
||
56 | public $time_mysql_total = 0.0; |
||
57 | |||
58 | /** |
||
59 | * Amount of queries on this DB |
||
60 | * |
||
61 | * @var int |
||
62 | */ |
||
63 | public $queryCount = 0; |
||
64 | |||
65 | public $isWatching = false; |
||
66 | |||
67 | /** |
||
68 | * @var \DBAL\DbTransaction $transaction |
||
69 | */ |
||
70 | protected $transaction; |
||
71 | |||
72 | /** |
||
73 | * Should query check be skipped? |
||
74 | * |
||
75 | * Used for altering scheme of DB |
||
76 | * |
||
77 | * @var bool $skipQueryCheck |
||
78 | */ |
||
79 | protected $skipQueryCheck = false; |
||
80 | |||
81 | /** |
||
82 | * @var SnCache $snCache |
||
83 | */ |
||
84 | public $snCache; |
||
85 | |||
86 | /** |
||
87 | * db_mysql constructor. |
||
88 | * |
||
89 | * @param \Common\GlobalContainer $gc |
||
90 | */ |
||
91 | public function __construct($gc) { |
||
95 | |||
96 | public function load_db_settings($configFile = '') { |
||
105 | |||
106 | /** |
||
107 | * @param null|array $external_db_settings |
||
108 | * |
||
109 | * @return bool |
||
110 | */ |
||
111 | public function sn_db_connect($external_db_settings = null) { |
||
140 | |||
141 | protected function driver_connect() { |
||
152 | |||
153 | public function db_disconnect() { |
||
161 | |||
162 | /** |
||
163 | * @param string $query |
||
164 | * |
||
165 | * @return mixed|string |
||
166 | */ |
||
167 | public function replaceTablePlaceholders($query) { |
||
177 | |||
178 | /** |
||
179 | * @param $query |
||
180 | */ |
||
181 | protected function logQuery($query) { |
||
192 | |||
193 | |||
194 | /** |
||
195 | * @return string |
||
196 | */ |
||
197 | public function queryTrace() { |
||
216 | |||
217 | /** |
||
218 | * @param string $query |
||
219 | * |
||
220 | * @return array|bool|mysqli_result|null |
||
221 | * @internal param bool $skip_query_check |
||
222 | * |
||
223 | */ |
||
224 | protected function doquery($query) { |
||
254 | |||
255 | |||
256 | // Just wrappers to distinguish query types |
||
257 | /** |
||
258 | * Executes non-data manipulation statements |
||
259 | * |
||
260 | * Can execute queries with check skip |
||
261 | * Honor current state of query checking |
||
262 | * |
||
263 | * @param string $query |
||
264 | * @param bool $skip_query_check |
||
265 | * |
||
266 | * @return array|bool|mysqli_result|null |
||
267 | */ |
||
268 | public function doExecute($query, $skip_query_check = false) { |
||
282 | |||
283 | |||
284 | public function doSelect($query) { |
||
287 | |||
288 | /** |
||
289 | * @param string $query |
||
290 | * |
||
291 | * @return array|null |
||
292 | */ |
||
293 | public function doSelectFetch($query) { |
||
296 | |||
297 | /** |
||
298 | * @param string $query |
||
299 | * |
||
300 | * @return mixed|null |
||
301 | */ |
||
302 | public function doSelectFetchValue($query) { |
||
307 | |||
308 | |||
309 | public function doInsertComplex($query) { |
||
312 | |||
313 | protected function doSet($table, $fieldsAndValues, $replace = DB_INSERT_PLAIN) { |
||
333 | |||
334 | /** |
||
335 | * @param string $table |
||
336 | * @param array $fieldsAndValues |
||
337 | * @param int $replace - DB_INSERT_PLAIN || DB_INSERT_IGNORE |
||
338 | * |
||
339 | * @return array|bool|mysqli_result|null |
||
340 | */ |
||
341 | public function doInsertSet($table, $fieldsAndValues, $replace = DB_INSERT_PLAIN) { |
||
344 | |||
345 | public function doReplaceSet($table, $fieldsAndValues) { |
||
348 | |||
349 | /** |
||
350 | * Values should be passed as-is |
||
351 | * |
||
352 | * @param string $table |
||
353 | * @param array $fields |
||
354 | * @param string[] $values |
||
355 | * @param bool $replace |
||
356 | * |
||
357 | * @return array|bool|mysqli_result|null |
||
358 | * @deprecated |
||
359 | */ |
||
360 | protected function doValuesDeprecated($table, $fields, &$values, $replace = DB_INSERT_PLAIN) { |
||
369 | |||
370 | // TODO - batch insert and replace here |
||
371 | |||
372 | // TODO - перед тем, как переделывать данные из депрекейтов - убедится, что |
||
373 | // null - это null, а не строка'NULL' |
||
374 | |||
375 | /** |
||
376 | * Values should be passed as-is |
||
377 | * |
||
378 | * @param string $table |
||
379 | * @param array $fields |
||
380 | * @param string[] $values |
||
381 | * |
||
382 | * @return array|bool|mysqli_result|null |
||
383 | * @deprecated |
||
384 | */ |
||
385 | public function doInsertValuesDeprecated($table, $fields, &$values) { |
||
388 | |||
389 | /** |
||
390 | * Values should be passed as-is |
||
391 | * |
||
392 | * @param string $table |
||
393 | * @param array $fields |
||
394 | * @param string[] $values |
||
395 | * |
||
396 | * @return array|bool|mysqli_result|null |
||
397 | * @deprecated |
||
398 | */ |
||
399 | public function doReplaceValuesDeprecated($table, $fields, &$values) { |
||
402 | |||
403 | |||
404 | public function doUpdateComplex($query) { |
||
407 | |||
408 | /** |
||
409 | * Executes self-contained SQL UPDATE query |
||
410 | * |
||
411 | * Self-contained - means no params used |
||
412 | * Such queries usually used to make large amount of in-base calculations |
||
413 | * |
||
414 | * @param $query |
||
415 | * |
||
416 | * @return array|bool|mysqli_result|null |
||
417 | */ |
||
418 | public function doUpdateSqlNoParam($query) { |
||
421 | |||
422 | protected function doUpdateWhere($table, $fieldsSet, $fieldsAdjust = array(), $where = array(), $isOneRecord = DB_RECORDS_ALL) { |
||
444 | |||
445 | public function doUpdateRowSet($table, $fieldsAndValues, $where) { |
||
448 | |||
449 | public function doUpdateTableSet($table, $fieldsAndValues, $where = array()) { |
||
452 | |||
453 | public function doUpdateRowAdjust($table, $fieldsSet, $fieldsAdjust, $where) { |
||
456 | |||
457 | public function doUpdateTableAdjust($table, $fieldsSet, $fieldsAdjust, $where) { |
||
460 | |||
461 | public function doUpdateAdjustDeprecated($query) { |
||
464 | |||
465 | |||
466 | |||
467 | /** |
||
468 | * For update_old - would be deprecated |
||
469 | * |
||
470 | * @param string $query |
||
471 | * |
||
472 | * @return array|bool|mysqli_result|null |
||
473 | * @deprecated |
||
474 | */ |
||
475 | public function doUpdateOld($query) { |
||
478 | |||
479 | |||
480 | /** |
||
481 | * @param string $query |
||
482 | * |
||
483 | * @return array|bool|mysqli_result|null |
||
484 | */ |
||
485 | public function doDelete($query) { |
||
488 | |||
489 | /** |
||
490 | * @param string $table |
||
491 | * @param array $where - simple WHERE statement list which can be combined with AND |
||
492 | * @param bool $isOneRecord |
||
493 | * |
||
494 | * @return array|bool|mysqli_result|null |
||
495 | */ |
||
496 | public function doDeleteWhere($table, $where, $isOneRecord = false) { |
||
504 | |||
505 | /** |
||
506 | * @param string $table |
||
507 | * @param array $where - simple WHERE statement list which can be combined with AND |
||
508 | * |
||
509 | * @return array|bool|mysqli_result|null |
||
510 | */ |
||
511 | public function doDeleteRowWhere($table, $where) { |
||
514 | |||
515 | /** |
||
516 | * @param string $query |
||
517 | * |
||
518 | * @return array|bool|mysqli_result|null |
||
519 | */ |
||
520 | public function doDeleteComplex($query) { |
||
523 | |||
524 | /** |
||
525 | * Early deprecated function for complex delete conditions |
||
526 | * |
||
527 | * Usually used for mallformed $where conditions |
||
528 | * |
||
529 | * @param $table |
||
530 | * @param $where |
||
531 | * |
||
532 | * @return array|bool|mysqli_result|null |
||
533 | * @deprecated |
||
534 | */ |
||
535 | public function doDeleteDeprecated($table, $where) { |
||
538 | |||
539 | |||
540 | protected function castAsDbValue($value) { |
||
570 | |||
571 | /** |
||
572 | * Make field list safe |
||
573 | * |
||
574 | * Support expressions - expression index should be strictly integer! |
||
575 | * |
||
576 | * @param array $fields - array of pair $fieldName => $fieldValue |
||
577 | * |
||
578 | * @return array |
||
579 | */ |
||
580 | View Code Duplication | protected function safeFieldsEqualValues($fields) { |
|
598 | |||
599 | /** |
||
600 | * Make fields adjustment safe |
||
601 | * |
||
602 | * Convert "key => value" pair to string "`key` = `key` + (value)" |
||
603 | * Supports expressions - expression index should be strictly integer! |
||
604 | * |
||
605 | * @param array $fields - array of pair $fieldName => $fieldValue |
||
606 | * |
||
607 | * @return array |
||
608 | */ |
||
609 | View Code Duplication | protected function safeFieldsAdjust($fields) { |
|
627 | |||
628 | // TODO - redo as callable usage with array_map/array_walk |
||
629 | View Code Duplication | public function safeValues($values) { |
|
642 | |||
643 | // TODO - redo as callable usage with array_map/array_walk |
||
644 | View Code Duplication | public function safeFields($fields) { |
|
657 | |||
658 | |||
659 | /** |
||
660 | * Returns iterator to iterate through mysqli_result |
||
661 | * |
||
662 | * @param string $query |
||
663 | * |
||
664 | * return DbResultIterator |
||
665 | * |
||
666 | * @return DbEmptyIterator|DbMysqliResultIterator |
||
667 | */ |
||
668 | public function doSelectIterator($query) { |
||
679 | |||
680 | /** |
||
681 | * @param DbQueryConstructor $stmt |
||
682 | * @param bool $skip_query_check |
||
683 | */ |
||
684 | public function doStmtLockAll($stmt, $skip_query_check = false) { |
||
694 | |||
695 | // TODO Заменить это на новый логгер |
||
696 | protected function security_watch_user_queries($query) { |
||
717 | |||
718 | |||
719 | public function security_query_check_bad_words($query) { |
||
776 | |||
777 | /** |
||
778 | * @param bool $prefixed_only |
||
779 | * |
||
780 | * @return array |
||
781 | */ |
||
782 | public function db_get_table_list($prefixed_only = true) { |
||
802 | |||
803 | /** |
||
804 | * @param string $statement |
||
805 | * |
||
806 | * @return bool|mysqli_stmt |
||
807 | */ |
||
808 | View Code Duplication | public function db_prepare($statement) { |
|
815 | |||
816 | |||
817 | /** |
||
818 | * L1 perform the query |
||
819 | * |
||
820 | * @param $query_string |
||
821 | * |
||
822 | * @return bool|mysqli_result |
||
823 | */ |
||
824 | View Code Duplication | public function db_sql_query($query_string) { |
|
831 | |||
832 | /** |
||
833 | * L1 fetch assoc array |
||
834 | * |
||
835 | * @param mysqli_result $query |
||
836 | * |
||
837 | * @return array|null |
||
838 | */ |
||
839 | View Code Duplication | public function db_fetch(&$query) { |
|
846 | |||
847 | public function db_fetch_row(&$query) { |
||
850 | |||
851 | public function db_escape($unescaped_string) { |
||
854 | |||
855 | public function driver_disconnect() { |
||
858 | |||
859 | public function db_error() { |
||
862 | |||
863 | public function db_insert_id() { |
||
866 | |||
867 | public function db_num_rows(&$result) { |
||
870 | |||
871 | public function db_affected_rows() { |
||
874 | |||
875 | /** |
||
876 | * @return string |
||
877 | */ |
||
878 | public function db_get_client_info() { |
||
881 | |||
882 | /** |
||
883 | * @return string |
||
884 | */ |
||
885 | public function db_get_server_info() { |
||
888 | |||
889 | /** |
||
890 | * @return string |
||
891 | */ |
||
892 | public function db_get_host_info() { |
||
895 | |||
896 | public function db_get_server_stat() { |
||
907 | |||
908 | /** |
||
909 | * @return array |
||
910 | * @throws Exception |
||
911 | */ |
||
912 | public function db_core_show_status() { |
||
925 | |||
926 | public function mysql_get_table_list() { |
||
929 | |||
930 | public function mysql_get_innodb_status() { |
||
933 | |||
934 | /** |
||
935 | * @return \DBAL\DbTransaction |
||
936 | */ |
||
937 | public function getTransaction() { |
||
940 | |||
941 | // Some wrappers to DbTransaction |
||
942 | // Unused for now |
||
943 | public function transactionCheck($status = null) { |
||
946 | |||
947 | public function transactionStart($level = '') { |
||
950 | |||
951 | public function transactionCommit() { |
||
954 | |||
955 | public function transactionRollback() { |
||
958 | |||
959 | } |
||
960 |