diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f3de909c5a15f18d51c236df497c1ce93c227a7b..61aa2464abaef325181bd7566a76adfecbe6acf7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,8 +1,9 @@ stages: - test -.test-verify-template: &test-verify-template +test-verify: stage: test + image: grifart/php8.0-with-all-modules-and-various-tools interruptible: true before_script: @@ -10,8 +11,3 @@ stages: script: - composer run verify - - -test.verify.php74: - <<: *test-verify-template - image: grifart/php7.4-with-gulp-and-all-php-modules diff --git a/composer.json b/composer.json index b8daf2405681a4da028fdb5f15edb882a26fe3af..23abd38e50b43dfe47b6625bbbe5d2d918d2f774 100644 --- a/composer.json +++ b/composer.json @@ -22,15 +22,15 @@ "require": { - "php": "^7.4", + "php": "^8.0", "dibi/dibi": "^4.0.2", - "grifart/class-scaffolder": "^0.2.0|^0.3.0", + "grifart/class-scaffolder": "^0.4.0", "nette/utils": "^3.0.1" }, "require-dev": { "nette/tester": "^2.3", - "grifart/phpstan-oneline": "^0.2.2", - "phpstan/phpstan": "^0.11.17" + "grifart/phpstan-oneline": "^0.4.0", + "phpstan/phpstan": "^0.12" }, diff --git a/src/Modifications.php b/src/Modifications.php index 9b3dd6ca3d5e20296014ac5c4faacb8b1ff29a38..6a810af57002764f38fe56d093ab6deef3f309a3 100644 --- a/src/Modifications.php +++ b/src/Modifications.php @@ -8,7 +8,10 @@ interface Modifications { - /** @internal used by {@see AccountsTable} */ + /** + * @internal used by {@see AccountsTable} + * @return mixed[] + */ public function getModifications(): array; /** @return null|PrimaryKey if null it means, that row is new (do INSERT) */ diff --git a/src/PrimaryKey.php b/src/PrimaryKey.php index 40ac8040000f06986b8c5b029c1b1be997b8c4ef..e90c7da7aa97e90f1be06fe81c2b284b18630acb 100644 --- a/src/PrimaryKey.php +++ b/src/PrimaryKey.php @@ -7,7 +7,7 @@ interface PrimaryKey { /** - * @return array query used in WHERE to narrow down results into one record + * @return array<string, mixed> query used in WHERE to narrow down results into one record */ public function getQuery(): array; diff --git a/src/Row.php b/src/Row.php index 612691434e73217ad52b3708fa38a4d724d591a6..0db2c7713767f2747e7b6d8025602d2d47ebd5dd 100644 --- a/src/Row.php +++ b/src/Row.php @@ -7,7 +7,9 @@ namespace Grifart\Tables; interface Row { - /** @return self */ - public static function reconstitute(array $values); + /** + * @param mixed[] $values + */ + public static function reconstitute(array $values): static; } diff --git a/src/Scaffolding/Column.php b/src/Scaffolding/Column.php index 34086dd1acd8bf963e17056ce9399d3a5060a995..6d1cf634062065b2cbacea69b029df6d87c4d715 100644 --- a/src/Scaffolding/Column.php +++ b/src/Scaffolding/Column.php @@ -7,21 +7,12 @@ namespace Grifart\Tables\Scaffolding; final class Column { - private string $name; - - private string $type; - - private 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 __construct( + private string $name, + private string $type, + private bool $nullable, + private bool $hasDefaultValue, + ) {} public function getName(): string { diff --git a/src/Scaffolding/PostgresReflector.php b/src/Scaffolding/PostgresReflector.php index 871dc7d01513f4ad1323c52876ab575c7b4dffc4..a580c8d8e0338cb0d184f946d93963a8bb7912dd 100644 --- a/src/Scaffolding/PostgresReflector.php +++ b/src/Scaffolding/PostgresReflector.php @@ -9,13 +9,9 @@ use Dibi\Connection; final class PostgresReflector { - /** @var Connection */ - private $connection; - - public function __construct(Connection $connection) - { - $this->connection = $connection; - } + public function __construct( + private Connection $connection + ) {} /** * source: https://stackoverflow.com/a/51897900/631369 diff --git a/src/Scaffolding/PrivateConstructorDecorator.php b/src/Scaffolding/PrivateConstructorDecorator.php index 0007998e332f424d6d64c4dcb67a7df8c9da0c2c..0889283bc8501ad4bd0a1d90bab1a2caa25711f4 100644 --- a/src/Scaffolding/PrivateConstructorDecorator.php +++ b/src/Scaffolding/PrivateConstructorDecorator.php @@ -11,6 +11,6 @@ final class PrivateConstructorDecorator implements ClassDecorator public function decorate(ClassType $classType, ClassDefinition $definition): void { - $classType->getMethod('__construct')->setVisibility('private'); + $classType->getMethod('__construct')->setPrivate(); } } diff --git a/src/Scaffolding/ReconstituteConstructorDecorator.php b/src/Scaffolding/ReconstituteConstructorDecorator.php index 046c3cfb121292525875a4d15d43028042c73433..e2739f939588db64df6738f5d1945e615f720693 100644 --- a/src/Scaffolding/ReconstituteConstructorDecorator.php +++ b/src/Scaffolding/ReconstituteConstructorDecorator.php @@ -14,7 +14,7 @@ final class ReconstituteConstructorDecorator implements ClassDecorator public function decorate(ClassType $classType, ClassDefinition $definition): void { $reconstitute = $classType->addMethod('reconstitute') - ->setReturnType('self') + ->setReturnType('static') ->setParameters([(new Code\Parameter('values'))->setTypeHint('array')]) ->setStatic(); @@ -25,6 +25,6 @@ final class ReconstituteConstructorDecorator implements ClassDecorator // todo: add array_keys that it contains just keys that are necessary - $reconstitute->addBody("return new self($questionMarks);", \array_values($literals)); + $reconstitute->addBody("return new static($questionMarks);", \array_values($literals)); } } diff --git a/src/Scaffolding/Scaffolding.php b/src/Scaffolding/Scaffolding.php index 2edb17cbbf80eaaeaa944334a5e45236026ded2f..d83bd9673324b8c73dbd385af1bd1c0a569758d2 100644 --- a/src/Scaffolding/Scaffolding.php +++ b/src/Scaffolding/Scaffolding.php @@ -8,8 +8,8 @@ namespace Grifart\Tables\Scaffolding; use Grifart\ClassScaffolder\Decorators\GettersDecorator; use Grifart\ClassScaffolder\Decorators\InitializingConstructorDecorator; use Grifart\ClassScaffolder\Decorators\PropertiesDecorator; +use Grifart\ClassScaffolder\Definition\ClassDefinition; use Grifart\ClassScaffolder\Definition\ClassDefinitionBuilder; -use Grifart\ClassScaffolder\Definition\Types\Type; use Grifart\Tables\Row; use Grifart\Tables\TypeMapper; use function Grifart\ClassScaffolder\Definition\Types\nullable; @@ -23,6 +23,9 @@ final class Scaffolding return "$schema.$table.$column"; } + /** + * @return ClassDefinition[] + */ public static function definitionsForPgTable( PostgresReflector $pgReflector, TypeMapper $mapper, diff --git a/src/Scaffolding/TableDecorator.php b/src/Scaffolding/TableDecorator.php index 7436f284e35d5a81a98e73d09f5b912e204da483..61b8328974644785381995dcdaaa74f1a28a907a 100644 --- a/src/Scaffolding/TableDecorator.php +++ b/src/Scaffolding/TableDecorator.php @@ -18,28 +18,24 @@ use Webmozart\Assert\Assert; final class TableDecorator implements ClassDecorator { - /** @var string */ - private $schema; + private string $schema; - /** @var string */ - private $tableName; + private string $tableName; - /** @var string */ - private $primaryKeyClass; + private string $primaryKeyClass; - /** @var string */ - private $rowClass; + private string $rowClass; - /** @var string */ - private $modificationClass; + private string $modificationClass; /** @var Column[] */ - private $columnInfo; + private array $columnInfo; /** @var array<string, Type> */ - private $columnPhpTypes; + private array $columnPhpTypes; /** + * @param array<string, Column> $columnInfo * @param array<string, Type> $columnPhpTypes */ public function __construct(string $schema, string $tableName, string $primaryKeyClass, string $rowClass, string $modificationClass, array $columnInfo, array $columnPhpTypes) @@ -269,7 +265,7 @@ final class TableDecorator implements ClassDecorator $this->implementConfigMethod($classType, $name, new Code\PhpLiteral($namespace->unresolveName($class) . '::class')); } - private function implementConfigMethod(Code\ClassType $classType, string $name, $value): void + private function implementConfigMethod(Code\ClassType $classType, string $name, mixed $value): void { $classType->addMethod($name) ->setStatic() diff --git a/src/TableManager.php b/src/TableManager.php index e79ed40b7b535bab5c7c69b395403a2e93aa7b32..0a6e04c4debd1a53ec89f100865e9a5ef5d72c84 100644 --- a/src/TableManager.php +++ b/src/TableManager.php @@ -15,21 +15,11 @@ use Dibi\Connection; final class TableManager { - /** @var Connection */ - private $connection; - - /** @var TypeMapper */ - private $phpToDatabaseMapper; - - /** @var TypeMapper */ - private $databaseToPhpMapper; - - public function __construct(Connection $connection, TypeMapper $phpToDatabaseMapper, TypeMapper $databaseToPhpMapper) - { - $this->connection = $connection; - $this->phpToDatabaseMapper = $phpToDatabaseMapper; - $this->databaseToPhpMapper = $databaseToPhpMapper; - } + public function __construct( + private Connection $connection, + private TypeMapper $phpToDatabaseMapper, + private TypeMapper $databaseToPhpMapper, + ) {} public function insert(Table $table, Modifications $changes): void @@ -55,7 +45,13 @@ final class TableManager return NULL; } - /** @return Row[] (subclass of row) */ + /** + * @param array<string, mixed> $conditions Conditions provides low-level access to "where" clause concatenated by %and. + * More: https://dibiphp.com/en/documentation + * Note! Types and names are currently NOT mapped. + * Please follow https://gitlab.grifart.cz/grifart/tables/-/issues/2 on progress. + * @return Row[] (subclass of row) + */ public function findBy(Table $table, array $conditions): array { $result = $this->connection->query( @@ -114,6 +110,10 @@ final class TableManager } + /** + * @param array<string, mixed> $values + * @return array<string, mixed> + */ private static function mapTypes(TypeMapper $mapper, array $values, Table $table): array { // could not use array_map as it does not preserve indexes diff --git a/src/TypeMapper.php b/src/TypeMapper.php index 17582a06f2ea0413e09807ee8cd8f158db43fba2..310d60731a2a7eaafa718a3db7149fb1b0393fe4 100644 --- a/src/TypeMapper.php +++ b/src/TypeMapper.php @@ -10,12 +10,12 @@ final class TypeMapper /** * @var (callable(string $typeName, string $location): (string|Type|null))[] */ - private $matchers = []; + private array $matchers = []; /** * @var (callable(mixed $value, string $typeName): mixed)[] */ - private $mappings = []; + private array $mappings = []; /** @@ -24,12 +24,12 @@ final class TypeMapper * * TODO: isn't it too general? Or just map db-type name to php type and back? */ - public function addMapping(callable $typeMatcher, callable $mapper) { + public function addMapping(callable $typeMatcher, callable $mapper): void { $this->matchers[] = $typeMatcher; $this->mappings[] = $mapper; } - public function map(string $location, string $typeName, $value) { + public function map(string $location, string $typeName, mixed $value): mixed { if ($value === NULL) { return NULL; // todo: really do not translate? } @@ -44,14 +44,7 @@ final class TypeMapper throw CouldNotMapTypeException::didYouRegisterTypeMapperFor($typeName, $value); } - private function getTypeForValue($value): string { - return !\is_object($value) ? \gettype($value) : \get_class($value); - } - - /** - * @return string|Type - */ - public function mapType(string $location, string $typeName) + public function mapType(string $location, string $typeName): string|Type { foreach($this->matchers as $idx => $matcher) { if ( ($translatingType = $matcher($typeName, $location)) !== NULL) { diff --git a/src/exceptions.php b/src/exceptions.php index 6e10e016ae0c869bdfba1aeaed617b6823febcf4..405d957461b58f38a46a0a0dc4f171086f1ce3fb 100644 --- a/src/exceptions.php +++ b/src/exceptions.php @@ -21,7 +21,7 @@ final class ProbablyBrokenPrimaryIndexImplementation extends UsageException { final class CouldNotMapTypeException extends UsageException { - public static function didYouRegisterTypeMapperFor(string $typeName, $value): self + public static function didYouRegisterTypeMapperFor(string $typeName, mixed $value): self { return new self( "Did you register type mapper for type '$typeName' and value of type "