-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67: Add the ability to configure foreign keys
- Loading branch information
Showing
14 changed files
with
493 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\Schema\Definition; | ||
|
||
final class ForeignKey | ||
{ | ||
/** | ||
* @var non-empty-string | ||
*/ | ||
private string $target; | ||
|
||
/** | ||
* @var array<non-empty-string> | ||
*/ | ||
private array $innerColumns; | ||
|
||
/** | ||
* @var array<non-empty-string> | ||
*/ | ||
private array $outerColumns; | ||
|
||
private bool $createIndex; | ||
|
||
/** | ||
* @var non-empty-string | ||
*/ | ||
private string $action; | ||
|
||
/** | ||
* @param non-empty-string $target | ||
*/ | ||
public function setTarget(string $target): self | ||
{ | ||
$this->target = $target; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return non-empty-string | ||
*/ | ||
public function getTarget(): string | ||
{ | ||
return $this->target; | ||
} | ||
|
||
/** | ||
* @param array<non-empty-string> $columns | ||
*/ | ||
public function setInnerColumns(array $columns): self | ||
{ | ||
$this->innerColumns = $columns; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return array<non-empty-string> | ||
*/ | ||
public function getInnerColumns(): array | ||
{ | ||
return $this->innerColumns; | ||
} | ||
|
||
/** | ||
* @param array<non-empty-string> $columns | ||
*/ | ||
public function setOuterColumns(array $columns): self | ||
{ | ||
$this->outerColumns = $columns; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return array<non-empty-string> | ||
*/ | ||
public function getOuterColumns(): array | ||
{ | ||
return $this->outerColumns; | ||
} | ||
|
||
/** | ||
* Create an index on innerKey. | ||
*/ | ||
public function createIndex(bool $createIndex = true): self | ||
{ | ||
$this->createIndex = $createIndex; | ||
|
||
return $this; | ||
} | ||
|
||
public function isCreateIndex(): bool | ||
{ | ||
return $this->createIndex; | ||
} | ||
|
||
/** | ||
* @param non-empty-string $action | ||
*/ | ||
public function setAction(string $action): self | ||
{ | ||
$this->action = $action; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return non-empty-string | ||
*/ | ||
public function getAction(): string | ||
{ | ||
return $this->action; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\Schema\Definition\Map; | ||
|
||
use Cycle\Schema\Definition\ForeignKey; | ||
|
||
/** | ||
* Manage the set of foreign keys associated with the entity. | ||
* | ||
* @implements \IteratorAggregate<non-empty-string, ForeignKey> | ||
*/ | ||
final class ForeignKeyMap implements \IteratorAggregate, \Countable | ||
{ | ||
/** | ||
* @var array<non-empty-string, ForeignKey> | ||
*/ | ||
private array $foreignKeys = []; | ||
|
||
/** | ||
* Cloning. | ||
*/ | ||
public function __clone() | ||
{ | ||
foreach ($this->foreignKeys as $index => $foreignKey) { | ||
$this->foreignKeys[$index] = clone $foreignKey; | ||
} | ||
} | ||
|
||
public function has(ForeignKey $foreignKey): bool | ||
{ | ||
return isset($this->foreignKeys[$this->generateIdentifier($foreignKey)]); | ||
} | ||
|
||
public function set(ForeignKey $foreignKey): self | ||
{ | ||
$this->foreignKeys[$this->generateIdentifier($foreignKey)] = $foreignKey; | ||
|
||
return $this; | ||
} | ||
|
||
public function remove(ForeignKey $foreignKey): self | ||
{ | ||
unset($this->foreignKeys[$this->generateIdentifier($foreignKey)]); | ||
|
||
return $this; | ||
} | ||
|
||
public function count(): int | ||
{ | ||
return \count($this->foreignKeys); | ||
} | ||
|
||
public function getIterator(): \Traversable | ||
{ | ||
return new \ArrayIterator($this->foreignKeys); | ||
} | ||
|
||
/** | ||
* @return non-empty-string | ||
*/ | ||
private function generateIdentifier(ForeignKey $foreignKey): string | ||
{ | ||
return \sprintf( | ||
'%s:%s:%s', | ||
$foreignKey->getTarget(), | ||
\implode(',', $foreignKey->getInnerColumns()), | ||
\implode(',', $foreignKey->getOuterColumns()) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\Schema\Generator; | ||
|
||
use Cycle\Schema\GeneratorInterface; | ||
use Cycle\Schema\Registry; | ||
|
||
final class ForeignKeys implements GeneratorInterface | ||
{ | ||
public function run(Registry $registry): Registry | ||
{ | ||
foreach ($registry as $entity) { | ||
foreach ($entity->getForeignKeys() as $fk) { | ||
$target = $registry->getEntity($fk->getTarget()); | ||
|
||
if (!$registry->getTableSchema($target)->hasIndex($fk->getOuterColumns())) { | ||
$registry->getTableSchema($target)->index($fk->getOuterColumns())->unique(); | ||
} | ||
|
||
$registry->getTableSchema($entity) | ||
->foreignKey($fk->getInnerColumns(), $fk->isCreateIndex()) | ||
->references($registry->getTable($target), $fk->getOuterColumns()) | ||
->onUpdate($fk->getAction()) | ||
->onDelete($fk->getAction()); | ||
} | ||
} | ||
|
||
return $registry; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\Schema\Tests\Definition; | ||
|
||
use Cycle\Schema\Definition\ForeignKey; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
final class ForeignKeyTest extends TestCase | ||
{ | ||
public function testTarget(): void | ||
{ | ||
$key = new ForeignKey(); | ||
|
||
$key->setTarget('foo'); | ||
$this->assertSame('foo', $key->getTarget()); | ||
} | ||
|
||
public function testInnerColumns(): void | ||
{ | ||
$key = new ForeignKey(); | ||
|
||
$key->setInnerColumns(['field']); | ||
$this->assertSame(['field'], $key->getInnerColumns()); | ||
} | ||
|
||
public function testOuterColumns(): void | ||
{ | ||
$key = new ForeignKey(); | ||
|
||
$key->setOuterColumns(['field']); | ||
$this->assertSame(['field'], $key->getOuterColumns()); | ||
} | ||
|
||
public function testIndex(): void | ||
{ | ||
$key = new ForeignKey(); | ||
|
||
$key->createIndex(true); | ||
$this->assertTrue($key->isCreateIndex()); | ||
$key->createIndex(false); | ||
$this->assertFalse($key->isCreateIndex()); | ||
} | ||
|
||
public function testAction(): void | ||
{ | ||
$key = new ForeignKey(); | ||
|
||
$key->setAction('CASCADE'); | ||
$this->assertSame('CASCADE', $key->getAction()); | ||
} | ||
} |
Oops, something went wrong.