diff --git a/CHANGELOG.md b/CHANGELOG.md index a61863d..68a6c93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased] + +### Added + +- `Formal\ORM\Adapter\SQL\ShowCreateTable::ifNotExists()` + ## 3.3.0 - 2024-09-29 ### Added diff --git a/documentation/adapters/sql.md b/documentation/adapters/sql.md index 5398e15..e751010 100644 --- a/documentation/adapters/sql.md +++ b/documentation/adapters/sql.md @@ -110,6 +110,9 @@ CREATE TABLE `user` (`id` varchar(36) NOT NULL COMMENT 'UUID', `name` varchar( CREATE TABLE `user_addresses` (`aggregateId` varchar(36) NOT NULL COMMENT 'UUID', `street` longtext NOT NULL COMMENT 'TODO adjust the type depending on your use case', `zipCode` longtext NOT NULL COMMENT 'TODO adjust the type depending on your use case', `city` longtext NOT NULL COMMENT 'TODO adjust the type depending on your use case', CONSTRAINT `FK_user_addresses` FOREIGN KEY (`aggregateId`) REFERENCES `user`(`id`) ON DELETE CASCADE); ``` +??? tip + You can call `#!php $show->ifNotExists()(User::class)` to instead generate `CREATE TABLE IF NOT EXISTS` queries. + Instead of printing the queries you can execute them directly like this: ```php title="show_create_tables.php" hl_lines="8 15-17 19" diff --git a/proofs/adapter/sql/showCreateTable.php b/proofs/adapter/sql/showCreateTable.php index 7dd221f..9273973 100644 --- a/proofs/adapter/sql/showCreateTable.php +++ b/proofs/adapter/sql/showCreateTable.php @@ -54,6 +54,33 @@ static function($assert) { SQL, ]) ->same($queries); + + $queries = $show->ifNotExists()(User::class) + ->map(static fn($query) => $query->sql(Driver::mysql)) + ->toList(); + + $assert + ->expected([ + <<same($queries); }, )->tag(Storage::sql); diff --git a/src/Adapter/SQL/ShowCreateTable.php b/src/Adapter/SQL/ShowCreateTable.php index 00f2243..9fcbfa8 100644 --- a/src/Adapter/SQL/ShowCreateTable.php +++ b/src/Adapter/SQL/ShowCreateTable.php @@ -7,6 +7,8 @@ use Formal\AccessLayer\{ Query, Query\Constraint\ForeignKey, + Table\Name, + Table\Column, }; use Innmind\Immutable\Sequence; @@ -14,11 +16,19 @@ final class ShowCreateTable { private Aggregates $aggregates; private MapType $mapType; + private bool $ifNotExists; - private function __construct(Aggregates $aggregates) - { + /** + * @psalm-mutation-free + */ + private function __construct( + Aggregates $aggregates, + MapType $mapType, + bool $ifNotExists, + ) { $this->aggregates = $aggregates; - $this->mapType = MapType::new(); + $this->mapType = $mapType; + $this->ifNotExists = $ifNotExists; } /** @@ -30,10 +40,19 @@ public function __invoke(string $class): Sequence { $definition = $this->aggregates->get($class); $mainTable = MainTable::of($definition); + /** @psalm-suppress NamedArgumentNotAllowed */ + $create = match ($this->ifNotExists) { + true => static fn(Name $name, Column $first, Column ...$rest) => Query\CreateTable::ifNotExists( + $name, $first, ...$rest, + ), + false => static fn(Name $name, Column $first, Column ...$rest) => Query\CreateTable::named( + $name, $first, ...$rest, + ), + }; $entities = $mainTable ->entities() - ->map(fn($entity) => Query\CreateTable::named( + ->map(fn($entity) => $create( $entity->name()->name(), $entity->primaryKey(), ...$entity @@ -54,7 +73,7 @@ public function __invoke(string $class): Sequence ->toList(); $optionals = $mainTable ->optionals() - ->map(fn($optional) => Query\CreateTable::named( + ->map(fn($optional) => $create( $optional->name()->name(), $optional->primaryKey(), ...$optional @@ -77,7 +96,7 @@ public function __invoke(string $class): Sequence $collections = $mainTable ->collections() ->map( - fn($collection) => Query\CreateTable::named( + fn($collection) => $create( $collection->name()->name(), $collection->foreignKey(), ...$collection @@ -96,7 +115,7 @@ public function __invoke(string $class): Sequence ) ->toList(); - $main = Query\CreateTable::named( + $main = $create( $mainTable->name()->name(), $mainTable->primaryKey(), ...$mainTable @@ -114,6 +133,24 @@ public function __invoke(string $class): Sequence public static function of(Aggregates $aggregates): self { - return new self($aggregates); + return new self( + $aggregates, + MapType::new(), + false, + ); + } + + /** + * This will add the "IF NOT EXIST" to the sql queries + * + * @psalm-mutation-free + */ + public function ifNotExists(): self + { + return new self( + $this->aggregates, + $this->mapType, + true, + ); } }