Passed
Push — master ( 10a192...087136 )
by Aleksei
07:38 queued 05:42
created

Add   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 9
eloc 38
dl 0
loc 90
c 0
b 0
f 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B execute() 0 55 8
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license MIT
7
 * @author  Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Cycle\Migrations\Operation\ForeignKey;
13
14
use Cycle\Database\ForeignKeyInterface;
15
use Cycle\Migrations\CapsuleInterface;
16
use Cycle\Migrations\Exception\Operation\ForeignKeyException;
17
use Cycle\Migrations\Operation\Traits\OptionsTrait;
18
19
final class Add extends ForeignKey
20
{
21
    use OptionsTrait;
22
23
    /** @var string */
24
    protected $foreignTable = '';
25
26
    /** @var array */
27
    protected $foreignKeys = [];
28
29
    /**
30
     * AddReference constructor.
31
     *
32
     * @param string $table
33
     * @param array  $columns
34
     * @param string $foreignTable
35
     * @param array  $foreignKeys
36
     * @param array  $options
37
     */
38
    public function __construct(
39
        string $table,
40
        array $columns,
41
        string $foreignTable,
42
        array $foreignKeys,
43
        array $options
44
    ) {
45
        parent::__construct($table, $columns);
46
        $this->foreignTable = $foreignTable;
47
        $this->foreignKeys = $foreignKeys;
48
        $this->options = $options;
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function execute(CapsuleInterface $capsule): void
55
    {
56
        $schema = $capsule->getSchema($this->getTable());
57
58
        if ($schema->hasForeignKey($this->columns)) {
59
            throw new ForeignKeyException(
60
                "Unable to add foreign key '{$schema->getName()}'.({$this->columnNames()}), "
61
                . 'foreign key already exists'
62
            );
63
        }
64
65
        $foreignSchema = $capsule->getSchema($this->foreignTable);
66
67
        if ($this->foreignTable !== $this->table && !$foreignSchema->exists()) {
68
            throw new ForeignKeyException(
69
                "Unable to add foreign key '{$schema->getName()}'.'{$this->columnNames()}', "
70
                . "foreign table '{$this->foreignTable}' does not exists"
71
            );
72
        }
73
74
        foreach ($this->foreignKeys as $fk) {
75
            if ($this->foreignTable !== $this->table && !$foreignSchema->hasColumn($fk)) {
76
                throw new ForeignKeyException(
77
                    "Unable to add foreign key '{$schema->getName()}'.'{$this->columnNames()}',"
78
                    . " foreign column '{$this->foreignTable}'.'{$fk}' does not exists"
79
                );
80
            }
81
        }
82
83
        $foreignKey = $schema->foreignKey($this->columns)->references(
84
            $this->foreignTable,
85
            $this->foreignKeys
86
        );
87
88
        if ($this->hasOption('name')) {
89
            $foreignKey->setName($this->getOption('name'));
0 ignored issues
show
Bug introduced by
It seems like $this->getOption('name') can also be of type false and null; however, parameter $name of Cycle\Database\Schema\Ab...ctForeignKey::setName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

89
            $foreignKey->setName(/** @scrutinizer ignore-type */ $this->getOption('name'));
Loading history...
90
        }
91
92
        /*
93
         * We are allowing both formats "NO_ACTION" and "NO ACTION".
94
         */
95
96
        $foreignKey->onDelete(
97
            str_replace(
98
                '_',
99
                ' ',
100
                $this->getOption('delete', ForeignKeyInterface::NO_ACTION)
101
            )
102
        );
103
104
        $foreignKey->onUpdate(
105
            str_replace(
106
                '_',
107
                ' ',
108
                $this->getOption('update', ForeignKeyInterface::NO_ACTION)
109
            )
110
        );
111
    }
112
}
113