From 6a1e6fd76e320d6e28e4c2e800a6bbd237590df8 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Thu, 27 Apr 2023 17:03:58 +0300 Subject: [PATCH 1/3] Add readonlySchema to the Column annotation --- src/Annotation/Column.php | 7 +++++++ src/Configurator.php | 4 ++++ tests/Annotated/Fixtures/Fixtures1/Simple.php | 6 ++++++ .../Functional/Driver/Common/TableTest.php | 17 +++++++++++++++++ tests/Annotated/Unit/Attribute/ColumnTest.php | 17 +++++++++++++++++ 5 files changed, 51 insertions(+) diff --git a/src/Annotation/Column.php b/src/Annotation/Column.php index f4e80a98..b36ff7b0 100644 --- a/src/Annotation/Column.php +++ b/src/Annotation/Column.php @@ -45,6 +45,7 @@ final class Column * If you want to use another rule you should add in the `typecast` argument of the {@see Entity} attribute * a relevant Typecast handler that supports the rule. * @param bool $castDefault + * @param bool $readonlySchema Set to true to disable schema synchronization for the assigned column. * @param mixed ...$attributes Other database specific attributes. Use named notation to define them. * For example: #[Column('smallInt', unsigned: true, zerofill: true)] */ @@ -68,6 +69,7 @@ public function __construct( private mixed $default = null, private mixed $typecast = null, private bool $castDefault = false, + private bool $readonlySchema = false, mixed ...$attributes, ) { if ($default !== null) { @@ -121,6 +123,11 @@ public function getTypecast(): mixed return $this->typecast; } + public function isReadonlySchema(): bool + { + return $this->readonlySchema; + } + /** * @return array */ diff --git a/src/Configurator.php b/src/Configurator.php index b26e8ccf..67c126dd 100644 --- a/src/Configurator.php +++ b/src/Configurator.php @@ -243,6 +243,10 @@ public function initField(string $name, Column $column, \ReflectionClass $class, $field->getOptions()->set(\Cycle\Schema\Table\Column::OPT_CAST_DEFAULT, true); } + if ($column->isReadonlySchema()) { + $field->getAttributes()->set('readOnly', true); + } + foreach ($column->getAttributes() as $k => $v) { $field->getAttributes()->set($k, $v); } diff --git a/tests/Annotated/Fixtures/Fixtures1/Simple.php b/tests/Annotated/Fixtures/Fixtures1/Simple.php index 21f21db3..baa5fd0b 100644 --- a/tests/Annotated/Fixtures/Fixtures1/Simple.php +++ b/tests/Annotated/Fixtures/Fixtures1/Simple.php @@ -66,4 +66,10 @@ class Simple implements LabelledInterface */ #[MorphedHasMany(target: 'Label', outerKey: 'owner_id', morphKey: 'owner_role', indexCreate: false, collection: Collection\BaseCollection::class)] // phpcs:ignore protected $labels; + + /** + * @Column(type="string", readonlySchema=true) + */ + #[Column(type: 'string', readonlySchema: true)] + protected string $readOnlyColumn; } diff --git a/tests/Annotated/Functional/Driver/Common/TableTest.php b/tests/Annotated/Functional/Driver/Common/TableTest.php index a14e3c95..96690d14 100644 --- a/tests/Annotated/Functional/Driver/Common/TableTest.php +++ b/tests/Annotated/Functional/Driver/Common/TableTest.php @@ -290,4 +290,21 @@ public function testNamingNone(ReaderInterface $reader): void $this->assertSame('with_table', $schema->getName()); } + + /** + * @dataProvider allReadersProvider + */ + public function testReadOnly(ReaderInterface $reader): void + { + $r = new Registry($this->dbal); + (new Entities($this->locator, $reader))->run($r); + (new MergeColumns($reader))->run($r); + (new RenderTables())->run($r); + + $this->assertTrue($r->hasTable($r->getEntity('simple'))); + + $schema = $r->getTableSchema($r->getEntity('simple')); + + $this->assertTrue($schema->column('read_only_column')->isReadOnly()); + } } diff --git a/tests/Annotated/Unit/Attribute/ColumnTest.php b/tests/Annotated/Unit/Attribute/ColumnTest.php index 009049fd..86d805b5 100644 --- a/tests/Annotated/Unit/Attribute/ColumnTest.php +++ b/tests/Annotated/Unit/Attribute/ColumnTest.php @@ -19,6 +19,9 @@ class ColumnTest extends TestCase #[Column('string(32)', size: 128)] private $column3; + #[Column('string(32)', readonlySchema: true)] + private mixed $column4; + public function testOneAttribute(): void { $attr = $this->getAttribute('column1'); @@ -40,6 +43,20 @@ public function testCustomSizeAttribute(): void $this->assertSame(['size' => 128], $attr->getAttributes()); } + public function testDefaultReadOnly(): void + { + $attr = $this->getAttribute('column1'); + + $this->assertFalse($attr->isReadonlySchema()); + } + + public function testReadOnly(): void + { + $attr = $this->getAttribute('column4'); + + $this->assertTrue($attr->isReadonlySchema()); + } + private function getAttribute(string $field): Column { $ref = new ReflectionClass(static::class); From 5d40838cf9d67b1dc897f7b61ebaf6b22a74c3ad Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Fri, 12 May 2023 17:56:18 +0300 Subject: [PATCH 2/3] Rename readonly attribute --- src/Configurator.php | 2 +- tests/Annotated/Functional/Driver/Common/TableTest.php | 4 ++-- tests/Annotated/Unit/Attribute/ColumnTest.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Configurator.php b/src/Configurator.php index 67c126dd..d4000066 100644 --- a/src/Configurator.php +++ b/src/Configurator.php @@ -244,7 +244,7 @@ public function initField(string $name, Column $column, \ReflectionClass $class, } if ($column->isReadonlySchema()) { - $field->getAttributes()->set('readOnly', true); + $field->getAttributes()->set('readonlySchema', true); } foreach ($column->getAttributes() as $k => $v) { diff --git a/tests/Annotated/Functional/Driver/Common/TableTest.php b/tests/Annotated/Functional/Driver/Common/TableTest.php index 96690d14..4cf13b84 100644 --- a/tests/Annotated/Functional/Driver/Common/TableTest.php +++ b/tests/Annotated/Functional/Driver/Common/TableTest.php @@ -294,7 +294,7 @@ public function testNamingNone(ReaderInterface $reader): void /** * @dataProvider allReadersProvider */ - public function testReadOnly(ReaderInterface $reader): void + public function testReadonlySchema(ReaderInterface $reader): void { $r = new Registry($this->dbal); (new Entities($this->locator, $reader))->run($r); @@ -305,6 +305,6 @@ public function testReadOnly(ReaderInterface $reader): void $schema = $r->getTableSchema($r->getEntity('simple')); - $this->assertTrue($schema->column('read_only_column')->isReadOnly()); + $this->assertTrue($schema->column('read_only_column')->isReadonlySchema()); } } diff --git a/tests/Annotated/Unit/Attribute/ColumnTest.php b/tests/Annotated/Unit/Attribute/ColumnTest.php index 86d805b5..4f638c29 100644 --- a/tests/Annotated/Unit/Attribute/ColumnTest.php +++ b/tests/Annotated/Unit/Attribute/ColumnTest.php @@ -43,14 +43,14 @@ public function testCustomSizeAttribute(): void $this->assertSame(['size' => 128], $attr->getAttributes()); } - public function testDefaultReadOnly(): void + public function testDefaultReadonlySchema(): void { $attr = $this->getAttribute('column1'); $this->assertFalse($attr->isReadonlySchema()); } - public function testReadOnly(): void + public function testReadonlySchema(): void { $attr = $this->getAttribute('column4'); From 941c8e73c70971d7c9517dedf93753c079b24d2d Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Fri, 12 May 2023 18:04:02 +0300 Subject: [PATCH 3/3] Add cycle/database to the composer.json --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index f5c4def1..0b165128 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "php": ">=8.0", "cycle/orm": "^2.2.0", "cycle/schema-builder": "^2.3", + "cycle/database": "^2.5", "doctrine/annotations": "^1.14.3 || ^2.0.1", "spiral/attributes": "^2.8|^3.0", "spiral/tokenizer": "^2.8|^3.0",