Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
90.00% covered (success)
90.00%
9 / 10
CRAP
97.83% covered (success)
97.83%
45 / 46
AttributeListMigrator
0.00% covered (danger)
0.00%
0 / 1
90.00% covered (success)
90.00%
9 / 10
23
97.83% covered (success)
97.83%
45 / 46
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
7 / 7
 createAlterStatementList
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
11 / 11
 getColumnByAttribute
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
4 / 4
 createAlterStatement
0.00% covered (danger)
0.00%
0 / 1
8.02
93.33% covered (success)
93.33%
14 / 15
 addModifyStatementList
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 addAddStatementList
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 addDropStatementList
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getAddColumnStatementList
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getModifyColumnStatementList
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getDropColumnStatementList
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
<?php
declare(strict_types = 1);
namespace Siesta\Migration;
use Siesta\Database\MetaData\ColumnMetaData;
use Siesta\Database\MigrationStatementFactory;
use Siesta\Model\Attribute;
/**
 * @author Gregor Müller
 */
class AttributeListMigrator
{
    /**
     * @var ColumnMetaData[]
     */
    protected $columnList;
    /**
     * @var Attribute[]
     */
    protected $attributeList;
    /**
     * @var MigrationStatementFactory
     */
    protected $migrationStatementFactory;
    /**
     * @var string[]
     */
    protected $addStatementList;
    /**
     * @var string[]
     */
    protected $modifiyStatementList;
    /**
     * @var string[]
     */
    protected $dropStatementList;
    /**
     * AttributeListMigrator constructor.
     *
     * @param MigrationStatementFactory $migrationStatementFactory
     * @param ColumnMetaData[] $columnList
     * @param Attribute[] $attributeList
     */
    public function __construct(MigrationStatementFactory $migrationStatementFactory, array $columnList, array $attributeList)
    {
        $this->migrationStatementFactory = $migrationStatementFactory;
        $this->columnList = $columnList;
        $this->attributeList = $attributeList;
        $this->addStatementList = [];
        $this->modifiyStatementList = [];
        $this->dropStatementList = [];
    }
    /**
     * compares attribute list and column list and request the needed alter statements
     * @return void
     */
    public function createAlterStatementList()
    {
        $processedDatabaseList = [];
        // iterate attributes from model and retrieve alter statements
        foreach ($this->attributeList as $attribute) {
            // check if a corresponding database attribute exists
            $column = $this->getColumnByAttribute($attribute);
            // retrieve alter statements from migrator and add them
            $this->createAlterStatement($column, $attribute);
            // if a database attribute has been found add it to the processed list
            if ($column) {
                $processedDatabaseList[] = $column->getDBName();
            }
        }
        // iterate attributes from database and retrieve alter statements
        foreach ($this->columnList as $column) {
            // check if attribute has already been processed
            if (in_array($column->getDBName(), $processedDatabaseList)) {
                continue;
            }
            // no corresponding model attribute will result in drop statements
            $this->createAlterStatement($column, null);
        }
    }
    /**
     * @param Attribute $attribute
     *
     * @return null|ColumnMetaData
     */
    protected function getColumnByAttribute(Attribute $attribute)
    {
        foreach ($this->columnList as $column) {
            if ($column->getDBName() === $attribute->getDBName()) {
                return $column;
            }
        }
        return null;
    }
    /**
     * @param ColumnMetaData|null $column
     * @param Attribute|null $attribute
     */
    protected function createAlterStatement(ColumnMetaData $column = null, Attribute $attribute = null)
    {
        // no column create it
        if ($column === null) {
            if ($attribute !== null and $attribute->getIsTransient()) {
                return;
            }
            $addList =  $this->migrationStatementFactory->createAddColumnStatement($attribute);
            $this->addAddStatementList($addList);
            return;
        }
        // no attribute drop the column
        if ($attribute === null or $attribute->getIsTransient()) {
            $dropList = $this->migrationStatementFactory->createDropColumnStatement($column);
            $this->addDropStatementList($dropList);
            return;
        }
        // types identical nothing to do
        if ($column->getDBType() === $attribute->getDbType() and $column->getIsRequired() === $attribute->getIsRequired()) {
            return;
        }
        // types not identical
        $modifyList = $this->migrationStatementFactory->createModifiyColumnStatement($attribute);
        $this->addModifyStatementList($modifyList);
    }
    /**
     * @param array $statementList
     */
    protected function addModifyStatementList(array $statementList)
    {
        $this->modifiyStatementList = array_merge($this->modifiyStatementList, $statementList);
    }
    /**
     * @param array $statementList
     */
    protected function addAddStatementList(array $statementList)
    {
        $this->addStatementList = array_merge($this->addStatementList, $statementList);
    }
    /**
     * @param array $statementList
     */
    protected function addDropStatementList(array $statementList)
    {
        $this->dropStatementList = array_merge($this->dropStatementList, $statementList);
    }
    /**
     * @return string[]
     */
    public function getAddColumnStatementList()
    {
        return $this->addStatementList;
    }
    /**
     * @return string[]
     */
    public function getModifyColumnStatementList()
    {
        return $this->modifiyStatementList;
    }
    /**
     * @return string[]
     */
    public function getDropColumnStatementList()
    {
        return $this->dropStatementList;
    }
}