Skip to content

Commit

Permalink
Declare generated fields in ORM Schema (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
msmakouz authored Feb 8, 2024
1 parent 891fd97 commit fd6de37
Show file tree
Hide file tree
Showing 16 changed files with 155 additions and 40 deletions.
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: cycle
13 changes: 8 additions & 5 deletions .github/workflows/ci-mssql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ jobs:
extensions: pdo, pdo_sqlsrv
mssql: 'server:2019-latest'
- php: '8.1'
extensions: pdo, pdo_sqlsrv-5.11.0
extensions: pdo, pdo_sqlsrv
mssql: 'server:2019-latest'
- php: '8.2'
extensions: pdo, pdo_sqlsrv-5.11.0
extensions: pdo, pdo_sqlsrv
mssql: 'server:2019-latest'
- php: '8.3'
extensions: pdo, pdo_sqlsrv
mssql: 'server:2019-latest'

services:
Expand Down Expand Up @@ -70,11 +73,11 @@ jobs:
run: composer self-update

- name: Install dependencies with composer
if: matrix.php != '8.2'
if: matrix.php != '8.4'
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Install dependencies with composer php 8.2
if: matrix.php == '8.2'
- name: Install dependencies with composer php 8.4
if: matrix.php == '8.4'
run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Run tests with phpunit without coverage
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/ci-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
- "8.0"
- "8.1"
- "8.2"
- "8.3"

mysql-version:
- "5.7"
Expand Down Expand Up @@ -81,11 +82,11 @@ jobs:
php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-
- name: Install dependencies with composer
if: matrix.php-version != '8.2'
if: matrix.php-version != '8.4'
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Install dependencies with composer php 8.2
if: matrix.php-version == '8.2'
- name: Install dependencies with composer php 8.4
if: matrix.php-version == '8.4'
run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Run mysql tests with phpunit
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/ci-pgsql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
- "8.0"
- "8.1"
- "8.2"
- "8.3"

pgsql-version:
- "10"
Expand Down Expand Up @@ -82,11 +83,11 @@ jobs:
php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-
- name: Install dependencies with composer
if: matrix.php-version != '8.2'
if: matrix.php-version != '8.4'
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Install dependencies with composer php 8.2
if: matrix.php-version == '8.2'
- name: Install dependencies with composer php 8.4
if: matrix.php-version == '8.4'
run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Run pgsql tests with phpunit
Expand Down
14 changes: 8 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
- "8.0"
- "8.1"
- "8.2"
- "8.3"
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -46,10 +47,10 @@ jobs:
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies with composer
if: matrix.php-version != '8.2'
if: matrix.php-version != '8.4'
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
- name: Install dependencies with composer php 8.2
if: matrix.php-version == '8.2'
- name: Install dependencies with composer php 8.4
if: matrix.php-version == '8.4'
run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
- name: Execute Tests
run: |
Expand Down Expand Up @@ -78,6 +79,7 @@ jobs:
- "8.0"
- "8.1"
- "8.2"
- "8.3"
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -99,11 +101,11 @@ jobs:
restore-keys: ${{ runner.os }}-composer-

- name: Install dependencies with composer
if: matrix.php-version != '8.1'
if: matrix.php-version != '8.4'
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Install dependencies with composer php 8.1
if: matrix.php-version == '8.1'
- name: Install dependencies with composer php 8.4
if: matrix.php-version == '8.4'
run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Execute Tests
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,3 @@ jobs:
with:
os: >-
['ubuntu-latest']
php: >-
['8.1']
37 changes: 34 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,43 @@
"name": "cycle/entity-behavior",
"description": "Provides a collection of attributes that add behaviors to Cycle ORM entities",
"type": "library",
"license": "MIT",
"homepage": "https://cycle-orm.dev",
"support": {
"issues": "https://github.com/cycle/entity-behavior/issues",
"source": "https://github.com/cycle/entity-behavior",
"docs": "https://cycle-orm.dev/docs",
"chat": "https://discord.gg/spiralphp"
},
"authors": [
{
"name": "Anton Titov (wolfy-j)",
"email": "[email protected]"
},
{
"name": "Aleksei Gagarin (roxblnfk)",
"email": "[email protected]"
},
{
"name": "Pavel Butchnev (butschster)",
"email": "[email protected]"
},
{
"name": "Maksim Smakouz (msmakouz)",
"email": "[email protected]"
}
],
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/cycle"
}
],
"require": {
"php": ">=8.0",
"psr/event-dispatcher": "^1",
"cycle/orm": "^2.0",
"cycle/schema-builder": "^2.5",
"cycle/orm": "^2.7",
"cycle/schema-builder": "^2.8",
"psr/container": "^1.0|^2.0",
"yiisoft/injector": "^1.0"
},
Expand All @@ -17,7 +49,6 @@
"spiral/tokenizer": "^2.8 || ^3.0",
"vimeo/psalm": "^5.11"
},
"license": "MIT",
"autoload": {
"psr-4": {
"Cycle\\ORM\\Entity\\Behavior\\": "src/"
Expand Down
5 changes: 3 additions & 2 deletions src/CreatedAt.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Cycle\ORM\Entity\Behavior\Schema\BaseModifier;
use Cycle\ORM\Entity\Behavior\Schema\RegistryModifier;
use Cycle\ORM\Entity\Behavior\Listener\CreatedAt as Listener;
use Cycle\ORM\Schema\GeneratedField;
use Cycle\Schema\Registry;
use Doctrine\Common\Annotations\Annotation\Attribute;
use Doctrine\Common\Annotations\Annotation\Attributes;
Expand Down Expand Up @@ -63,7 +64,7 @@ public function compute(Registry $registry): void
$this->column = $modifier->findColumnName($this->field, $this->column);

if ($this->column !== null) {
$modifier->addDatetimeColumn($this->column, $this->field)
$modifier->addDatetimeColumn($this->column, $this->field, GeneratedField::BEFORE_INSERT)
->nullable(false)
->defaultValue(AbstractColumn::DATETIME_NOW);
}
Expand All @@ -75,7 +76,7 @@ public function render(Registry $registry): void

$this->column = $modifier->findColumnName($this->field, $this->column) ?? $this->field;

$modifier->addDatetimeColumn($this->column, $this->field)
$modifier->addDatetimeColumn($this->column, $this->field, GeneratedField::BEFORE_INSERT)
->nullable(false)
->defaultValue(AbstractColumn::DATETIME_NOW);
}
Expand Down
21 changes: 18 additions & 3 deletions src/OptimisticLock.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Cycle\ORM\Entity\Behavior\Schema\RegistryModifier;
use Cycle\ORM\Entity\Behavior\Exception\BehaviorCompilationException;
use Cycle\ORM\Entity\Behavior\Listener\OptimisticLock as Listener;
use Cycle\ORM\Schema\GeneratedField;
use Cycle\Schema\Definition\Field;
use Cycle\Schema\Registry;
use Doctrine\Common\Annotations\Annotation\Enum;
Expand Down Expand Up @@ -132,18 +133,32 @@ private function addField(Registry $registry): void

switch ($this->rule) {
case self::RULE_INCREMENT:
$modifier->addIntegerColumn($this->column, $this->field)
$modifier
->addIntegerColumn(
$this->column,
$this->field,
GeneratedField::BEFORE_INSERT | GeneratedField::BEFORE_UPDATE
)
->nullable(false)
->defaultValue(self::DEFAULT_INT_VERSION);
break;
case self::RULE_RAND_STR:
case self::RULE_MICROTIME:
$modifier->addStringColumn($this->column, $this->field)
$modifier
->addStringColumn(
$this->column,
$this->field,
GeneratedField::BEFORE_INSERT | GeneratedField::BEFORE_UPDATE
)
->nullable(false)
->string(self::STRING_COLUMN_LENGTH);
break;
case self::RULE_DATETIME:
$modifier->addDatetimeColumn($this->column, $this->field);
$modifier->addDatetimeColumn(
$this->column,
$this->field,
GeneratedField::BEFORE_INSERT | GeneratedField::BEFORE_UPDATE
);
break;
default:
throw new BehaviorCompilationException(
Expand Down
35 changes: 24 additions & 11 deletions src/Schema/RegistryModifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,72 +51,85 @@ public function __construct(Registry $registry, string $role)
$this->defaults = $registry->getDefaults();
}

public function addDatetimeColumn(string $columnName, string $fieldName): AbstractColumn
public function addDatetimeColumn(string $columnName, string $fieldName, int|null $generated = null): AbstractColumn
{
if ($this->fields->has($fieldName)) {
if (!static::isDatetimeType($this->fields->get($fieldName)->getType())) {
throw new BehaviorCompilationException(sprintf('Field %s must be of type datetime.', $fieldName));
}
$this->validateColumnName($fieldName, $columnName);
$this->fields->get($fieldName)->setGenerated($generated);

return $this->table->column($columnName);
}

$this->fields->set(
$fieldName,
(new Field())->setColumn($columnName)->setType('datetime')->setTypecast('datetime')
);
$field = (new Field())
->setColumn($columnName)
->setType('datetime')
->setTypecast('datetime')
->setGenerated($generated);
$this->fields->set($fieldName, $field);

return $this->table->column($columnName)->type(self::DATETIME_COLUMN);
}

public function addIntegerColumn(string $columnName, string $fieldName): AbstractColumn
public function addIntegerColumn(string $columnName, string $fieldName, int|null $generated = null): AbstractColumn
{
if ($this->fields->has($fieldName)) {
if (!static::isIntegerType($this->fields->get($fieldName)->getType())) {
throw new BehaviorCompilationException(sprintf('Field %s must be of type integer.', $fieldName));
}
$this->validateColumnName($fieldName, $columnName);
$this->fields->get($fieldName)->setGenerated($generated);

return $this->table->column($columnName);
}

$this->fields->set($fieldName, (new Field())->setColumn($columnName)->setType('integer')->setTypecast('int'));
$field = (new Field())
->setColumn($columnName)
->setType('integer')
->setTypecast('int')
->setGenerated($generated);
$this->fields->set($fieldName, $field);

return $this->table->column($columnName)->type(self::INT_COLUMN);
}

public function addStringColumn(string $columnName, string $fieldName): AbstractColumn
public function addStringColumn(string $columnName, string $fieldName, int|null $generated = null): AbstractColumn
{
if ($this->fields->has($fieldName)) {
if (!static::isStringType($this->fields->get($fieldName)->getType())) {
throw new BehaviorCompilationException(sprintf('Field %s must be of type string.', $fieldName));
}
$this->validateColumnName($fieldName, $columnName);
$this->fields->get($fieldName)->setGenerated($generated);

return $this->table->column($columnName);
}

$this->fields->set($fieldName, (new Field())->setColumn($columnName)->setType('string'));
$field = (new Field())->setColumn($columnName)->setType('string')->setGenerated($generated);
$this->fields->set($fieldName, $field);

return $this->table->column($columnName)->type(self::STRING_COLUMN);
}

/**
* @throws BehaviorCompilationException
*/
public function addUuidColumn(string $columnName, string $fieldName): AbstractColumn
public function addUuidColumn(string $columnName, string $fieldName, int|null $generated = null): AbstractColumn
{
if ($this->fields->has($fieldName)) {
if (!static::isUuidType($this->fields->get($fieldName)->getType())) {
throw new BehaviorCompilationException(sprintf('Field %s must be of type uuid.', $fieldName));
}
$this->validateColumnName($fieldName, $columnName);
$this->fields->get($fieldName)->setGenerated($generated);

return $this->table->column($columnName);
}

$this->fields->set($fieldName, (new Field())->setColumn($columnName)->setType('uuid'));
$field = (new Field())->setColumn($columnName)->setType('uuid')->setGenerated($generated);
$this->fields->set($fieldName, $field);

return $this->table->column($columnName)->type(self::UUID_COLUMN);
}
Expand Down
3 changes: 2 additions & 1 deletion src/SoftDelete.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Cycle\ORM\Entity\Behavior\Schema\BaseModifier;
use Cycle\ORM\Entity\Behavior\Schema\RegistryModifier;
use Cycle\ORM\Entity\Behavior\Listener\SoftDelete as Listener;
use Cycle\ORM\Schema\GeneratedField;
use Cycle\Schema\Registry;
use Doctrine\Common\Annotations\Annotation\Attribute;
use Doctrine\Common\Annotations\Annotation\Attributes;
Expand Down Expand Up @@ -76,7 +77,7 @@ public function render(Registry $registry): void

$this->column = $modifier->findColumnName($this->field, $this->column) ?? $this->field;

$modifier->addDatetimeColumn($this->column, $this->field)
$modifier->addDatetimeColumn($this->column, $this->field, GeneratedField::BEFORE_UPDATE)
->nullable(true);
}
}
7 changes: 6 additions & 1 deletion src/UpdatedAt.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Cycle\ORM\Entity\Behavior\Schema\BaseModifier;
use Cycle\ORM\Entity\Behavior\Schema\RegistryModifier;
use Cycle\ORM\Entity\Behavior\Listener\UpdatedAt as Listener;
use Cycle\ORM\Schema\GeneratedField;
use Cycle\Schema\Registry;
use Doctrine\Common\Annotations\Annotation\Attribute;
use Doctrine\Common\Annotations\Annotation\Attributes;
Expand Down Expand Up @@ -76,6 +77,10 @@ public function render(Registry $registry): void

$this->column = $modifier->findColumnName($this->field, $this->column) ?? $this->field;

$modifier->addDatetimeColumn($this->column, $this->field);
$modifier->addDatetimeColumn(
$this->column,
$this->field,
GeneratedField::BEFORE_INSERT | GeneratedField::BEFORE_UPDATE
);
}
}
Loading

0 comments on commit fd6de37

Please sign in to comment.