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 Table 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 Table, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 33 | class Table extends AbstractAsset |
||
| 34 | { |
||
| 35 | /** |
||
| 36 | * @var string |
||
| 37 | */ |
||
| 38 | protected $_name = null; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * @var Column[] |
||
| 42 | */ |
||
| 43 | protected $_columns = []; |
||
| 44 | |||
| 45 | /** |
||
| 46 | * @var Index[] |
||
| 47 | */ |
||
| 48 | private $implicitIndexes = []; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var Index[] |
||
| 52 | */ |
||
| 53 | protected $_indexes = []; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @var string |
||
| 57 | */ |
||
| 58 | protected $_primaryKeyName = false; |
||
| 59 | |||
| 60 | /** |
||
| 61 | * @var ForeignKeyConstraint[] |
||
| 62 | */ |
||
| 63 | protected $_fkConstraints = []; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * @var array |
||
| 67 | */ |
||
| 68 | protected $_options = []; |
||
| 69 | |||
| 70 | /** |
||
| 71 | * @var SchemaConfig |
||
| 72 | */ |
||
| 73 | protected $_schemaConfig = null; |
||
| 74 | |||
| 75 | /** |
||
| 76 | * @param string $tableName |
||
| 77 | * @param Column[] $columns |
||
| 78 | * @param Index[] $indexes |
||
| 79 | * @param ForeignKeyConstraint[] $fkConstraints |
||
| 80 | * @param integer $idGeneratorType |
||
| 81 | * @param array $options |
||
| 82 | * |
||
| 83 | * @throws DBALException |
||
| 84 | */ |
||
| 85 | 753 | public function __construct($tableName, array $columns=[], array $indexes=[], array $fkConstraints=[], $idGeneratorType = 0, array $options=[]) |
|
| 107 | |||
| 108 | /** |
||
| 109 | * @param SchemaConfig $schemaConfig |
||
| 110 | * |
||
| 111 | * @return void |
||
| 112 | */ |
||
| 113 | 61 | public function setSchemaConfig(SchemaConfig $schemaConfig) |
|
| 117 | |||
| 118 | /** |
||
| 119 | * @return integer |
||
| 120 | */ |
||
| 121 | 144 | protected function _getMaxIdentifierLength() |
|
| 129 | |||
| 130 | /** |
||
| 131 | * Sets the Primary Key. |
||
| 132 | * |
||
| 133 | * @param array $columns |
||
| 134 | * @param string|boolean $indexName |
||
| 135 | * |
||
| 136 | * @return self |
||
| 137 | */ |
||
| 138 | 314 | public function setPrimaryKey(array $columns, $indexName = false) |
|
| 149 | |||
| 150 | /** |
||
| 151 | * @param array $columnNames |
||
| 152 | * @param string|null $indexName |
||
| 153 | * @param array $flags |
||
| 154 | * @param array $options |
||
| 155 | * |
||
| 156 | * @return self |
||
| 157 | */ |
||
| 158 | 95 | View Code Duplication | public function addIndex(array $columnNames, $indexName = null, array $flags = [], array $options = []) |
| 168 | |||
| 169 | /** |
||
| 170 | * Drops the primary key from this table. |
||
| 171 | * |
||
| 172 | * @return void |
||
| 173 | */ |
||
| 174 | 13 | public function dropPrimaryKey() |
|
| 179 | |||
| 180 | /** |
||
| 181 | * Drops an index from this table. |
||
| 182 | * |
||
| 183 | * @param string $indexName The index name. |
||
| 184 | * |
||
| 185 | * @return void |
||
| 186 | * |
||
| 187 | * @throws SchemaException If the index does not exist. |
||
| 188 | */ |
||
| 189 | 25 | View Code Duplication | public function dropIndex($indexName) |
| 197 | |||
| 198 | /** |
||
| 199 | * @param array $columnNames |
||
| 200 | * @param string|null $indexName |
||
| 201 | * @param array $options |
||
| 202 | * |
||
| 203 | * @return self |
||
| 204 | */ |
||
| 205 | 29 | View Code Duplication | public function addUniqueIndex(array $columnNames, $indexName = null, array $options = []) |
| 215 | |||
| 216 | /** |
||
| 217 | * Renames an index. |
||
| 218 | * |
||
| 219 | * @param string $oldIndexName The name of the index to rename from. |
||
| 220 | * @param string|null $newIndexName The name of the index to rename to. |
||
| 221 | * If null is given, the index name will be auto-generated. |
||
| 222 | * |
||
| 223 | * @return self This table instance. |
||
| 224 | * |
||
| 225 | * @throws SchemaException if no index exists for the given current name |
||
| 226 | * or if an index with the given new name already exists on this table. |
||
| 227 | */ |
||
| 228 | 13 | public function renameIndex($oldIndexName, $newIndexName = null) |
|
| 261 | |||
| 262 | /** |
||
| 263 | * Checks if an index begins in the order of the given columns. |
||
| 264 | * |
||
| 265 | * @param array $columnsNames |
||
| 266 | * |
||
| 267 | * @return boolean |
||
| 268 | */ |
||
| 269 | 1 | public function columnsAreIndexed(array $columnsNames) |
|
| 270 | { |
||
| 271 | 1 | foreach ($this->getIndexes() as $index) { |
|
| 272 | /* @var $index Index */ |
||
| 273 | 1 | if ($index->spansColumns($columnsNames)) { |
|
| 274 | 1 | return true; |
|
| 275 | } |
||
| 276 | } |
||
| 277 | |||
| 278 | return false; |
||
| 279 | } |
||
| 280 | |||
| 281 | /** |
||
| 282 | * @param array $columnNames |
||
| 283 | * @param string $indexName |
||
| 284 | * @param boolean $isUnique |
||
| 285 | * @param boolean $isPrimary |
||
| 286 | * @param array $flags |
||
| 287 | * @param array $options |
||
| 288 | * |
||
| 289 | * @return Index |
||
| 290 | * |
||
| 291 | * @throws SchemaException |
||
| 292 | */ |
||
| 293 | 450 | private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = [], array $options = []) |
|
| 311 | |||
| 312 | /** |
||
| 313 | * @param string $columnName |
||
| 314 | * @param string $typeName |
||
| 315 | * @param array $options |
||
| 316 | * |
||
| 317 | * @return Column |
||
| 318 | */ |
||
| 319 | 607 | public function addColumn($columnName, $typeName, array $options=[]) |
|
| 327 | |||
| 328 | /** |
||
| 329 | * Renames a Column. |
||
| 330 | * |
||
| 331 | * @param string $oldColumnName |
||
| 332 | * @param string $newColumnName |
||
| 333 | * |
||
| 334 | * @deprecated |
||
| 335 | * |
||
| 336 | * @throws DBALException |
||
| 337 | */ |
||
| 338 | public function renameColumn($oldColumnName, $newColumnName) |
||
| 344 | |||
| 345 | /** |
||
| 346 | * Change Column Details. |
||
| 347 | * |
||
| 348 | * @param string $columnName |
||
| 349 | * @param array $options |
||
| 350 | * |
||
| 351 | * @return self |
||
| 352 | */ |
||
| 353 | 12 | public function changeColumn($columnName, array $options) |
|
| 360 | |||
| 361 | /** |
||
| 362 | * Drops a Column from the Table. |
||
| 363 | * |
||
| 364 | * @param string $columnName |
||
| 365 | * |
||
| 366 | * @return self |
||
| 367 | */ |
||
| 368 | 9 | public function dropColumn($columnName) |
|
| 375 | |||
| 376 | /** |
||
| 377 | * Adds a foreign key constraint. |
||
| 378 | * |
||
| 379 | * Name is inferred from the local columns. |
||
| 380 | * |
||
| 381 | * @param Table|string $foreignTable Table schema instance or table name |
||
| 382 | * @param array $localColumnNames |
||
| 383 | * @param array $foreignColumnNames |
||
| 384 | * @param array $options |
||
| 385 | * @param string|null $constraintName |
||
| 386 | * |
||
| 387 | * @return self |
||
| 388 | */ |
||
| 389 | 95 | public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=[], $constraintName = null) |
|
| 395 | |||
| 396 | /** |
||
| 397 | * Adds a foreign key constraint. |
||
| 398 | * |
||
| 399 | * Name is to be generated by the database itself. |
||
| 400 | * |
||
| 401 | * @deprecated Use {@link addForeignKeyConstraint} |
||
| 402 | * |
||
| 403 | * @param Table|string $foreignTable Table schema instance or table name |
||
| 404 | * @param array $localColumnNames |
||
| 405 | * @param array $foreignColumnNames |
||
| 406 | * @param array $options |
||
| 407 | * |
||
| 408 | * @return self |
||
| 409 | */ |
||
| 410 | 5 | public function addUnnamedForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=[]) |
|
| 414 | |||
| 415 | /** |
||
| 416 | * Adds a foreign key constraint with a given name. |
||
| 417 | * |
||
| 418 | * @deprecated Use {@link addForeignKeyConstraint} |
||
| 419 | * |
||
| 420 | * @param string $name |
||
| 421 | * @param Table|string $foreignTable Table schema instance or table name |
||
| 422 | * @param array $localColumnNames |
||
| 423 | * @param array $foreignColumnNames |
||
| 424 | * @param array $options |
||
| 425 | * |
||
| 426 | * @return self |
||
| 427 | * |
||
| 428 | * @throws SchemaException |
||
| 429 | */ |
||
| 430 | 96 | public function addNamedForeignKeyConstraint($name, $foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=[]) |
|
| 453 | |||
| 454 | /** |
||
| 455 | * @param string $name |
||
| 456 | * @param string $value |
||
| 457 | * |
||
| 458 | * @return self |
||
| 459 | */ |
||
| 460 | 35 | public function addOption($name, $value) |
|
| 466 | |||
| 467 | /** |
||
| 468 | * @param Column $column |
||
| 469 | * |
||
| 470 | * @return void |
||
| 471 | * |
||
| 472 | * @throws SchemaException |
||
| 473 | */ |
||
| 474 | 637 | protected function _addColumn(Column $column) |
|
| 485 | |||
| 486 | /** |
||
| 487 | * Adds an index to the table. |
||
| 488 | * |
||
| 489 | * @param Index $indexCandidate |
||
| 490 | * |
||
| 491 | * @return self |
||
| 492 | * |
||
| 493 | * @throws SchemaException |
||
| 494 | */ |
||
| 495 | 455 | protected function _addIndex(Index $indexCandidate) |
|
| 525 | |||
| 526 | /** |
||
| 527 | * @param ForeignKeyConstraint $constraint |
||
| 528 | * |
||
| 529 | * @return void |
||
| 530 | */ |
||
| 531 | 97 | protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint) |
|
| 565 | |||
| 566 | /** |
||
| 567 | * Returns whether this table has a foreign key constraint with the given name. |
||
| 568 | * |
||
| 569 | * @param string $constraintName |
||
| 570 | * |
||
| 571 | * @return boolean |
||
| 572 | */ |
||
| 573 | 10 | public function hasForeignKey($constraintName) |
|
| 579 | |||
| 580 | /** |
||
| 581 | * Returns the foreign key constraint with the given name. |
||
| 582 | * |
||
| 583 | * @param string $constraintName The constraint name. |
||
| 584 | * |
||
| 585 | * @return ForeignKeyConstraint |
||
| 586 | * |
||
| 587 | * @throws SchemaException If the foreign key does not exist. |
||
| 588 | */ |
||
| 589 | 8 | View Code Duplication | public function getForeignKey($constraintName) |
| 598 | |||
| 599 | /** |
||
| 600 | * Removes the foreign key constraint with the given name. |
||
| 601 | * |
||
| 602 | * @param string $constraintName The constraint name. |
||
| 603 | * |
||
| 604 | * @return void |
||
| 605 | * |
||
| 606 | * @throws SchemaException |
||
| 607 | */ |
||
| 608 | 10 | View Code Duplication | public function removeForeignKey($constraintName) |
| 617 | |||
| 618 | /** |
||
| 619 | * Returns ordered list of columns (primary keys are first, then foreign keys, then the rest) |
||
| 620 | * @return Column[] |
||
| 621 | */ |
||
| 622 | 447 | public function getColumns() |
|
| 631 | |||
| 632 | /** |
||
| 633 | * Returns foreign key columns |
||
| 634 | * @return Column[] |
||
| 635 | */ |
||
| 636 | 447 | private function getForeignKeyColumns() |
|
| 645 | |||
| 646 | /** |
||
| 647 | * Returns only columns that have specified names |
||
| 648 | * @param array $columnNames |
||
| 649 | * @return Column[] |
||
| 650 | */ |
||
| 651 | private function filterColumns(array $columnNames) |
||
| 657 | |||
| 658 | /** |
||
| 659 | * Returns whether this table has a Column with the given name. |
||
| 660 | * |
||
| 661 | * @param string $columnName The column name. |
||
| 662 | * |
||
| 663 | * @return boolean |
||
| 664 | */ |
||
| 665 | 518 | public function hasColumn($columnName) |
|
| 671 | |||
| 672 | /** |
||
| 673 | * Returns the Column with the given name. |
||
| 674 | * |
||
| 675 | * @param string $columnName The column name. |
||
| 676 | * |
||
| 677 | * @return Column |
||
| 678 | * |
||
| 679 | * @throws SchemaException If the column does not exist. |
||
| 680 | */ |
||
| 681 | 397 | public function getColumn($columnName) |
|
| 690 | |||
| 691 | /** |
||
| 692 | * Returns the primary key. |
||
| 693 | * |
||
| 694 | * @return Index|null The primary key, or null if this Table has no primary key. |
||
| 695 | */ |
||
| 696 | 214 | public function getPrimaryKey() |
|
| 704 | |||
| 705 | /** |
||
| 706 | * Returns the primary key columns. |
||
| 707 | * |
||
| 708 | * @return array |
||
| 709 | * |
||
| 710 | * @throws DBALException |
||
| 711 | */ |
||
| 712 | 9 | public function getPrimaryKeyColumns() |
|
| 719 | |||
| 720 | /** |
||
| 721 | * Returns whether this table has a primary key. |
||
| 722 | * |
||
| 723 | * @return boolean |
||
| 724 | */ |
||
| 725 | 455 | public function hasPrimaryKey() |
|
| 729 | |||
| 730 | /** |
||
| 731 | * Returns whether this table has an Index with the given name. |
||
| 732 | * |
||
| 733 | * @param string $indexName The index name. |
||
| 734 | * |
||
| 735 | * @return boolean |
||
| 736 | */ |
||
| 737 | 264 | public function hasIndex($indexName) |
|
| 743 | |||
| 744 | /** |
||
| 745 | * Returns the Index with the given name. |
||
| 746 | * |
||
| 747 | * @param string $indexName The index name. |
||
| 748 | * |
||
| 749 | * @return Index |
||
| 750 | * |
||
| 751 | * @throws SchemaException If the index does not exist. |
||
| 752 | */ |
||
| 753 | 242 | View Code Duplication | public function getIndex($indexName) |
| 762 | |||
| 763 | /** |
||
| 764 | * @return Index[] |
||
| 765 | */ |
||
| 766 | 423 | public function getIndexes() |
|
| 770 | |||
| 771 | /** |
||
| 772 | * Returns the foreign key constraints. |
||
| 773 | * |
||
| 774 | * @return ForeignKeyConstraint[] |
||
| 775 | */ |
||
| 776 | 460 | public function getForeignKeys() |
|
| 780 | |||
| 781 | /** |
||
| 782 | * @param string $name |
||
| 783 | * |
||
| 784 | * @return boolean |
||
| 785 | */ |
||
| 786 | 51 | public function hasOption($name) |
|
| 790 | |||
| 791 | /** |
||
| 792 | * @param string $name |
||
| 793 | * |
||
| 794 | * @return mixed |
||
| 795 | */ |
||
| 796 | 5 | public function getOption($name) |
|
| 800 | |||
| 801 | /** |
||
| 802 | * @return array |
||
| 803 | */ |
||
| 804 | 334 | public function getOptions() |
|
| 808 | |||
| 809 | /** |
||
| 810 | * @param Visitor $visitor |
||
| 811 | * |
||
| 812 | * @return void |
||
| 813 | */ |
||
| 814 | 18 | public function visit(Visitor $visitor) |
|
| 830 | |||
| 831 | /** |
||
| 832 | * Clone of a Table triggers a deep clone of all affected assets. |
||
| 833 | * |
||
| 834 | * @return void |
||
| 835 | */ |
||
| 836 | 50 | public function __clone() |
|
| 849 | |||
| 850 | /** |
||
| 851 | * Normalizes a given identifier. |
||
| 852 | * |
||
| 853 | * Trims quotes and lowercases the given identifier. |
||
| 854 | * |
||
| 855 | * @param string $identifier The identifier to normalize. |
||
| 856 | * |
||
| 857 | * @return string The normalized identifier. |
||
| 858 | */ |
||
| 859 | 641 | private function normalizeIdentifier($identifier) |
|
| 863 | } |
||
| 864 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.