Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
10 / 10 |
CRAP | |
100.00% |
48 / 48 |
TableMigrator | |
100.00% |
1 / 1 |
|
100.00% |
10 / 10 |
17 | |
100.00% |
48 / 48 |
__construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
createAlterStatementList | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
assembleStatementList | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
getMigratePrimaryKeyStatementList | |
100.00% |
1 / 1 |
3 | |
100.00% |
7 / 7 |
|||
getEntityPrimaryKeyColumnList | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
getTablePrimaryKeyList | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
migrateAttributeList | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
migrateReferenceList | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
migrateIndexList | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
addStatementList | |
100.00% |
1 / 1 |
4 | |
100.00% |
5 / 5 |
<?php | |
declare(strict_types = 1); | |
namespace Siesta\Migration; | |
use Siesta\Database\MetaData\TableMetaData; | |
use Siesta\Database\MigrationStatementFactory; | |
use Siesta\Model\Entity; | |
/** | |
* @author Gregor Müller | |
*/ | |
class TableMigrator | |
{ | |
/** | |
* @var MigrationStatementFactory | |
*/ | |
protected $migrationStatementFactory; | |
/** | |
* @var TableMetaData | |
*/ | |
protected $tableMetaData; | |
/** | |
* @var Entity | |
*/ | |
protected $entity; | |
/** | |
* @var AttributeListMigrator | |
*/ | |
protected $attributeListMigrator; | |
/** | |
* @var ReferenceListMigrator | |
*/ | |
protected $referenceListMigrator; | |
/** | |
* @var IndexListMigrator | |
*/ | |
protected $indexListMigrator; | |
/** | |
* @var string[] | |
*/ | |
protected $alterStatementList; | |
/** | |
* TableMigrator constructor. | |
* | |
* @param MigrationStatementFactory $migrationStatementFactory | |
* @param TableMetaData $tableMetaData | |
* @param Entity $entity | |
*/ | |
public function __construct(MigrationStatementFactory $migrationStatementFactory, TableMetaData $tableMetaData, Entity $entity) | |
{ | |
$this->migrationStatementFactory = $migrationStatementFactory; | |
$this->tableMetaData = $tableMetaData; | |
$this->entity = $entity; | |
$this->alterStatementList = []; | |
} | |
/** | |
* returns the list of ALTER statement for the migration of the given database entity to the target model entity | |
* @return string[] | |
*/ | |
public function createAlterStatementList() | |
{ | |
$this->migrateAttributeList(); | |
$this->migrateReferenceList(); | |
$this->migrateIndexList(); | |
$this->assembleStatementList(); | |
return $this->alterStatementList; | |
} | |
/** | |
* brings the alter table statements into the right order. First indexes and foreign keys are dropped, then columns | |
* are added, existing ones are modified. Then the primary key is changed (if needed). Afterwards not needed | |
* columns are droped and finaly indexes and foreign key constraints are addedd. | |
* @return void | |
*/ | |
private function assembleStatementList() | |
{ | |
// drop foreign key and index | |
$this->addStatementList($this->referenceListMigrator->getDropForeignKeyStatementList()); | |
$this->addStatementList($this->indexListMigrator->getDropIndexStatementList()); | |
// add columns | |
$this->addStatementList($this->attributeListMigrator->getAddColumnStatementList(), true); | |
$this->addStatementList($this->attributeListMigrator->getModifyColumnStatementList(), true); | |
// modify primary key | |
$this->addStatementList($this->getMigratePrimaryKeyStatementList()); | |
// drop columns | |
$this->addStatementList($this->attributeListMigrator->getDropColumnStatementList(), true); | |
// add foreign key and index | |
$this->addStatementList($this->referenceListMigrator->getAddForeignKeyStatementList()); | |
$this->addStatementList($this->indexListMigrator->getAddIndexStatementList()); | |
} | |
/** | |
* compares the primary key column and generates migrate primary key statements if needed | |
* @return array | |
*/ | |
private function getMigratePrimaryKeyStatementList() | |
{ | |
$tablePrimaryKeyList = $this->getTablePrimaryKeyList($this->tableMetaData); | |
$entityPrimaryKeyList = $this->getEntityPrimaryKeyColumnList($this->entity); | |
$nonEntityPK = array_diff($tablePrimaryKeyList, $entityPrimaryKeyList); | |
$nonTablePK = array_diff($entityPrimaryKeyList, $tablePrimaryKeyList); | |
if (sizeof($nonEntityPK) === 0 && sizeof($nonTablePK) === 0) { | |
return []; | |
} | |
return $this->migrationStatementFactory->getModifyPrimaryKeyStatement($this->tableMetaData, $this->entity); | |
} | |
/** | |
* @param Entity $entity | |
* | |
* @return array | |
*/ | |
protected function getEntityPrimaryKeyColumnList(Entity $entity) | |
{ | |
$pkList = []; | |
foreach ($entity->getPrimaryKeyAttributeList() as $attribute) { | |
$pkList[] = $attribute->getDBName(); | |
} | |
return $pkList; | |
} | |
/** | |
* @param TableMetaData $tableMetaData | |
* | |
* @return array | |
*/ | |
protected function getTablePrimaryKeyList(TableMetaData $tableMetaData) | |
{ | |
$pkList = []; | |
foreach ($tableMetaData->getPrimaryKeyAttributeList() as $columnMetaData) { | |
$pkList[] = $columnMetaData->getDBName(); | |
} | |
return $pkList; | |
} | |
/** | |
* migrates the attributes of the entity and gathers add modify and drop statements | |
* @return void | |
*/ | |
private function migrateAttributeList() | |
{ | |
$this->attributeListMigrator = new AttributeListMigrator($this->migrationStatementFactory, $this->tableMetaData->getColumnList(), $this->entity->getAttributeList()); | |
$this->attributeListMigrator->createAlterStatementList(); | |
} | |
/** | |
* migrates the references of the entity and gathers add modify and drop statements for the used columns and add | |
* drop constraints statements | |
* @return void | |
*/ | |
private function migrateReferenceList() | |
{ | |
$this->referenceListMigrator = new ReferenceListMigrator($this->migrationStatementFactory, $this->tableMetaData->getConstraintList(), $this->entity->getReferenceList()); | |
$this->referenceListMigrator->createAlterStatementList(); | |
} | |
/** | |
* migrates the indexes of the entity and gathers drop and add statements | |
* @return void | |
*/ | |
private function migrateIndexList() | |
{ | |
$this->indexListMigrator = new IndexListMigrator($this->migrationStatementFactory, $this->tableMetaData->getIndexList(), $this->entity->getIndexList()); | |
$this->indexListMigrator->createAlterStatementList(); | |
} | |
/** | |
* adds a statement and replaces the table place holder against the real table. Considers delimited tables. | |
* | |
* @param string[] $statementList | |
* @param bool $isAttribute delimiter tables are only changed for the attributes | |
* | |
* @return void | |
*/ | |
private function addStatementList(array $statementList, $isAttribute = false) | |
{ | |
foreach ($statementList as $statement) { | |
$this->alterStatementList[] = str_replace(MigrationStatementFactory::TABLE_PLACE_HOLDER, $this->tableMetaData->getName(), $statement); | |
// handle delimited table | |
if ($this->entity->getIsDelimit() and $isAttribute) { | |
$this->alterStatementList[] = str_replace(MigrationStatementFactory::TABLE_PLACE_HOLDER, $this->entity->getDelimitTableName(), $statement); | |
} | |
// TODO : handle replication table | |
} | |
} | |
} |