Skip to content

Commit

Permalink
Add readonlySchema to the Column annotation (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
msmakouz authored May 16, 2023
1 parent 47c35bd commit 0fca640
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 0 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
7 changes: 7 additions & 0 deletions src/Annotation/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
*/
Expand All @@ -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) {
Expand Down Expand Up @@ -121,6 +123,11 @@ public function getTypecast(): mixed
return $this->typecast;
}

public function isReadonlySchema(): bool
{
return $this->readonlySchema;
}

/**
* @return array<non-empty-string, mixed>
*/
Expand Down
4 changes: 4 additions & 0 deletions src/Configurator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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('readonlySchema', true);
}

foreach ($column->getAttributes() as $k => $v) {
$field->getAttributes()->set($k, $v);
}
Expand Down
6 changes: 6 additions & 0 deletions tests/Annotated/Fixtures/Fixtures1/Simple.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
17 changes: 17 additions & 0 deletions tests/Annotated/Functional/Driver/Common/TableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,21 @@ public function testNamingNone(ReaderInterface $reader): void

$this->assertSame('with_table', $schema->getName());
}

/**
* @dataProvider allReadersProvider
*/
public function testReadonlySchema(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')->isReadonlySchema());
}
}
17 changes: 17 additions & 0 deletions tests/Annotated/Unit/Attribute/ColumnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -40,6 +43,20 @@ public function testCustomSizeAttribute(): void
$this->assertSame(['size' => 128], $attr->getAttributes());
}

public function testDefaultReadonlySchema(): void
{
$attr = $this->getAttribute('column1');

$this->assertFalse($attr->isReadonlySchema());
}

public function testReadonlySchema(): void
{
$attr = $this->getAttribute('column4');

$this->assertTrue($attr->isReadonlySchema());
}

private function getAttribute(string $field): Column
{
$ref = new ReflectionClass(static::class);
Expand Down

0 comments on commit 0fca640

Please sign in to comment.