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 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 |
||
16 | class DB |
||
17 | { |
||
18 | |||
19 | static $isSupported = FALSE; |
||
20 | |||
21 | /** |
||
22 | * priority of DBMS |
||
23 | * @var array |
||
24 | */ |
||
25 | var $priority_dbms = array( |
||
26 | 'mysqli' => 6, |
||
27 | 'mysqli_innodb' => 5, |
||
28 | 'mysql' => 4, |
||
29 | 'mysql_innodb' => 3, |
||
30 | 'cubrid' => 2, |
||
31 | 'mssql' => 1 |
||
32 | ); |
||
33 | |||
34 | /** |
||
35 | * count cache path |
||
36 | * @var string |
||
37 | */ |
||
38 | var $count_cache_path = 'files/cache/db'; |
||
39 | |||
40 | /** |
||
41 | * operations for condition |
||
42 | * @var array |
||
43 | */ |
||
44 | var $cond_operation = array( |
||
45 | 'equal' => '=', |
||
46 | 'more' => '>=', |
||
47 | 'excess' => '>', |
||
48 | 'less' => '<=', |
||
49 | 'below' => '<', |
||
50 | 'notequal' => '<>', |
||
51 | 'notnull' => 'is not null', |
||
52 | 'null' => 'is null', |
||
53 | ); |
||
54 | |||
55 | /** |
||
56 | * master database connection string |
||
57 | * @var array |
||
58 | */ |
||
59 | var $master_db = NULL; |
||
60 | |||
61 | /** |
||
62 | * array of slave databases connection strings |
||
63 | * @var array |
||
64 | */ |
||
65 | var $slave_db = NULL; |
||
66 | var $result = NULL; |
||
67 | |||
68 | /** |
||
69 | * error code (0 means no error) |
||
70 | * @var int |
||
71 | */ |
||
72 | var $errno = 0; |
||
73 | |||
74 | /** |
||
75 | * error message |
||
76 | * @var string |
||
77 | */ |
||
78 | var $errstr = ''; |
||
79 | |||
80 | /** |
||
81 | * query string of latest executed query |
||
82 | * @var string |
||
83 | */ |
||
84 | var $query = ''; |
||
85 | var $connection = ''; |
||
86 | |||
87 | /** |
||
88 | * elapsed time of latest executed query |
||
89 | * @var int |
||
90 | */ |
||
91 | var $elapsed_time = 0; |
||
92 | |||
93 | /** |
||
94 | * elapsed time of latest executed DB class |
||
95 | * @var int |
||
96 | */ |
||
97 | var $elapsed_dbclass_time = 0; |
||
98 | |||
99 | /** |
||
100 | * transaction flag |
||
101 | * @var boolean |
||
102 | */ |
||
103 | var $transaction_started = FALSE; |
||
104 | var $is_connected = FALSE; |
||
105 | |||
106 | /** |
||
107 | * returns enable list in supported dbms list |
||
108 | * will be written by classes/DB/DB***.class.php |
||
109 | * @var array |
||
110 | */ |
||
111 | static $supported_list = array(); |
||
112 | |||
113 | /** |
||
114 | * location of query cache |
||
115 | * @var string |
||
116 | */ |
||
117 | var $cache_file = 'files/cache/queries/'; |
||
118 | |||
119 | /** |
||
120 | * stores database type: 'mysql','cubrid','mssql' etc. or 'db' when database is not yet set |
||
121 | * @var string |
||
122 | */ |
||
123 | var $db_type; |
||
124 | |||
125 | /** |
||
126 | * flag to decide if class prepared statements or not (when supported); can be changed from db.config.info |
||
127 | * @var string |
||
128 | */ |
||
129 | var $use_prepared_statements; |
||
130 | |||
131 | /** |
||
132 | * leve of transaction |
||
133 | * @var unknown |
||
134 | */ |
||
135 | private $transactionNestedLevel = 0; |
||
136 | |||
137 | /** |
||
138 | * returns instance of certain db type |
||
139 | * @param string $db_type type of db |
||
140 | * @return DB return DB object instance |
||
141 | */ |
||
142 | function getInstance($db_type = NULL) |
||
174 | |||
175 | /** |
||
176 | * returns instance of db |
||
177 | * @return DB return DB object instance |
||
178 | */ |
||
179 | function create() |
||
183 | |||
184 | /** |
||
185 | * constructor |
||
186 | * @return void |
||
187 | */ |
||
188 | function __construct() |
||
189 | { |
||
190 | $this->count_cache_path = _XE_PATH_ . $this->count_cache_path; |
||
191 | $this->cache_file = _XE_PATH_ . $this->cache_file; |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * returns list of supported dbms list |
||
196 | * this list return by directory list |
||
197 | * check by instance can creatable |
||
198 | * @return array return supported DBMS list |
||
199 | */ |
||
200 | function getSupportedList() |
||
205 | |||
206 | /** |
||
207 | * returns enable list in supported dbms list |
||
208 | * this list return by child class |
||
209 | * @return array return enable DBMS list in supported dbms list |
||
210 | */ |
||
211 | View Code Duplication | public static function getEnableList() |
|
232 | |||
233 | /** |
||
234 | * returns list of disable in supported dbms list |
||
235 | * this list return by child class |
||
236 | * @return array return disable DBMS list in supported dbms list |
||
237 | */ |
||
238 | View Code Duplication | public static function getDisableList() |
|
259 | |||
260 | /** |
||
261 | * returns list of supported dbms list |
||
262 | * this method is private |
||
263 | * @return array return supported DBMS list |
||
264 | */ |
||
265 | function _getSupportedList() |
||
312 | |||
313 | /** |
||
314 | * sort dbms as priority |
||
315 | */ |
||
316 | function _sortDBMS($a, $b) |
||
343 | |||
344 | /** |
||
345 | * Return dbms supportable status |
||
346 | * The value is set in the child class |
||
347 | * @return boolean true: is supported, false: is not supported |
||
348 | */ |
||
349 | function isSupported() |
||
353 | |||
354 | /** |
||
355 | * Return connected status |
||
356 | * @param string $type master or slave |
||
357 | * @param int $indx key of server list |
||
358 | * @return boolean true: connected, false: not connected |
||
359 | */ |
||
360 | function isConnected($type = 'master', $indx = 0) |
||
371 | |||
372 | /** |
||
373 | * start recording log |
||
374 | * @param string $query query string |
||
375 | * @return void |
||
376 | */ |
||
377 | function actStart($query) |
||
384 | |||
385 | /** |
||
386 | * finish recording log |
||
387 | * @return void |
||
388 | */ |
||
389 | function actFinish() |
||
459 | |||
460 | /** |
||
461 | * set query debug log |
||
462 | * @param array $log values set query debug |
||
463 | * @return void |
||
464 | */ |
||
465 | function setQueryLog($log) |
||
469 | |||
470 | /** |
||
471 | * set error |
||
472 | * @param int $errno error code |
||
473 | * @param string $errstr error message |
||
474 | * @return void |
||
475 | */ |
||
476 | function setError($errno = 0, $errstr = 'success') |
||
481 | |||
482 | /** |
||
483 | * Return error status |
||
484 | * @return boolean true: error, false: no error |
||
485 | */ |
||
486 | function isError() |
||
490 | |||
491 | /** |
||
492 | * Returns object of error info |
||
493 | * @return object object of error |
||
494 | */ |
||
495 | function getError() |
||
500 | |||
501 | /** |
||
502 | * Execute Query that result of the query xml file |
||
503 | * This function finds xml file or cache file of $query_id, compiles it and then execute it |
||
504 | * @param string $query_id query id (module.queryname) |
||
505 | * @param array|object $args arguments for query |
||
506 | * @param array $arg_columns column list. if you want get specific colums from executed result, add column list to $arg_columns |
||
507 | * @return object result of query |
||
508 | */ |
||
509 | function executeQuery($query_id, $args = NULL, $arg_columns = NULL, $type = NULL) |
||
569 | |||
570 | /** |
||
571 | * Look for query cache file |
||
572 | * @param string $query_id query id for finding |
||
573 | * @param string $xml_file original xml query file |
||
574 | * @return string cache file |
||
575 | */ |
||
576 | function checkQueryCacheFile($query_id, $xml_file) |
||
596 | |||
597 | /** |
||
598 | * Execute query and return the result |
||
599 | * @param string $cache_file cache file of query |
||
600 | * @param array|object $source_args arguments for query |
||
601 | * @param string $query_id query id |
||
602 | * @param array $arg_columns column list. if you want get specific colums from executed result, add column list to $arg_columns |
||
603 | * @return object result of query |
||
604 | */ |
||
605 | function _executeQuery($cache_file, $source_args, $query_id, $arg_columns, $type) |
||
665 | |||
666 | /** |
||
667 | * Returns counter cache data |
||
668 | * @param array|string $tables tables to get data |
||
669 | * @param string $condition condition to get data |
||
670 | * @return int count of cache data |
||
671 | */ |
||
672 | function getCountCache($tables, $condition) |
||
724 | |||
725 | /** |
||
726 | * Save counter cache data |
||
727 | * @param array|string $tables tables to save data |
||
728 | * @param string $condition condition to save data |
||
729 | * @param int $count count of cache data to save |
||
730 | * @return void |
||
731 | */ |
||
732 | function putCountCache($tables, $condition, $count = 0) |
||
764 | |||
765 | /** |
||
766 | * Reset counter cache data |
||
767 | * @param array|string $tables tables to reset cache data |
||
768 | * @return boolean true: success, false: failed |
||
769 | */ |
||
770 | function resetCountCache($tables) |
||
794 | |||
795 | /** |
||
796 | * Drop tables |
||
797 | * @param string $table_name |
||
798 | * @return void |
||
799 | */ |
||
800 | function dropTable($table_name) |
||
809 | |||
810 | /** |
||
811 | * Return select query string |
||
812 | * @param object $query |
||
813 | * @param boolean $with_values |
||
814 | * @return string |
||
815 | */ |
||
816 | function getSelectSql($query, $with_values = TRUE) |
||
873 | |||
874 | /** |
||
875 | * Given a SELECT statement that uses click count |
||
876 | * returns the corresponding update sql string |
||
877 | * for databases that don't have click count support built in |
||
878 | * (aka all besides CUBRID) |
||
879 | * |
||
880 | * Function does not check if click count columns exist! |
||
881 | * You must call $query->usesClickCount() before using this function |
||
882 | * |
||
883 | * @param $queryObject |
||
884 | */ |
||
885 | function getClickCountQuery($queryObject) |
||
903 | |||
904 | /** |
||
905 | * Return delete query string |
||
906 | * @param object $query |
||
907 | * @param boolean $with_values |
||
908 | * @param boolean $with_priority |
||
909 | * @return string |
||
910 | */ |
||
911 | function getDeleteSql($query, $with_values = TRUE, $with_priority = FALSE) |
||
935 | |||
936 | /** |
||
937 | * Return update query string |
||
938 | * @param object $query |
||
939 | * @param boolean $with_values |
||
940 | * @param boolean $with_priority |
||
941 | * @return string |
||
942 | */ |
||
943 | function getUpdateSql($query, $with_values = TRUE, $with_priority = FALSE) |
||
967 | |||
968 | /** |
||
969 | * Return insert query string |
||
970 | * @param object $query |
||
971 | * @param boolean $with_values |
||
972 | * @param boolean $with_priority |
||
973 | * @return string |
||
974 | */ |
||
975 | function getInsertSql($query, $with_values = TRUE, $with_priority = FALSE) |
||
983 | |||
984 | /** |
||
985 | * Return index from slave server list |
||
986 | * @return int |
||
987 | */ |
||
988 | function _getSlaveConnectionStringIndex() |
||
994 | |||
995 | /** |
||
996 | * Return connection resource |
||
997 | * @param string $type use 'master' or 'slave'. default value is 'master' |
||
998 | * @param int $indx if indx value is NULL, return rand number in slave server list |
||
999 | * @return resource |
||
1000 | */ |
||
1001 | function _getConnection($type = 'master', $indx = NULL) |
||
1026 | |||
1027 | /** |
||
1028 | * check db information exists |
||
1029 | * @return boolean |
||
1030 | */ |
||
1031 | function _dbInfoExists() |
||
1043 | |||
1044 | /** |
||
1045 | * DB disconnection |
||
1046 | * this method is protected |
||
1047 | * @param resource $connection |
||
1048 | * @return void |
||
1049 | */ |
||
1050 | function _close($connection) |
||
1054 | |||
1055 | /** |
||
1056 | * DB disconnection |
||
1057 | * @param string $type 'master' or 'slave' |
||
1058 | * @param int $indx number in slave dbms server list |
||
1059 | * @return void |
||
1060 | */ |
||
1061 | function close($type = 'master', $indx = 0) |
||
1082 | |||
1083 | /** |
||
1084 | * DB transaction start |
||
1085 | * this method is protected |
||
1086 | * @return boolean |
||
1087 | */ |
||
1088 | function _begin($transactionLevel = 0) |
||
1092 | |||
1093 | /** |
||
1094 | * DB transaction start |
||
1095 | * @return void |
||
1096 | */ |
||
1097 | function begin() |
||
1110 | |||
1111 | /** |
||
1112 | * DB transaction rollback |
||
1113 | * this method is protected |
||
1114 | * @return boolean |
||
1115 | */ |
||
1116 | function _rollback($transactionLevel = 0) |
||
1120 | |||
1121 | /** |
||
1122 | * DB transaction rollback |
||
1123 | * @return void |
||
1124 | */ |
||
1125 | function rollback() |
||
1141 | |||
1142 | /** |
||
1143 | * DB transaction commit |
||
1144 | * this method is protected |
||
1145 | * @return boolean |
||
1146 | */ |
||
1147 | function _commit() |
||
1151 | |||
1152 | /** |
||
1153 | * DB transaction commit |
||
1154 | * @param boolean $force regardless transaction start status or connect status, forced to commit |
||
1155 | * @return void |
||
1156 | */ |
||
1157 | function commit($force = FALSE) |
||
1173 | |||
1174 | /** |
||
1175 | * Execute the query |
||
1176 | * this method is protected |
||
1177 | * @param string $query |
||
1178 | * @param resource $connection |
||
1179 | * @return void |
||
1180 | */ |
||
1181 | function __query($query, $connection) |
||
1185 | |||
1186 | /** |
||
1187 | * Execute the query |
||
1188 | * this method is protected |
||
1189 | * @param string $query |
||
1190 | * @param resource $connection |
||
1191 | * @return resource |
||
1192 | */ |
||
1193 | function _query($query, $connection = NULL) |
||
1210 | |||
1211 | /** |
||
1212 | * DB info settings |
||
1213 | * this method is protected |
||
1214 | * @return void |
||
1215 | */ |
||
1216 | function _setDBInfo() |
||
1236 | |||
1237 | /** |
||
1238 | * DB Connect |
||
1239 | * this method is protected |
||
1240 | * @param array $connection |
||
1241 | * @return void |
||
1242 | */ |
||
1243 | function __connect($connection) |
||
1247 | |||
1248 | /** |
||
1249 | * If have a task after connection, add a taks in this method |
||
1250 | * this method is protected |
||
1251 | * @param resource $connection |
||
1252 | * @return void |
||
1253 | */ |
||
1254 | function _afterConnect($connection) |
||
1258 | |||
1259 | /** |
||
1260 | * DB Connect |
||
1261 | * this method is protected |
||
1262 | * @param string $type 'master' or 'slave' |
||
1263 | * @param int $indx number in slave dbms server list |
||
1264 | * @return void |
||
1265 | */ |
||
1266 | function _connect($type = 'master', $indx = 0) |
||
1307 | |||
1308 | /** |
||
1309 | * Start recording DBClass log |
||
1310 | * @return void |
||
1311 | */ |
||
1312 | function actDBClassStart() |
||
1318 | |||
1319 | /** |
||
1320 | * Finish recording DBClass log |
||
1321 | * @return void |
||
1322 | */ |
||
1323 | function actDBClassFinish() |
||
1334 | |||
1335 | /** |
||
1336 | * Returns a database specific parser instance |
||
1337 | * used for escaping expressions and table/column identifiers |
||
1338 | * |
||
1339 | * Requires an implementation of the DB class (won't work if database is not set) |
||
1340 | * this method is singleton |
||
1341 | * |
||
1342 | * @param boolean $force force load DBParser instance |
||
1343 | * @return DBParser |
||
1344 | */ |
||
1345 | function getParser($force = FALSE) |
||
1356 | |||
1357 | } |
||
1358 | /* End of file DB.class.php */ |
||
1360 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: