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!=, orswitchconditions), values of different types might be equal.For
stringvalues, the empty string''is a special case, in particular the following results might be unexpected: