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 | var $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) |
||
143 | { |
||
144 | if(!$db_type) |
||
|
|||
145 | { |
||
146 | $db_type = Context::getDBType(); |
||
147 | } |
||
148 | if(!$db_type && Context::isInstalled()) |
||
149 | { |
||
150 | return new Object(-1, 'msg_db_not_setted'); |
||
151 | } |
||
152 | |||
153 | if(!isset($GLOBALS['__DB__'])) |
||
154 | { |
||
155 | $GLOBALS['__DB__'] = array(); |
||
156 | } |
||
157 | if(!isset($GLOBALS['__DB__'][$db_type])) |
||
158 | { |
||
159 | $class_name = 'DB' . ucfirst($db_type); |
||
160 | $class_file = _XE_PATH_ . "classes/db/$class_name.class.php"; |
||
161 | if(!file_exists($class_file)) |
||
162 | { |
||
163 | return new Object(-1, 'msg_db_not_setted'); |
||
164 | } |
||
165 | |||
166 | // get a singletone instance of the database driver class |
||
167 | require_once($class_file); |
||
168 | $GLOBALS['__DB__'][$db_type] = call_user_func(array($class_name, 'create')); |
||
169 | $GLOBALS['__DB__'][$db_type]->db_type = $db_type; |
||
170 | } |
||
171 | |||
172 | return $GLOBALS['__DB__'][$db_type]; |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * returns instance of db |
||
177 | * @return DB return DB object instance |
||
178 | */ |
||
179 | function create() |
||
180 | { |
||
181 | return new DB; |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * constructor |
||
186 | * @return void |
||
187 | */ |
||
188 | function DB() |
||
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() |
||
201 | { |
||
202 | $oDB = new DB(); |
||
203 | return $oDB->_getSupportedList(); |
||
204 | } |
||
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 | function getEnableList() |
|
234 | |||
235 | /** |
||
236 | * returns list of disable in supported dbms list |
||
237 | * this list return by child class |
||
238 | * @return array return disable DBMS list in supported dbms list |
||
239 | */ |
||
240 | View Code Duplication | function getDisableList() |
|
263 | |||
264 | /** |
||
265 | * returns list of supported dbms list |
||
266 | * this method is private |
||
267 | * @return array return supported DBMS list |
||
268 | */ |
||
269 | function _getSupportedList() |
||
316 | |||
317 | /** |
||
318 | * sort dbms as priority |
||
319 | */ |
||
320 | function _sortDBMS($a, $b) |
||
347 | |||
348 | /** |
||
349 | * Return dbms supportable status |
||
350 | * The value is set in the child class |
||
351 | * @return boolean true: is supported, false: is not supported |
||
352 | */ |
||
353 | function isSupported() |
||
357 | |||
358 | /** |
||
359 | * Return connected status |
||
360 | * @param string $type master or slave |
||
361 | * @param int $indx key of server list |
||
362 | * @return boolean true: connected, false: not connected |
||
363 | */ |
||
364 | function isConnected($type = 'master', $indx = 0) |
||
375 | |||
376 | /** |
||
377 | * start recording log |
||
378 | * @param string $query query string |
||
379 | * @return void |
||
380 | */ |
||
381 | function actStart($query) |
||
388 | |||
389 | /** |
||
390 | * finish recording log |
||
391 | * @return void |
||
392 | */ |
||
393 | function actFinish() |
||
463 | |||
464 | /** |
||
465 | * set query debug log |
||
466 | * @param array $log values set query debug |
||
467 | * @return void |
||
468 | */ |
||
469 | function setQueryLog($log) |
||
473 | |||
474 | /** |
||
475 | * set error |
||
476 | * @param int $errno error code |
||
477 | * @param string $errstr error message |
||
478 | * @return void |
||
479 | */ |
||
480 | function setError($errno = 0, $errstr = 'success') |
||
485 | |||
486 | /** |
||
487 | * Return error status |
||
488 | * @return boolean true: error, false: no error |
||
489 | */ |
||
490 | function isError() |
||
494 | |||
495 | /** |
||
496 | * Returns object of error info |
||
497 | * @return object object of error |
||
498 | */ |
||
499 | function getError() |
||
504 | |||
505 | /** |
||
506 | * Execute Query that result of the query xml file |
||
507 | * This function finds xml file or cache file of $query_id, compiles it and then execute it |
||
508 | * @param string $query_id query id (module.queryname) |
||
509 | * @param array|object $args arguments for query |
||
510 | * @param array $arg_columns column list. if you want get specific colums from executed result, add column list to $arg_columns |
||
511 | * @return object result of query |
||
512 | */ |
||
513 | function executeQuery($query_id, $args = NULL, $arg_columns = NULL, $type = NULL) |
||
573 | |||
574 | /** |
||
575 | * Look for query cache file |
||
576 | * @param string $query_id query id for finding |
||
577 | * @param string $xml_file original xml query file |
||
578 | * @return string cache file |
||
579 | */ |
||
580 | function checkQueryCacheFile($query_id, $xml_file) |
||
600 | |||
601 | /** |
||
602 | * Execute query and return the result |
||
603 | * @param string $cache_file cache file of query |
||
604 | * @param array|object $source_args arguments for query |
||
605 | * @param string $query_id query id |
||
606 | * @param array $arg_columns column list. if you want get specific colums from executed result, add column list to $arg_columns |
||
607 | * @return object result of query |
||
608 | */ |
||
609 | function _executeQuery($cache_file, $source_args, $query_id, $arg_columns, $type) |
||
669 | |||
670 | /** |
||
671 | * Returns counter cache data |
||
672 | * @param array|string $tables tables to get data |
||
673 | * @param string $condition condition to get data |
||
674 | * @return int count of cache data |
||
675 | */ |
||
676 | function getCountCache($tables, $condition) |
||
728 | |||
729 | /** |
||
730 | * Save counter cache data |
||
731 | * @param array|string $tables tables to save data |
||
732 | * @param string $condition condition to save data |
||
733 | * @param int $count count of cache data to save |
||
734 | * @return void |
||
735 | */ |
||
736 | function putCountCache($tables, $condition, $count = 0) |
||
768 | |||
769 | /** |
||
770 | * Reset counter cache data |
||
771 | * @param array|string $tables tables to reset cache data |
||
772 | * @return boolean true: success, false: failed |
||
773 | */ |
||
774 | function resetCountCache($tables) |
||
798 | |||
799 | /** |
||
800 | * Drop tables |
||
801 | * @param string $table_name |
||
802 | * @return void |
||
803 | */ |
||
804 | function dropTable($table_name) |
||
813 | |||
814 | /** |
||
815 | * Return select query string |
||
816 | * @param object $query |
||
817 | * @param boolean $with_values |
||
818 | * @return string |
||
819 | */ |
||
820 | function getSelectSql($query, $with_values = TRUE) |
||
877 | |||
878 | /** |
||
879 | * Given a SELECT statement that uses click count |
||
880 | * returns the corresponding update sql string |
||
881 | * for databases that don't have click count support built in |
||
882 | * (aka all besides CUBRID) |
||
883 | * |
||
884 | * Function does not check if click count columns exist! |
||
885 | * You must call $query->usesClickCount() before using this function |
||
886 | * |
||
887 | * @param $queryObject |
||
888 | */ |
||
889 | function getClickCountQuery($queryObject) |
||
907 | |||
908 | /** |
||
909 | * Return delete query string |
||
910 | * @param object $query |
||
911 | * @param boolean $with_values |
||
912 | * @param boolean $with_priority |
||
913 | * @return string |
||
914 | */ |
||
915 | function getDeleteSql($query, $with_values = TRUE, $with_priority = FALSE) |
||
939 | |||
940 | /** |
||
941 | * Return update query string |
||
942 | * @param object $query |
||
943 | * @param boolean $with_values |
||
944 | * @param boolean $with_priority |
||
945 | * @return string |
||
946 | */ |
||
947 | function getUpdateSql($query, $with_values = TRUE, $with_priority = FALSE) |
||
971 | |||
972 | /** |
||
973 | * Return insert query string |
||
974 | * @param object $query |
||
975 | * @param boolean $with_values |
||
976 | * @param boolean $with_priority |
||
977 | * @return string |
||
978 | */ |
||
979 | function getInsertSql($query, $with_values = TRUE, $with_priority = FALSE) |
||
987 | |||
988 | /** |
||
989 | * Return index from slave server list |
||
990 | * @return int |
||
991 | */ |
||
992 | function _getSlaveConnectionStringIndex() |
||
998 | |||
999 | /** |
||
1000 | * Return connection resource |
||
1001 | * @param string $type use 'master' or 'slave'. default value is 'master' |
||
1002 | * @param int $indx if indx value is NULL, return rand number in slave server list |
||
1003 | * @return resource |
||
1004 | */ |
||
1005 | function _getConnection($type = 'master', $indx = NULL) |
||
1030 | |||
1031 | /** |
||
1032 | * check db information exists |
||
1033 | * @return boolean |
||
1034 | */ |
||
1035 | function _dbInfoExists() |
||
1047 | |||
1048 | /** |
||
1049 | * DB disconnection |
||
1050 | * this method is protected |
||
1051 | * @param resource $connection |
||
1052 | * @return void |
||
1053 | */ |
||
1054 | function _close($connection) |
||
1058 | |||
1059 | /** |
||
1060 | * DB disconnection |
||
1061 | * @param string $type 'master' or 'slave' |
||
1062 | * @param int $indx number in slave dbms server list |
||
1063 | * @return void |
||
1064 | */ |
||
1065 | function close($type = 'master', $indx = 0) |
||
1086 | |||
1087 | /** |
||
1088 | * DB transaction start |
||
1089 | * this method is protected |
||
1090 | * @return boolean |
||
1091 | */ |
||
1092 | function _begin($transactionLevel = 0) |
||
1096 | |||
1097 | /** |
||
1098 | * DB transaction start |
||
1099 | * @return void |
||
1100 | */ |
||
1101 | function begin() |
||
1114 | |||
1115 | /** |
||
1116 | * DB transaction rollback |
||
1117 | * this method is protected |
||
1118 | * @return boolean |
||
1119 | */ |
||
1120 | function _rollback($transactionLevel = 0) |
||
1124 | |||
1125 | /** |
||
1126 | * DB transaction rollback |
||
1127 | * @return void |
||
1128 | */ |
||
1129 | function rollback() |
||
1145 | |||
1146 | /** |
||
1147 | * DB transaction commit |
||
1148 | * this method is protected |
||
1149 | * @return boolean |
||
1150 | */ |
||
1151 | function _commit() |
||
1155 | |||
1156 | /** |
||
1157 | * DB transaction commit |
||
1158 | * @param boolean $force regardless transaction start status or connect status, forced to commit |
||
1159 | * @return void |
||
1160 | */ |
||
1161 | function commit($force = FALSE) |
||
1177 | |||
1178 | /** |
||
1179 | * Execute the query |
||
1180 | * this method is protected |
||
1181 | * @param string $query |
||
1182 | * @param resource $connection |
||
1183 | * @return void |
||
1184 | */ |
||
1185 | function __query($query, $connection) |
||
1189 | |||
1190 | /** |
||
1191 | * Execute the query |
||
1192 | * this method is protected |
||
1193 | * @param string $query |
||
1194 | * @param resource $connection |
||
1195 | * @return resource |
||
1196 | */ |
||
1197 | function _query($query, $connection = NULL) |
||
1214 | |||
1215 | /** |
||
1216 | * DB info settings |
||
1217 | * this method is protected |
||
1218 | * @return void |
||
1219 | */ |
||
1220 | function _setDBInfo() |
||
1240 | |||
1241 | /** |
||
1242 | * DB Connect |
||
1243 | * this method is protected |
||
1244 | * @param array $connection |
||
1245 | * @return void |
||
1246 | */ |
||
1247 | function __connect($connection) |
||
1251 | |||
1252 | /** |
||
1253 | * If have a task after connection, add a taks in this method |
||
1254 | * this method is protected |
||
1255 | * @param resource $connection |
||
1256 | * @return void |
||
1257 | */ |
||
1258 | function _afterConnect($connection) |
||
1262 | |||
1263 | /** |
||
1264 | * DB Connect |
||
1265 | * this method is protected |
||
1266 | * @param string $type 'master' or 'slave' |
||
1267 | * @param int $indx number in slave dbms server list |
||
1268 | * @return void |
||
1269 | */ |
||
1270 | function _connect($type = 'master', $indx = 0) |
||
1311 | |||
1312 | /** |
||
1313 | * Start recording DBClass log |
||
1314 | * @return void |
||
1315 | */ |
||
1316 | function actDBClassStart() |
||
1322 | |||
1323 | /** |
||
1324 | * Finish recording DBClass log |
||
1325 | * @return void |
||
1326 | */ |
||
1327 | function actDBClassFinish() |
||
1338 | |||
1339 | /** |
||
1340 | * Returns a database specific parser instance |
||
1341 | * used for escaping expressions and table/column identifiers |
||
1342 | * |
||
1343 | * Requires an implementation of the DB class (won't work if database is not set) |
||
1344 | * this method is singleton |
||
1345 | * |
||
1346 | * @param boolean $force force load DBParser instance |
||
1347 | * @return DBParser |
||
1348 | */ |
||
1349 | function &getParser($force = FALSE) |
||
1360 | |||
1361 | } |
||
1362 | /* End of file DB.class.php */ |
||
1364 |
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: