Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
83.33% |
10 / 12 |
CRAP | |
96.88% |
62 / 64 |
| DatabaseMigrator | |
0.00% |
0 / 1 |
|
83.33% |
10 / 12 |
23 | |
96.88% |
62 / 64 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
11 / 11 |
|||
| createAlterStatementList | |
100.00% |
1 / 1 |
3 | |
100.00% |
9 / 9 |
|||
| createDropAllProcedureStatementList | |
0.00% |
0 / 1 |
2.06 | |
75.00% |
3 / 4 |
|||
| migrateEntity | |
100.00% |
1 / 1 |
2 | |
100.00% |
10 / 10 |
|||
| setupEntityInDatabase | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
|||
| getTableMetaDataByEntity | |
0.00% |
0 / 1 |
4.03 | |
87.50% |
7 / 8 |
|||
| dropUnusedTables | |
100.00% |
1 / 1 |
4 | |
100.00% |
8 / 8 |
|||
| addStatementList | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| addAlterStatementList | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| getDropStoredProcedureStatementList | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| getAlterStatementList | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| getCreateStoredProcedureStatementList | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| <?php | |
| declare(strict_types = 1); | |
| namespace Siesta\Migration; | |
| use Siesta\Database\Connection; | |
| use Siesta\Database\CreateStatementFactory; | |
| use Siesta\Database\MetaData\DatabaseMetaData; | |
| use Siesta\Database\MetaData\TableMetaData; | |
| use Siesta\Database\MigrationStatementFactory; | |
| use Siesta\Database\StoredProcedureFactory; | |
| use Siesta\Model\DataModel; | |
| use Siesta\Model\Entity; | |
| /** | |
| * @author Gregor Müller | |
| */ | |
| class DatabaseMigrator | |
| { | |
| /** | |
| * @var Connection | |
| */ | |
| protected $connection; | |
| /** | |
| * @var DatabaseMetaData | |
| */ | |
| protected $databaseMetaData; | |
| /** | |
| * @var TableMetaData[] | |
| */ | |
| protected $databaseTableList; | |
| /** | |
| * @var MigrationStatementFactory | |
| */ | |
| protected $migrationStatementFactory; | |
| /** | |
| * @var StoredProcedureFactory | |
| */ | |
| protected $storedProcedureFactoy; | |
| /** | |
| * @var StoredProcedureMigrator | |
| */ | |
| protected $storedProcedureMigrator; | |
| /** | |
| * @var DataModel | |
| */ | |
| protected $dataModel; | |
| /** | |
| * list of table names that are also defined in the current datamodel | |
| * @var string[] | |
| */ | |
| protected $neededTableList; | |
| /** | |
| * @var string[] | |
| */ | |
| protected $dropStoredProcedureStatementList; | |
| /** | |
| * @var string[] | |
| */ | |
| protected $createStoredProcedureStatementList; | |
| /** | |
| * @var string[] | |
| */ | |
| protected $alterStatementList; | |
| /** | |
| * @param DataModel $dataModel | |
| * @param Connection $connection | |
| */ | |
| public function __construct(DataModel $dataModel, Connection $connection) | |
| { | |
| $this->dataModel = $dataModel; | |
| $this->connection = $connection; | |
| $this->databaseMetaData = $connection->getDatabaseMetaData(); | |
| $this->storedProcedureFactory = $connection->getStoredProcedureFactory(); | |
| $this->storedProcedureMigrator = new StoredProcedureMigrator($this->storedProcedureFactory); | |
| $this->migrationStatementFactory = $connection->getMigrationStatementFactory(); | |
| $this->neededTableList = [CreateStatementFactory::SEQUENCER_TABLE_NAME]; | |
| $this->dropStoredProcedureStatementList = []; | |
| $this->alterStatementList = []; | |
| $this->createStoredProcedureStatementList = []; | |
| } | |
| /** | |
| * @param bool $dropUnusedTables | |
| */ | |
| public function createAlterStatementList(bool $dropUnusedTables) | |
| { | |
| $this->createDropAllProcedureStatementList(); | |
| $factory = $this->connection->getCreateStatementFactory(); | |
| $this->addStatementList($factory->buildSequencer()); | |
| $this->databaseTableList = $this->databaseMetaData->getTableList(); | |
| foreach ($this->dataModel->getEntityList() as $entity) { | |
| $this->migrateEntity($entity); | |
| } | |
| if ($dropUnusedTables) { | |
| $this->dropUnusedTables(); | |
| } | |
| } | |
| /** | |
| * | |
| */ | |
| private function createDropAllProcedureStatementList() | |
| { | |
| $storedProcedureNameList = $this->databaseMetaData->getStoredProcedureList(); | |
| foreach ($storedProcedureNameList as $storedProcedureName) { | |
| $this->dropStoredProcedureStatementList[] = $this->storedProcedureFactory->createDropStatementForProcedureName($storedProcedureName); | |
| } | |
| } | |
| /** | |
| * @param Entity $entity | |
| * | |
| * @return void | |
| */ | |
| private function migrateEntity(Entity $entity) | |
| { | |
| $tableMetaData = $this->getTableMetaDataByEntity($entity); | |
| // if database entity does not exist, create it | |
| if ($tableMetaData === null) { | |
| $this->setupEntityInDatabase($entity); | |
| return; | |
| } | |
| // compare database with current model/schema | |
| $entityMigrator = new TableMigrator($this->migrationStatementFactory, $tableMetaData, $entity); | |
| $alterStatementList = $entityMigrator->createAlterStatementList(); | |
| $this->addAlterStatementList($alterStatementList); | |
| // create stored procedures | |
| $statementList = $this->storedProcedureMigrator->getMigrateProcedureStatementList($this->dataModel, $entity); | |
| $this->addStatementList($statementList); | |
| } | |
| /** | |
| * @param Entity $entity | |
| * | |
| * @return void | |
| */ | |
| private function setupEntityInDatabase(Entity $entity) | |
| { | |
| $factory = $this->connection->getCreateStatementFactory(); | |
| $this->addAlterStatementList($factory->buildCreateTable($entity)); | |
| if ($entity->getIsDelimit()) { | |
| $this->addAlterStatementList($factory->buildCreateDelimitTable($entity)); | |
| } | |
| $spMigrationList = $this->storedProcedureMigrator->getMigrateProcedureStatementList($this->dataModel, $entity); | |
| $this->addStatementList($spMigrationList); | |
| } | |
| /** | |
| * @param Entity $entity | |
| * | |
| * @return TableMetaData|null | |
| */ | |
| private function getTableMetaDataByEntity(Entity $entity) | |
| { | |
| $tableName = $entity->getTableName(); | |
| foreach ($this->databaseTableList as $tableMetaData) { | |
| if ($tableMetaData->getName() === $tableName) { | |
| $this->neededTableList[] = $tableName; | |
| if ($entity->getIsDelimit()) { | |
| $this->neededTableList[] = $entity->getDelimitTableName(); | |
| } | |
| // TODO: handle replication | |
| return $tableMetaData; | |
| } | |
| } | |
| return null; | |
| } | |
| /** | |
| * drops unused database tables | |
| * @return void | |
| */ | |
| private function dropUnusedTables() | |
| { | |
| foreach ($this->databaseTableList as $databaseTable) { | |
| if (in_array($databaseTable->getName(), $this->neededTableList)) { | |
| continue; | |
| } | |
| $statementList = $this->migrationStatementFactory->getDropTableStatement($databaseTable); | |
| foreach ($statementList as $statement) { | |
| $dropStatement = str_replace(MigrationStatementFactory::TABLE_PLACE_HOLDER, $databaseTable->getName(), $statement); | |
| $this->addAlterStatementList([$dropStatement]); | |
| } | |
| } | |
| } | |
| /** | |
| * @param array $statementList | |
| * | |
| * @return void | |
| */ | |
| private function addStatementList(array $statementList) | |
| { | |
| $this->createStoredProcedureStatementList = array_merge($this->createStoredProcedureStatementList, $statementList); | |
| } | |
| /** | |
| * @param array $alterStatementList | |
| */ | |
| private function addAlterStatementList(array $alterStatementList) | |
| { | |
| $this->alterStatementList = array_merge($this->alterStatementList, $alterStatementList); | |
| } | |
| /** | |
| * @return string[] | |
| */ | |
| public function getDropStoredProcedureStatementList() | |
| { | |
| return $this->dropStoredProcedureStatementList; | |
| } | |
| /** | |
| * will contain create table and alter table statements | |
| * @return String[] | |
| */ | |
| public function getAlterStatementList() | |
| { | |
| return $this->alterStatementList; | |
| } | |
| /** | |
| * will contain stored procedure create and drop statements as well as sequencer | |
| * @return String[] | |
| */ | |
| public function getCreateStoredProcedureStatementList() | |
| { | |
| return $this->createStoredProcedureStatementList; | |
| } | |
| } |