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 Adodb 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 Adodb, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
38 | class Adodb extends Fwolflib { |
||
|
|||
39 | |||
40 | /** |
||
41 | * Real ADODB connection object |
||
42 | * @var object |
||
43 | */ |
||
44 | protected $__conn = null; |
||
45 | |||
46 | /** |
||
47 | * Db profile |
||
48 | * @var array |
||
49 | */ |
||
50 | public $aDbProfile = null; |
||
51 | |||
52 | /** |
||
53 | * Table schema |
||
54 | * |
||
55 | * array( |
||
56 | * col -> // ADOFieldObject Object, not Array ! |
||
57 | * [name] => ts |
||
58 | * [max_length] => -1 |
||
59 | * [type] => timestamp |
||
60 | * [scale] => |
||
61 | * [not_null] => 1 |
||
62 | * [primary_key] => |
||
63 | * [auto_increment] => |
||
64 | * [binary] => |
||
65 | * [unsigned] => |
||
66 | * [zerofill] => |
||
67 | * [has_default] => 1 |
||
68 | * [default_value] => CURRENT_TIMESTAMP |
||
69 | * ) |
||
70 | * ) |
||
71 | * @var array |
||
72 | */ |
||
73 | public $aMetaColumn = array(); |
||
74 | |||
75 | /** |
||
76 | * Table column name array, index is upper case of column name |
||
77 | * |
||
78 | * eg: array( |
||
79 | * 'COLUMN' => 'column', |
||
80 | * ) |
||
81 | * @var array |
||
82 | */ |
||
83 | public $aMetaColumnName = array(); |
||
84 | |||
85 | /** |
||
86 | * Primary key columns of table |
||
87 | * |
||
88 | * array( |
||
89 | * tbl_name -> 'col_pk', |
||
90 | * tbl_name -> array(pk_col1, pk_col2), |
||
91 | * ) |
||
92 | * @var array |
||
93 | */ |
||
94 | public $aMetaPrimaryKey = array(); |
||
95 | |||
96 | /** |
||
97 | * Sql generator object |
||
98 | * @var object |
||
99 | */ |
||
100 | protected $oSg; |
||
101 | |||
102 | /** |
||
103 | * Error msg |
||
104 | * @var string |
||
105 | */ |
||
106 | public $sErrorMsg = ''; |
||
107 | |||
108 | /** |
||
109 | * System charset |
||
110 | * |
||
111 | * In common, this is your php script/operation system charset |
||
112 | * @var string |
||
113 | */ |
||
114 | public $sSysCharset = 'utf8'; |
||
115 | |||
116 | |||
117 | /** |
||
118 | * construct |
||
119 | * |
||
120 | * <code> |
||
121 | * $dbprofile = array(type, host, user, pass, name, lang); |
||
122 | * type is mysql/sybase_ase etc, |
||
123 | * name is dbname to select, |
||
124 | * lang is db server charset. |
||
125 | * </code> |
||
126 | * @var param array $dbprofile |
||
127 | * @var param string $path_adodb Include path of original ADODB |
||
128 | */ |
||
129 | public function __construct ($dbprofile, $path_adodb = '') { |
||
143 | |||
144 | |||
145 | /** |
||
146 | * Overload __call, redirect method call to adodb |
||
147 | * |
||
148 | * @var string $name Method name |
||
149 | * @var array $arg Method argument |
||
150 | * @global int $i_db_query_times |
||
151 | * @return mixed |
||
152 | */ |
||
153 | public function __call ($name, $arg) { |
||
202 | |||
203 | |||
204 | /** |
||
205 | * Overload __get, redirect method call to adodb |
||
206 | * |
||
207 | * @param string $name |
||
208 | * @return mixed |
||
209 | */ |
||
210 | public function __get ($name) { |
||
213 | |||
214 | |||
215 | /** |
||
216 | * Overload __set, redirect method call to adodb |
||
217 | * |
||
218 | * @param string $name |
||
219 | * @param mixed $val |
||
220 | */ |
||
221 | public function __set ($name, $val) { |
||
224 | |||
225 | |||
226 | /** |
||
227 | } |
||
228 | * Connect, Add mysql 'set names utf8' |
||
229 | * |
||
230 | * <code> |
||
231 | * Obmit params(dbprofile was set in __construct): |
||
232 | * param $argHostname Host to connect to |
||
233 | * param $argUsername Userid to login |
||
234 | * param $argPassword Associated password |
||
235 | * param $argDatabaseName database |
||
236 | * </code> |
||
237 | * @param $forcenew Force new connection |
||
238 | * @return boolean |
||
239 | */ |
||
240 | public function Connect ($forcenew = false) { |
||
340 | |||
341 | |||
342 | /** |
||
343 | * Count how many db query have executed |
||
344 | * |
||
345 | * This function can be extend by subclass if you want to count on multi db objects. |
||
346 | * |
||
347 | * Can't count in Adodb::property, because need display is done by Controler, |
||
348 | * which will call View, but Adodb is property of Module, |
||
349 | * so we can only use global vars to save this value. |
||
350 | * @global int $i_db_query_times |
||
351 | */ |
||
352 | protected function CountDbQueryTimes () { |
||
356 | |||
357 | |||
358 | /** |
||
359 | * Delete rows by condition user given |
||
360 | * |
||
361 | * @param string $tbl |
||
362 | * @param string $cond Condition, can be where, having etc, raw sql string, not null. |
||
363 | * @return int -1 error/0 not found/N > 0 number of rows |
||
364 | */ |
||
365 | View Code Duplication | public function DelRow ($tbl, $cond) { |
|
378 | |||
379 | |||
380 | /** |
||
381 | * Convert recordset(simple array) or other string |
||
382 | * from db encoding to system encoding |
||
383 | * |
||
384 | * Use recursive mechanism, beware of loop hole. |
||
385 | * @param mixed &$s Source to convert |
||
386 | * @return mixed |
||
387 | */ |
||
388 | View Code Duplication | public function EncodingConvert (&$s) { |
|
401 | |||
402 | |||
403 | /** |
||
404 | * Convert data encoding |
||
405 | * from system(usually utf-8) to db |
||
406 | * |
||
407 | * Use recursive mechanism, beware of loop hole. |
||
408 | * @param mixed &$s Source to convert |
||
409 | * @return mixed |
||
410 | */ |
||
411 | View Code Duplication | public function EncodingConvertReverse (&$s) { |
|
424 | |||
425 | |||
426 | /** |
||
427 | * Generate SQL then exec it |
||
428 | * |
||
429 | * @param array $ar_sql Same as GenSql() |
||
430 | * @return object |
||
431 | * @see GenSql() |
||
432 | */ |
||
433 | public function ExecuteGenSql ($ar_sql) { |
||
436 | |||
437 | |||
438 | /** |
||
439 | * Find name of timestamp column of a table |
||
440 | * |
||
441 | * @param $tbl Table name |
||
442 | * @return string |
||
443 | */ |
||
444 | public function FindColTs ($tbl) { |
||
503 | |||
504 | |||
505 | /** |
||
506 | * Generate SQL statement |
||
507 | * |
||
508 | * User should avoid use SELECT/UPDATE/INSERT/DELETE simultaneously. |
||
509 | * |
||
510 | * Generate order by SQL statement format order. |
||
511 | * |
||
512 | * UPDATE/INSERT/DELETE is followed by [TBL_NAME], |
||
513 | * so need not use FROM. |
||
514 | * @param array $ar_sql Array(select=>..., from=>...) |
||
515 | * @return string |
||
516 | * @see SqlGenerator |
||
517 | */ |
||
518 | public function GenSql ($ar_sql) { |
||
526 | |||
527 | |||
528 | /** |
||
529 | * Generate SQL statement for Prepare |
||
530 | * |
||
531 | * value -> ? or :name, and quote chars removed |
||
532 | * @param array $ar_sql Same as GenSql() |
||
533 | * @return string |
||
534 | * @see GenSql() |
||
535 | * @see SqlGenerator |
||
536 | */ |
||
537 | public function GenSqlPrepare ($ar_sql) { |
||
543 | |||
544 | |||
545 | /** |
||
546 | * Get data from single table using PK |
||
547 | * |
||
548 | * $m_pk, $col, $col_pk support string split by ',' or array, like: |
||
549 | * 1. 'val' |
||
550 | * 2. 'val1, val2' |
||
551 | * 3. array('val1', 'val2') |
||
552 | * |
||
553 | * '*' can be used for $col, means all cols in table, this way can't use |
||
554 | * cache, not recommend. |
||
555 | * |
||
556 | * Notice: $col must indexed by number start from 0. |
||
557 | * |
||
558 | * Also, this function can be used to retrieve data from a table with |
||
559 | * single unique index, by assigning $col_pk to non-PK column. |
||
560 | * |
||
561 | * @param string $s_tbl |
||
562 | * @param mixed $m_pk PK value |
||
563 | * @param mixed $col Cols need to retrieve. |
||
564 | * @param mixed $col_pk PK column name, NULL to auto get. |
||
565 | * @return mixed Single/array, NULL if error occur. |
||
566 | */ |
||
567 | public function GetDataByPk ($s_tbl, $m_pk, $col = NULL, $col_pk = NULL) { |
||
637 | |||
638 | |||
639 | /** |
||
640 | * Get table schema |
||
641 | * |
||
642 | * @param string $table |
||
643 | * @param boolean $forcenew Force to retrieve instead of read from cache |
||
644 | * @return array |
||
645 | * @see $aMetaColumn |
||
646 | */ |
||
647 | public function GetMetaColumn ($table, $forcenew = false) { |
||
668 | |||
669 | |||
670 | /** |
||
671 | * Get table column name |
||
672 | * |
||
673 | * @param string $table |
||
674 | * @param boolean $forcenew Force to retrieve instead of read from cache |
||
675 | * @return array |
||
676 | * @see $aMetaColumnName |
||
677 | */ |
||
678 | public function GetMetaColumnName ($table, $forcenew = false) { |
||
684 | |||
685 | |||
686 | /** |
||
687 | * Get primary key column of a table |
||
688 | * |
||
689 | * @param string $table |
||
690 | * @param boolean $forcenew Force to retrieve instead of read from cache |
||
691 | * @return mixed Single string value or array when primary key contain multi columns. |
||
692 | * @see $aMetaPrimaryKey |
||
693 | */ |
||
694 | public function GetMetaPrimaryKey ($table, $forcenew = false) { |
||
780 | |||
781 | |||
782 | /** |
||
783 | * Get rows count by condition user given |
||
784 | * |
||
785 | * @param string $tbl |
||
786 | * @param string $cond Condition, can be where, having etc, raw sql string. |
||
787 | * @return int -1: error/N >= 0: number of rows |
||
788 | */ |
||
789 | View Code Duplication | public function GetRowCount ($tbl, $cond = '') { |
|
801 | |||
802 | |||
803 | /** |
||
804 | * Get delimiter between SQL for various db |
||
805 | * |
||
806 | * @return string |
||
807 | */ |
||
808 | public function GetSqlDelimiter () { |
||
819 | |||
820 | |||
821 | /** |
||
822 | * Get SQL: begin transaction |
||
823 | * |
||
824 | * @return string |
||
825 | */ |
||
826 | public function GetSqlTransBegin () { |
||
832 | |||
833 | |||
834 | /** |
||
835 | * Get SQL: commit transaction |
||
836 | * |
||
837 | * @return string |
||
838 | */ |
||
839 | public function GetSqlTransCommit () { |
||
842 | |||
843 | |||
844 | /** |
||
845 | * Get SQL: rollback transaction |
||
846 | * |
||
847 | * @return string |
||
848 | */ |
||
849 | public function GetSqlTransRollback () { |
||
852 | |||
853 | |||
854 | /** |
||
855 | * If current db is a mysql db. |
||
856 | * |
||
857 | * @return boolean |
||
858 | */ |
||
859 | public function IsDbMysql () { |
||
862 | |||
863 | |||
864 | /** |
||
865 | * If current db is a sybase db. |
||
866 | * |
||
867 | * @return boolean |
||
868 | */ |
||
869 | public function IsDbSybase () { |
||
873 | |||
874 | |||
875 | /** |
||
876 | * Is timestamp column's value is unique |
||
877 | * |
||
878 | * @return boolean |
||
879 | */ |
||
880 | public function IsTsUnique () { |
||
887 | |||
888 | |||
889 | /** |
||
890 | * Prepare and execute sql |
||
891 | * |
||
892 | * @param string $sql |
||
893 | * @param array $inputarr Optional parameters in sql |
||
894 | * @return object |
||
895 | */ |
||
896 | public function PExecute ($sql, $inputarr = false) { |
||
911 | |||
912 | |||
913 | /** |
||
914 | * Generate, prepare and exec SQL |
||
915 | * |
||
916 | * @param array $ar_sql Same as GenSql() |
||
917 | * @param array $inputarr Optional parameters in sql |
||
918 | * @return object |
||
919 | * @see GenSql() |
||
920 | */ |
||
921 | public function PExecuteGenSql ($ar_sql, $inputarr = false) { |
||
924 | |||
925 | |||
926 | /** |
||
927 | * Smarty quote string in sql, by check columns type |
||
928 | * |
||
929 | * @param string $table |
||
930 | * @param string $column |
||
931 | * @param mixed $val |
||
932 | * @return string |
||
933 | */ |
||
934 | View Code Duplication | public function QuoteValue ($table, $column, $val) { |
|
973 | |||
974 | |||
975 | /** |
||
976 | * If a table exists in db ? |
||
977 | * |
||
978 | * @param string $tbl |
||
979 | * @return boolean |
||
980 | */ |
||
981 | View Code Duplication | public function TblExists ($tbl) { |
|
999 | |||
1000 | |||
1001 | /** |
||
1002 | * Smart write data row(s) to table |
||
1003 | * |
||
1004 | * Will auto check row existence, and decide to use INSERT or UPDATE, |
||
1005 | * so PRIMARY KEY column must include in $data array. |
||
1006 | * Also, table must have primary key defined. |
||
1007 | * @param string $tbl Table which rows to write to |
||
1008 | * @param array $data Row(s) data, only one row(1-dim array, index is column name) |
||
1009 | * or some rows(2-dim array, index layer 1 MUST be number and |
||
1010 | * will not write to db). |
||
1011 | * @param string $mode A auto detect/U update/I insert, ignore case. |
||
1012 | * If you assign some rows, it's better not to set this to 0, |
||
1013 | * because it will only detect by the FIRST row data. |
||
1014 | * @return int Number of inserted or updated rows, -1 means some error, |
||
1015 | * 0 and upper are normal result. |
||
1016 | */ |
||
1017 | public function Write ($tbl, $data, $mode = 'A') { |
||
1148 | |||
1149 | |||
1150 | } // end of class Adodb |
||
1151 | ?> |
||
1152 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.