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
98.18% covered (success)
98.18%
54 / 55
MySQLDeleteByCollectionManyStoredProcedure
0.00% covered (danger)
0.00%
0 / 1
90.00% covered (success)
90.00%
9 / 10
17
98.18% covered (success)
98.18%
54 / 55
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
8 / 8
 buildElements
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
6 / 6
 buildSignature
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
9 / 9
 buildStatement
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
6 / 6
 getJoinCondition
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
8 / 8
 getWhereCondition
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
11 / 11
 getCorrespondingColumnForPKAttribute
0.00% covered (danger)
0.00%
0 / 1
3.14
75.00% covered (success)
75.00%
3 / 4
 buildTableColumn
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 buildComparision
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 buildParameterName
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
<?php
declare(strict_types = 1);
namespace Siesta\Driver\MySQL\StoredProcedure;
use Siesta\Database\StoredProcedureNaming;
use Siesta\Model\Attribute;
use Siesta\Model\CollectionMany;
use Siesta\Model\DataModel;
use Siesta\Model\Entity;
use Siesta\Model\Reference;
class MySQLDeleteByCollectionManyStoredProcedure extends MySQLStoredProcedureBase
{
    const JOIN = "DELETE %s FROM %s LEFT JOIN %s ON %s WHERE %s;";
    /**
     * @var CollectionMany
     */
    protected $collectionMany;
    /**
     * @var Entity
     */
    protected $foreignEntity;
    /**
     * @var Reference
     */
    protected $foreignReference;
    /**
     * @var Entity
     */
    protected $mappingEntity;
    /**
     * @var Reference
     */
    protected $mappingReference;
    /**
     *
     */
    protected $reference;
    public function __construct(DataModel $dataModel, Entity $entity, CollectionMany $collectionMany)
    {
        parent::__construct($dataModel, $entity);
        $this->collectionMany = $collectionMany;
        $this->foreignEntity = $collectionMany->getForeignEntity();
        $this->foreignReference = $collectionMany->getForeignReference();
        $this->mappingEntity = $collectionMany->getMappingEntity();
        $this->mappingReference = $collectionMany->getMappingReference();
        $this->buildElements();
    }
    /**
     *
     */
    protected function buildElements()
    {
        $this->modifies = false;
        $this->name = StoredProcedureNaming::getDeleteByCollectionManyName($this->collectionMany);
        $this->determineTableNames();
        $this->buildSignature();
        $this->buildStatement();
    }
    /**
     * @return void
     */
    protected function buildSignature()
    {
        $signaturePart = [];
        foreach ($this->entity->getPrimaryKeyAttributeList() as $pkAttribute) {
            $parameterName = $this->buildParameterName($this->entity, $pkAttribute);
            $signaturePart[] = $this->buildSignatureParameter($parameterName, $pkAttribute->getDbType());
        }
        foreach ($this->foreignEntity->getPrimaryKeyAttributeList() as $pkAttribute) {
            $parameterName = $this->buildParameterName($this->foreignEntity, $pkAttribute);
            $signaturePart[] = $this->buildSignatureParameter($parameterName, $pkAttribute->getDbType());
        }
        $this->signature = $this->buildSignatureFromList($signaturePart);
    }
    /**
     *
     */
    protected function buildStatement()
    {
        $foreignTable = $this->quote($this->foreignEntity->getTableName());
        $mappingTable = $this->quote($this->mappingEntity->getTableName());
        $joinCondition = $this->getJoinCondition();
        $whereStatement = $this->getWhereCondition();
        $this->statement = sprintf(self::JOIN, $foreignTable, $foreignTable, $mappingTable, $joinCondition, $whereStatement);
    }
    /**
     *
     */
    protected function getJoinCondition() : string
    {
        $foreignTable = $this->foreignEntity->getTableName();
        $mappingTable = $this->mappingEntity->getTableName();
        $conditionList = [];
        foreach ($this->foreignEntity->getPrimaryKeyAttributeList() as $pkAttribute) {
            $mappingAttribute = $this->getCorrespondingColumnForPKAttribute($this->foreignReference, $pkAttribute);
            $foreignAttribute = $pkAttribute->getDBName();
            $conditionList[] = $this->buildComparision($foreignTable, $foreignAttribute, $mappingTable, $mappingAttribute);
        }
        return implode(",", $conditionList);
    }
    /**
     * @return string
     */
    protected function getWhereCondition() : string
    {
        $mappingTable = $this->mappingEntity->getTableName();
        $whereList = [];
        foreach ($this->entity->getPrimaryKeyAttributeList() as $pkAttribute) {
            $mappingAttribute = $this->getCorrespondingColumnForPKAttribute($this->mappingReference, $pkAttribute);
            $whereList[] = $this->buildTableColumn($mappingTable, $mappingAttribute) . ' = ' . $this->buildParameterName($this->entity, $pkAttribute);
        }
        foreach ($this->foreignEntity->getPrimaryKeyAttributeList() as $pkAttribute) {
            $mappingAttribute = $this->getCorrespondingColumnForPKAttribute($this->foreignReference, $pkAttribute);
            $mappingAttribute = $this->quote($mappingAttribute);
            $spParam = $this->buildParameterName($this->foreignEntity, $pkAttribute);
            $whereList[] = "($spParam IS NULL OR $mappingAttribute = $spParam)";
        }
        return implode(" AND ", $whereList);
    }
    /**
     * @param Reference $reference
     * @param Attribute $pkAttribute
     *
     * @return string
     */
    protected function getCorrespondingColumnForPKAttribute(Reference $reference, Attribute $pkAttribute) : string
    {
        foreach ($reference->getReferenceMappingList() as $referenceMapping) {
            if ($referenceMapping->getForeignAttributeName() === $pkAttribute->getDBName()) {
                return $referenceMapping->getLocalColumnName();
            }
        }
    }
    /**
     * @param string $tableName
     * @param string $columnName
     *
     * @return string
     */
    protected function buildTableColumn(string $tableName, string $columnName) : string
    {
        return $this->quote($tableName) . '.' . $this->quote($columnName);
    }
    /**
     * @param string $table1
     * @param string $column1
     * @param string $table2
     * @param string $column2
     *
     * @return string
     */
    protected function buildComparision(string $table1, string $column1, string $table2, string $column2) : string
    {
        return $this->buildTableColumn($table1, $column1) . ' = ' . $this->buildTableColumn($table2, $column2);
    }
    /**
     * @param Entity $entity
     * @param Attribute $attribute
     *
     * @return string
     */
    protected function buildParameterName(Entity $entity, Attribute $attribute)
    {
        return 'P_' . $entity->getTableName() . '_' . $attribute->getDBName();
    }
}