diff --git a/composer.json b/composer.json index 8a93f39..31a5e03 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "prefer-stable": true, "require": { "php": ">=8.0", - "cycle/orm": "^2.0", + "cycle/orm": "^2.7", "cycle/database": "^2.7.1", "yiisoft/friendly-exception": "^1.1" }, diff --git a/src/Compiler.php b/src/Compiler.php index 186b932..918bb49 100644 --- a/src/Compiler.php +++ b/src/Compiler.php @@ -84,6 +84,7 @@ private function compute(Registry $registry, Entity $entity): void Schema::FIND_BY_KEYS => $this->renderReferences($entity), Schema::TYPECAST => $this->renderTypecast($entity), Schema::RELATIONS => [], + Schema::GENERATED_FIELDS => $this->renderGeneratedFields($entity), ]; // For table inheritance we need to fill specific schema segments @@ -187,6 +188,18 @@ private function renderColumns(Entity $entity): array return $schema; } + private function renderGeneratedFields(Entity $entity): array + { + $schema = []; + foreach ($entity->getFields() as $name => $field) { + if ($field->getGenerated() !== null) { + $schema[$name] = $field->getGenerated(); + } + } + + return $schema; + } + private function renderTypecast(Entity $entity): array { $schema = []; diff --git a/src/Definition/Field.php b/src/Definition/Field.php index e21c540..cf73391 100644 --- a/src/Definition/Field.php +++ b/src/Definition/Field.php @@ -4,6 +4,7 @@ namespace Cycle\Schema\Definition; +use Cycle\ORM\Schema\GeneratedField; use Cycle\Schema\Definition\Map\OptionMap; use Cycle\Schema\Exception\FieldException; @@ -32,6 +33,8 @@ final class Field */ private array|string|null $typecast = null; + private ?int $generated = null; + private bool $referenced = false; private ?string $entityClass = null; @@ -138,6 +141,21 @@ public function getTypecast(): array|string|null return $this->typecast; } + /** + * @param int|null $type Generating type {@see GeneratedField*} constants. + */ + public function setGenerated(int|null $type): self + { + $this->generated = $type; + + return $this; + } + + public function getGenerated(): ?int + { + return $this->generated; + } + public function setReferenced(bool $indexed): self { $this->referenced = $indexed; diff --git a/tests/Schema/CompilerTest.php b/tests/Schema/CompilerTest.php index 776653f..c55a815 100644 --- a/tests/Schema/CompilerTest.php +++ b/tests/Schema/CompilerTest.php @@ -6,6 +6,7 @@ use Cycle\Database\DatabaseProviderInterface; use Cycle\ORM\Parser\Typecast; +use Cycle\ORM\Schema\GeneratedField; use Cycle\ORM\SchemaInterface; use Cycle\Schema\Compiler; use Cycle\Schema\Definition\Entity; @@ -18,7 +19,7 @@ use Cycle\Schema\Tests\Fixtures\Typecaster; use PHPUnit\Framework\TestCase; -class CompilerTest extends TestCase +final class CompilerTest extends TestCase { public function testWrongGeneratorShouldThrowAnException(): void { @@ -86,6 +87,46 @@ public function testRenderTypecast(mixed $expected, array $defaults, mixed $enti $this->assertSame($expected, $schema['author'][SchemaInterface::TYPECAST_HANDLER]); } + public function testRenderGeneratedFields(): void + { + $entity = new Entity(); + $entity->setRole('author')->setClass(Author::class); + $entity->getFields()->set('id', (new Field())->setType('primary')->setColumn('id')); + $entity->getFields()->set('name', (new Field())->setType('string')->setColumn('name')); + $entity->getFields()->set( + 'createdAt', + (new Field()) + ->setType('datetime') + ->setColumn('created_at') + ->setGenerated(GeneratedField::BEFORE_INSERT) + ); + $entity->getFields()->set( + 'updatedAt', + (new Field()) + ->setType('datetime') + ->setColumn('created_at') + ->setGenerated(GeneratedField::BEFORE_INSERT | GeneratedField::BEFORE_UPDATE) + ); + $entity->getFields()->set( + 'sequence', + (new Field()) + ->setType('serial') + ->setColumn('some_sequence') + ->setGenerated(GeneratedField::ON_INSERT) + ); + + $r = new Registry($this->createMock(DatabaseProviderInterface::class)); + $r->register($entity); + + $schema = (new Compiler())->compile($r); + + $this->assertSame([ + 'createdAt' => GeneratedField::BEFORE_INSERT, + 'updatedAt' => GeneratedField::BEFORE_INSERT | GeneratedField::BEFORE_UPDATE, + 'sequence' => GeneratedField::ON_INSERT, + ], $schema['author'][SchemaInterface::GENERATED_FIELDS]); + } + public static function renderTypecastDataProvider(): \Traversable { yield [null, []]; diff --git a/tests/Schema/Generator/TableGeneratorTest.php b/tests/Schema/Generator/TableGeneratorTest.php index c02a2ae..e26af39 100644 --- a/tests/Schema/Generator/TableGeneratorTest.php +++ b/tests/Schema/Generator/TableGeneratorTest.php @@ -67,6 +67,7 @@ public function testCompiled(): void Schema::TYPECAST => [], Schema::SCHEMA => [], Schema::TYPECAST_HANDLER => [Typecaster::class, 'default_typecaster'], + Schema::GENERATED_FIELDS => [], ], ], $schema); } @@ -103,6 +104,7 @@ public function testCompiledWithPassedDefaultTypecastHandler(): void Schema::TYPECAST => [], Schema::SCHEMA => [], Schema::TYPECAST_HANDLER => [Typecaster::class], + Schema::GENERATED_FIELDS => [], ], ], $schema); } @@ -171,6 +173,7 @@ public function testCompiledUser(): void Schema::TYPECAST_HANDLER => [ Typecaster::class, ], + Schema::GENERATED_FIELDS => [], ], ], $c->getSchema()); } @@ -203,6 +206,7 @@ public function testCompiledPost(): void Schema::TYPECAST => [], Schema::SCHEMA => [], Schema::TYPECAST_HANDLER => null, + Schema::GENERATED_FIELDS => [], ], ], $c->getSchema()); }