diff --git a/src/Scaffolding/Column.php b/src/Scaffolding/Column.php index fa615d2facb7dc7a52cf28352857a4e4b28023f7..34086dd1acd8bf963e17056ce9399d3a5060a995 100644 --- a/src/Scaffolding/Column.php +++ b/src/Scaffolding/Column.php @@ -7,20 +7,20 @@ namespace Grifart\Tables\Scaffolding; final class Column { - /** @var string */ - private $name; + private string $name; - /** @var string */ - private $type; + private string $type; - /** @var bool */ - private $nullable; + private bool $nullable; - public function __construct(string $name, string $type, bool $nullable) + private bool $hasDefaultValue; + + public function __construct(string $name, string $type, bool $nullable, bool $hasDefaultValue) { $this->name = $name; $this->type = $type; $this->nullable = $nullable; + $this->hasDefaultValue = $hasDefaultValue; } public function getName(): string @@ -38,6 +38,9 @@ final class Column return $this->nullable; } - + public function hasDefaultValue(): bool + { + return $this->hasDefaultValue; + } } diff --git a/src/Scaffolding/ModificationsDecorator.php b/src/Scaffolding/ModificationsDecorator.php index 2058f9b3e23f727d0a76cdf93c93d242b2df74e7..dbdbc8987cba6621f9d7d0043158e24b43e41cb6 100644 --- a/src/Scaffolding/ModificationsDecorator.php +++ b/src/Scaffolding/ModificationsDecorator.php @@ -14,20 +14,23 @@ use Nette\PhpGenerator\PhpLiteral; final class ModificationsDecorator implements ClassDecorator { - /** @var string */ - private $modificationsStorage; + private string $modificationsStorage; - /** @var string */ - private $relatedTableClass; + private string $relatedTableClass; - /** @var string */ - private $primaryKeyClass; + private string $primaryKeyClass; - public function __construct(string $relatedTable, string $primaryKeyClass) + private array $columnInfo; + + /** + * @param Column[] $columnInfo + */ + public function __construct(string $relatedTable, string $primaryKeyClass, array $columnInfo) { $this->modificationsStorage = '$this->modifications'; $this->relatedTableClass = $relatedTable; $this->primaryKeyClass = $primaryKeyClass; + $this->columnInfo = $columnInfo; } @@ -54,11 +57,34 @@ final class ModificationsDecorator implements ClassDecorator ]) ->setBody('return self::_update($primaryKey);'); - $classType->addMethod('new') + $newMethod = $classType->addMethod('new') ->setStatic() ->setVisibility('public') ->setReturnType('self') - ->setBody('return self::_new();'); + ->addBody('$self = self::_new();'); + foreach ($definition->getFields() as $fieldName => $fieldType) { + $columnInfo = $this->columnInfo[$fieldName]; + if ( ! $columnInfo->hasDefaultValue()) { + $newMethod->addParameter($fieldName) + ->setTypeHint($fieldType->getTypeHint()) + ->setNullable($fieldType->isNullable()); + + if ($fieldType->requiresDocComment()) { + $newMethod->addComment(\sprintf( + '@param %s $%s%s', + $fieldType->getDocCommentType($namespace), + $fieldName, + $fieldType->hasComment() ? ' ' . $fieldType->getComment($namespace) : '', + )); + } + + $newMethod->addBody('$self->modifications[?] = ?;', [ + $fieldName, + new PhpLiteral('$' . $fieldName), + ]); + } + } + $newMethod->addBody('return $self;'); // implement forTable method $namespace->addUse($this->relatedTableClass); diff --git a/src/Scaffolding/PostgresReflector.php b/src/Scaffolding/PostgresReflector.php index f73ac55abf6fc80c89507f244de4191432d920e0..871dc7d01513f4ad1323c52876ab575c7b4dffc4 100644 --- a/src/Scaffolding/PostgresReflector.php +++ b/src/Scaffolding/PostgresReflector.php @@ -26,7 +26,8 @@ final class PostgresReflector SELECT `pg_attribute`.attname as `name`, pg_catalog.format_type(`pg_attribute`.atttypid, `pg_attribute`.atttypmod) as `type`, - not(`pg_attribute`.attnotnull) AS `nullable` + not(`pg_attribute`.attnotnull) AS `nullable`, + `pg_attribute`.atthasdef AS `hasDefaultValue` FROM pg_catalog.pg_attribute `pg_attribute` WHERE @@ -45,7 +46,7 @@ SQL $results = []; foreach($result->fetchAssoc('name') as $columnName => $columnInfo) { \assert($columnInfo instanceof \Dibi\Row); - $results[$columnName] = new Column($columnInfo['name'], $columnInfo['type'], $columnInfo['nullable']); + $results[$columnName] = new Column($columnInfo['name'], $columnInfo['type'], $columnInfo['nullable'], $columnInfo['hasDefaultValue']); } return $results; } diff --git a/src/Scaffolding/Scaffolding.php b/src/Scaffolding/Scaffolding.php index fc7ffe07cfd21485fbd70746319ba76e29516919..b76a816985babb521997c16e067520f77dbbb6e8 100644 --- a/src/Scaffolding/Scaffolding.php +++ b/src/Scaffolding/Scaffolding.php @@ -64,7 +64,7 @@ final class Scaffolding // row modification class $addTableFields(new ClassDefinitionBuilder($modificationClass)) - ->decorate(new ModificationsDecorator($tableClass, $primaryKeyClass)) + ->decorate(new ModificationsDecorator($tableClass, $primaryKeyClass, $columnsNativeTypes)) ->build(), // table class