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 CreateStatement 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 CreateStatement, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 28 | class CreateStatement extends Statement |
||
| 29 | { |
||
| 30 | /** |
||
| 31 | * Options for `CREATE` statements. |
||
| 32 | * |
||
| 33 | * @var array |
||
| 34 | */ |
||
| 35 | public static $OPTIONS = array( |
||
| 36 | // CREATE TABLE |
||
| 37 | 'TEMPORARY' => 1, |
||
| 38 | |||
| 39 | // CREATE VIEW |
||
| 40 | 'OR REPLACE' => array(2, 'var='), |
||
| 41 | 'ALGORITHM' => array(3, 'var='), |
||
| 42 | // `DEFINER` is also used for `CREATE FUNCTION / PROCEDURE` |
||
| 43 | 'DEFINER' => array(4, 'expr='), |
||
| 44 | 'SQL SECURITY' => array(5, 'var'), |
||
| 45 | |||
| 46 | 'DATABASE' => 6, |
||
| 47 | 'EVENT' => 6, |
||
| 48 | 'FUNCTION' => 6, |
||
| 49 | 'INDEX' => 6, |
||
| 50 | 'UNIQUE INDEX' => 6, |
||
| 51 | 'FULLTEXT INDEX' => 6, |
||
| 52 | 'SPATIAL INDEX' => 6, |
||
| 53 | 'PROCEDURE' => 6, |
||
| 54 | 'SERVER' => 6, |
||
| 55 | 'TABLE' => 6, |
||
| 56 | 'TABLESPACE' => 6, |
||
| 57 | 'TRIGGER' => 6, |
||
| 58 | 'USER' => 6, |
||
| 59 | 'VIEW' => 6, |
||
| 60 | |||
| 61 | // CREATE TABLE |
||
| 62 | 'IF NOT EXISTS' => 7, |
||
| 63 | ); |
||
| 64 | |||
| 65 | /** |
||
| 66 | * All database options. |
||
| 67 | * |
||
| 68 | * @var array |
||
| 69 | */ |
||
| 70 | public static $DB_OPTIONS = array( |
||
| 71 | 'CHARACTER SET' => array(1, 'var='), |
||
| 72 | 'CHARSET' => array(1, 'var='), |
||
| 73 | 'DEFAULT CHARACTER SET' => array(1, 'var='), |
||
| 74 | 'DEFAULT CHARSET' => array(1, 'var='), |
||
| 75 | 'DEFAULT COLLATE' => array(2, 'var='), |
||
| 76 | 'COLLATE' => array(2, 'var='), |
||
| 77 | ); |
||
| 78 | |||
| 79 | /** |
||
| 80 | * All table options. |
||
| 81 | * |
||
| 82 | * @var array |
||
| 83 | */ |
||
| 84 | public static $TABLE_OPTIONS = array( |
||
| 85 | 'ENGINE' => array(1, 'var='), |
||
| 86 | 'AUTO_INCREMENT' => array(2, 'var='), |
||
| 87 | 'AVG_ROW_LENGTH' => array(3, 'var'), |
||
| 88 | 'CHARACTER SET' => array(4, 'var='), |
||
| 89 | 'CHARSET' => array(4, 'var='), |
||
| 90 | 'DEFAULT CHARACTER SET' => array(4, 'var='), |
||
| 91 | 'DEFAULT CHARSET' => array(4, 'var='), |
||
| 92 | 'CHECKSUM' => array(5, 'var'), |
||
| 93 | 'DEFAULT COLLATE' => array(6, 'var='), |
||
| 94 | 'COLLATE' => array(6, 'var='), |
||
| 95 | 'COMMENT' => array(7, 'var='), |
||
| 96 | 'CONNECTION' => array(8, 'var'), |
||
| 97 | 'DATA DIRECTORY' => array(9, 'var'), |
||
| 98 | 'DELAY_KEY_WRITE' => array(10, 'var'), |
||
| 99 | 'INDEX DIRECTORY' => array(11, 'var'), |
||
| 100 | 'INSERT_METHOD' => array(12, 'var'), |
||
| 101 | 'KEY_BLOCK_SIZE' => array(13, 'var'), |
||
| 102 | 'MAX_ROWS' => array(14, 'var'), |
||
| 103 | 'MIN_ROWS' => array(15, 'var'), |
||
| 104 | 'PACK_KEYS' => array(16, 'var'), |
||
| 105 | 'PASSWORD' => array(17, 'var'), |
||
| 106 | 'ROW_FORMAT' => array(18, 'var'), |
||
| 107 | 'TABLESPACE' => array(19, 'var'), |
||
| 108 | 'STORAGE' => array(20, 'var'), |
||
| 109 | 'UNION' => array(21, 'var'), |
||
| 110 | ); |
||
| 111 | |||
| 112 | /** |
||
| 113 | * All function options. |
||
| 114 | * |
||
| 115 | * @var array |
||
| 116 | */ |
||
| 117 | public static $FUNC_OPTIONS = array( |
||
| 118 | 'COMMENT' => array(1, 'var='), |
||
| 119 | 'LANGUAGE SQL' => 2, |
||
| 120 | 'DETERMINISTIC' => 3, |
||
| 121 | 'NOT DETERMINISTIC' => 3, |
||
| 122 | 'CONTAINS SQL' => 4, |
||
| 123 | 'NO SQL' => 4, |
||
| 124 | 'READS SQL DATA' => 4, |
||
| 125 | 'MODIFIES SQL DATA' => 4, |
||
| 126 | 'SQL SECURITY DEFINER' => array(5, 'var'), |
||
| 127 | ); |
||
| 128 | |||
| 129 | /** |
||
| 130 | * All trigger options. |
||
| 131 | * |
||
| 132 | * @var array |
||
| 133 | */ |
||
| 134 | public static $TRIGGER_OPTIONS = array( |
||
| 135 | 'BEFORE' => 1, |
||
| 136 | 'AFTER' => 1, |
||
| 137 | 'INSERT' => 2, |
||
| 138 | 'UPDATE' => 2, |
||
| 139 | 'DELETE' => 2, |
||
| 140 | ); |
||
| 141 | |||
| 142 | /** |
||
| 143 | * The name of the entity that is created. |
||
| 144 | * |
||
| 145 | * Used by all `CREATE` statements. |
||
| 146 | * |
||
| 147 | * @var Expression |
||
| 148 | */ |
||
| 149 | public $name; |
||
| 150 | |||
| 151 | /** |
||
| 152 | * The options of the entity (table, procedure, function, etc.). |
||
| 153 | * |
||
| 154 | * Used by `CREATE TABLE`, `CREATE FUNCTION` and `CREATE PROCEDURE`. |
||
| 155 | * |
||
| 156 | * @var OptionsArray |
||
| 157 | * |
||
| 158 | * @see static::$TABLE_OPTIONS |
||
| 159 | * @see static::$FUNC_OPTIONS |
||
| 160 | * @see static::$TRIGGER_OPTIONS |
||
| 161 | */ |
||
| 162 | public $entityOptions; |
||
| 163 | |||
| 164 | /** |
||
| 165 | * If `CREATE TABLE`, a list of columns and keys. |
||
| 166 | * If `CREATE VIEW`, a list of columns. |
||
| 167 | * |
||
| 168 | * Used by `CREATE TABLE` and `CREATE VIEW`. |
||
| 169 | * |
||
| 170 | * @var CreateDefinition[]|ArrayObj |
||
| 171 | */ |
||
| 172 | public $fields; |
||
| 173 | |||
| 174 | /** |
||
| 175 | * If `CREATE TABLE ... SELECT`. |
||
| 176 | * |
||
| 177 | * Used by `CREATE TABLE` |
||
| 178 | * |
||
| 179 | * @var SelectStatement |
||
| 180 | */ |
||
| 181 | public $select; |
||
| 182 | |||
| 183 | /** |
||
| 184 | * If `CREATE TABLE ... LIKE`. |
||
| 185 | * |
||
| 186 | * Used by `CREATE TABLE` |
||
| 187 | * |
||
| 188 | * @var Expression |
||
| 189 | */ |
||
| 190 | public $like; |
||
| 191 | |||
| 192 | /** |
||
| 193 | * Expression used for partitioning. |
||
| 194 | * |
||
| 195 | * @var string |
||
| 196 | */ |
||
| 197 | public $partitionBy; |
||
| 198 | |||
| 199 | /** |
||
| 200 | * The number of partitions. |
||
| 201 | * |
||
| 202 | * @var int |
||
| 203 | */ |
||
| 204 | public $partitionsNum; |
||
| 205 | |||
| 206 | /** |
||
| 207 | * Expression used for subpartitioning. |
||
| 208 | * |
||
| 209 | * @var string |
||
| 210 | */ |
||
| 211 | public $subpartitionBy; |
||
| 212 | |||
| 213 | /** |
||
| 214 | * The number of subpartitions. |
||
| 215 | * |
||
| 216 | * @var int |
||
| 217 | */ |
||
| 218 | public $subpartitionsNum; |
||
| 219 | |||
| 220 | /** |
||
| 221 | * The partition of the new table. |
||
| 222 | * |
||
| 223 | * @var PartitionDefinition[] |
||
| 224 | */ |
||
| 225 | public $partitions; |
||
| 226 | |||
| 227 | /** |
||
| 228 | * If `CREATE TRIGGER` the name of the table. |
||
| 229 | * |
||
| 230 | * Used by `CREATE TRIGGER`. |
||
| 231 | * |
||
| 232 | * @var Expression |
||
| 233 | */ |
||
| 234 | public $table; |
||
| 235 | |||
| 236 | /** |
||
| 237 | * The return data type of this routine. |
||
| 238 | * |
||
| 239 | * Used by `CREATE FUNCTION`. |
||
| 240 | * |
||
| 241 | * @var DataType |
||
| 242 | */ |
||
| 243 | public $return; |
||
| 244 | |||
| 245 | /** |
||
| 246 | * The parameters of this routine. |
||
| 247 | * |
||
| 248 | * Used by `CREATE FUNCTION` and `CREATE PROCEDURE`. |
||
| 249 | * |
||
| 250 | * @var ParameterDefinition[] |
||
| 251 | */ |
||
| 252 | public $parameters; |
||
| 253 | |||
| 254 | /** |
||
| 255 | * The body of this function or procedure. For views, it is the select |
||
| 256 | * statement that gets the. |
||
| 257 | * |
||
| 258 | * Used by `CREATE FUNCTION`, `CREATE PROCEDURE` and `CREATE VIEW`. |
||
| 259 | * |
||
| 260 | * @var Token[]|string |
||
| 261 | */ |
||
| 262 | public $body = array(); |
||
| 263 | |||
| 264 | /** |
||
| 265 | * @return string |
||
| 266 | */ |
||
| 267 | 9 | public function build() |
|
| 350 | |||
| 351 | /** |
||
| 352 | * @param Parser $parser the instance that requests parsing |
||
| 353 | * @param TokensList $list the list of tokens to be parsed |
||
| 354 | */ |
||
| 355 | 53 | public function parse(Parser $parser, TokensList $list) |
|
| 633 | } |
||
| 634 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.