diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e6519becdede37024477578eec9023bfa60ee40..32afcc27e8a64c825f749874c366d98210234f15 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,10 +12,6 @@ stages: - vendor/ expire_in: 1 day -install.php81: - extends: .install - image: grifart/php8.1-with-all-modules-and-various-tools - install.php82: extends: .install image: grifart/php8.2-with-all-modules-and-various-tools @@ -24,11 +20,15 @@ install.php83: extends: .install image: grifart/php8.3-with-all-modules-and-various-tools +install.php84: + extends: .install + image: grifart/php8.4-with-all-modules-and-various-tools + .tests: stage: test interruptible: true services: - - postgres:14-alpine + - postgres:16-alpine variables: POSTGRES_DB: tables POSTGRES_USER: postgres @@ -39,12 +39,6 @@ install.php83: script: - composer run test -tests.php81: - extends: .tests - image: grifart/php8.1-with-all-modules-and-various-tools - dependencies: - - install.php81 - tests.php82: extends: .tests image: grifart/php8.2-with-all-modules-and-various-tools @@ -57,11 +51,17 @@ tests.php83: dependencies: - install.php83 +tests.php84: + extends: .tests + image: grifart/php8.4-with-all-modules-and-various-tools + dependencies: + - install.php84 + phpstan: stage: test - image: grifart/php8.3-with-all-modules-and-various-tools + image: grifart/php8.4-with-all-modules-and-various-tools interruptible: true dependencies: - - install.php83 + - install.php84 script: - composer run phpstan diff --git a/composer.json b/composer.json index 6f141889c4538810117757663bfffbeed3b08d89..43beb4f5e568f93bc6088038a15385c0cf1e0261 100644 --- a/composer.json +++ b/composer.json @@ -22,22 +22,22 @@ "test": "tester -C tests" }, "require": { - "php": "^8.1", + "php": "^8.2", "dibi/dibi": "^4.0.2||^5.0", "grifart/scaffolder": "^0.6.3", - "lstrojny/functional-php": "^1.17", + "jiripudil/phun": "^0.1.0", "nette/utils": "^3.0.1||^4.0" }, "require-dev": { - "brick/date-time": "^0.4.1", - "brick/math": "^0.11.0", - "grifart/phpstan-oneline": "^0.4.0", - "nette/bootstrap": "^3.1", - "nette/di": "^3.0", - "nette/tester": "^2.3", - "nikic/php-parser": "^4.13", - "phpstan/phpstan": "^1.0", - "ramsey/uuid": "^4.2" + "brick/date-time": "^0.7.0", + "brick/math": "^0.12.0", + "grifart/phpstan-oneline": "^0.5.0", + "nette/bootstrap": "^3.2", + "nette/di": "^3.2", + "nette/tester": "^2.5", + "nikic/php-parser": "^5.4", + "phpstan/phpstan": "^2.0", + "ramsey/uuid": "^4.7" }, "suggest": { "brick/date-time": "if you want to use date-time types", diff --git a/phpstan.neon b/phpstan.neon index 885431b029a9dc2a97b1be4c8982c9548773c29c..d974faf007f4dd310c1c31cf741672b331da7c01 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,12 +11,3 @@ parameters: excludePaths: - tests/DI/temp/* - - ignoreErrors: - # null() / notNull() currently require type parameter so that it can be used in the return annotation. - # A better solution would be to use a type projection in the return type, but that's not currently supported in PHPStan. - # more info: https://gitlab.grifart.cz/grifart/tables/-/merge_requests/38#note_90571, https://github.com/phpstan/phpstan/issues/3290 - - - message: "#^Template type ValueType of function Grifart\\\\Tables\\\\Conditions\\\\(null|notNull)\\(\\) is not referenced in a parameter\\.$#" - count: 2 - path: src/Conditions/functions.php diff --git a/src/Conditions/Composite.php b/src/Conditions/Composite.php index 146bb63b8857216373359cb201f3625b60d07a6d..1d6eeb09ca1e8e4d405aab92364dbd2952b2646c 100644 --- a/src/Conditions/Composite.php +++ b/src/Conditions/Composite.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Grifart\Tables\Conditions; use Dibi\Expression as DibiExpression; -use function Functional\map; +use function Phun\map; final class Composite implements Condition { diff --git a/src/Conditions/IsIn.php b/src/Conditions/IsIn.php index 50c2db44f6a12299ab6022bf9246bab703957b04..b9bb5caf6e9f0332221a254fe84dd3ce58bbce8b 100644 --- a/src/Conditions/IsIn.php +++ b/src/Conditions/IsIn.php @@ -6,8 +6,8 @@ namespace Grifart\Tables\Conditions; use Dibi\Expression as DibiExpression; use Grifart\Tables\Expression; -use function Functional\map; use function Grifart\Tables\Types\mapToDatabase; +use function Phun\map; /** * @template ValueType diff --git a/src/Conditions/IsNotIn.php b/src/Conditions/IsNotIn.php index c9bb3f6a61644054000fc485609be6a81e07f698..f2bdd34886894baade269acb4e7f5b31cdd60309 100644 --- a/src/Conditions/IsNotIn.php +++ b/src/Conditions/IsNotIn.php @@ -6,8 +6,8 @@ namespace Grifart\Tables\Conditions; use Dibi\Expression as DibiExpression; use Grifart\Tables\Expression; -use function Functional\map; use function Grifart\Tables\Types\mapToDatabase; +use function Phun\map; /** * @template ValueType diff --git a/src/Conditions/IsNotNull.php b/src/Conditions/IsNotNull.php index 9496096261df3249c8271c85b1b4563b634a4d52..c1aac9d3f93a720eaa6a9ca2cc81e2bdd0083fcb 100644 --- a/src/Conditions/IsNotNull.php +++ b/src/Conditions/IsNotNull.php @@ -10,7 +10,7 @@ use Grifart\Tables\Expression; final class IsNotNull implements Condition { /** - * @param Expression<mixed> $expression + * @param Expression<*> $expression */ public function __construct( private Expression $expression, diff --git a/src/Conditions/IsNull.php b/src/Conditions/IsNull.php index ed08268608f1ece9fdf26abea1d7a4f6d7b46a4f..e75992fd389f10e952d71332a48b2fd2e5d7a8dc 100644 --- a/src/Conditions/IsNull.php +++ b/src/Conditions/IsNull.php @@ -10,7 +10,7 @@ use Grifart\Tables\Expression; final class IsNull implements Condition { /** - * @param Expression<mixed> $expression + * @param Expression<*> $expression */ public function __construct( private Expression $expression, diff --git a/src/Conditions/functions.php b/src/Conditions/functions.php index 57f445b3bbcba4d213fa02abf1c1b0ff16b7e9b8..8cfa7143ee25a52726abb12bff5d523b27a2144b 100644 --- a/src/Conditions/functions.php +++ b/src/Conditions/functions.php @@ -94,8 +94,7 @@ function notIn(array $values): \Closure { } /** - * @template ValueType - * @return \Closure(Expression<ValueType>): IsNull + * @return \Closure(Expression<*>): IsNull */ function null(): \Closure { @@ -103,8 +102,7 @@ function null(): \Closure } /** - * @template ValueType - * @return \Closure(Expression<ValueType>): IsNotNull + * @return \Closure(Expression<*>): IsNotNull */ function notNull(): \Closure { diff --git a/src/Database/Identifier.php b/src/Database/Identifier.php index 5cef9a3a0c54b48cca43e1585be0343f664ee488..b7b1aea8b64a6740736a18d9893633eaccb212c4 100644 --- a/src/Database/Identifier.php +++ b/src/Database/Identifier.php @@ -5,7 +5,7 @@ namespace Grifart\Tables\Database; use Dibi\Expression; use Dibi\Literal; -use function Functional\map; +use function Phun\map; final class Identifier { diff --git a/src/Scaffolding/PostgresReflector.php b/src/Scaffolding/PostgresReflector.php index 3c4ce66e5135ebb98bca3d7ed4c977be350e5501..5565d53c44d258084f5943806679b84ed6a97103 100644 --- a/src/Scaffolding/PostgresReflector.php +++ b/src/Scaffolding/PostgresReflector.php @@ -7,8 +7,8 @@ namespace Grifart\Tables\Scaffolding; use Dibi\Connection; use Grifart\Tables\ColumnMetadata; use Grifart\Tables\MissingPrimaryIndex; -use function Functional\map; -use function Functional\reindex; +use function Phun\map; +use function Phun\reindex; final class PostgresReflector { diff --git a/src/Scaffolding/PrimaryKeyImplementation.php b/src/Scaffolding/PrimaryKeyImplementation.php index 7f2a8b3a79ce137af0fe6d2249cb8669360b83de..56c68dee0a0307a837ca3938fb1c3a390b29f4a7 100644 --- a/src/Scaffolding/PrimaryKeyImplementation.php +++ b/src/Scaffolding/PrimaryKeyImplementation.php @@ -13,7 +13,7 @@ use Grifart\Tables\Conditions\Condition; use Grifart\Tables\PrimaryKey; use Grifart\Tables\Table; use Nette\PhpGenerator\Literal; -use function Functional\map; +use function Phun\map; final class PrimaryKeyImplementation implements Capability { diff --git a/src/Scaffolding/TableImplementation.php b/src/Scaffolding/TableImplementation.php index bc5bd15662e28641ec93c347f65f714e95223faa..89192cdff0b8f406dd374a83675325f2f37984e3 100644 --- a/src/Scaffolding/TableImplementation.php +++ b/src/Scaffolding/TableImplementation.php @@ -27,8 +27,8 @@ use Grifart\Tables\Type; use Grifart\Tables\TypeResolver; use Nette\PhpGenerator as Code; use Nette\Utils\Paginator; -use function Functional\map; use function Grifart\ClassScaffolder\Definition\Types\resolve; +use function Phun\map; use function usort; final class TableImplementation implements Capability diff --git a/src/Scaffolding/TablesDefinitions.php b/src/Scaffolding/TablesDefinitions.php index ebd350c92d95a6430db960ffd392703a04598f4d..0a5b6290434a0d50cf22c54745cd9bfb8e8e03d0 100644 --- a/src/Scaffolding/TablesDefinitions.php +++ b/src/Scaffolding/TablesDefinitions.php @@ -11,14 +11,14 @@ use Grifart\Tables\Database\Identifier; use Grifart\Tables\Row; use Grifart\Tables\Type; use Grifart\Tables\TypeResolver; -use function array_keys; -use function Functional\map; use function Grifart\ClassScaffolder\Capabilities\constructorWithPromotedProperties; use function Grifart\ClassScaffolder\Capabilities\getters; use function Grifart\ClassScaffolder\Capabilities\implementedInterface; use function Grifart\ClassScaffolder\Capabilities\namedConstructor; use function Grifart\ClassScaffolder\Capabilities\privatizedConstructor; use function Grifart\ClassScaffolder\Definition\Types\nullable; +use function Phun\map; +use function Phun\mapWithKeys; final class TablesDefinitions { @@ -41,17 +41,17 @@ final class TablesDefinitions throw new \LogicException('No columns found for given configuration. Does referenced table exist?'); } - $columnResolvedTypes = map( + $columnResolvedTypes = mapWithKeys( $columnMetadata, - function (ColumnMetadata $column) use ($schema, $table): Type { + function ($_, ColumnMetadata $column) use ($schema, $table): Type { $location = new Identifier($schema, $table, $column->getName()); return $this->typeResolver->resolveType($column->getType(), $location); }, ); - $columnPhpTypes = map( + $columnPhpTypes = mapWithKeys( $columnMetadata, - static function (ColumnMetadata $column) use ($columnResolvedTypes): PhpType { + static function ($_, ColumnMetadata $column) use ($columnResolvedTypes): PhpType { $type = $columnResolvedTypes[$column->getName()]; $phpType = $type->getPhpType(); return $column->isNullable() ? nullable($phpType) : $phpType; @@ -78,7 +78,7 @@ final class TablesDefinitions ->with(new ModificationsImplementation($tableClassName, $primaryKeyClassName, $columnMetadata)); $primaryKeyColumnNames = $this->pgReflector->retrievePrimaryKeyColumns($schema, $table); - $primaryKeyFields = map($primaryKeyColumnNames, static fn(string $name) => $columnPhpTypes[$name]); + $primaryKeyFields = mapWithKeys($primaryKeyColumnNames, static fn($_, string $name) => $columnPhpTypes[$name]); $primaryKeyClass = (new ClassDefinition($primaryKeyClassName)) ->withFields($primaryKeyFields) ->with( diff --git a/src/TableManager.php b/src/TableManager.php index 48ee27da7deadea313c97bdd00f06bbe198108ee..acbf929754ff0b27455643c39eb45fe1efca894c 100644 --- a/src/TableManager.php +++ b/src/TableManager.php @@ -11,7 +11,8 @@ use Grifart\Tables\Conditions\Condition; use Grifart\Tables\OrderBy\OrderBy; use Grifart\Tables\OrderBy\OrderByDirection; use Nette\Utils\Paginator; -use function Functional\map; +use function Phun\map; +use function Phun\mapWithKeys; // todo: error handling // todo: mapping of exceptions @@ -37,9 +38,9 @@ final class TableManager $this->connection->query( 'INSERT', 'INTO %n.%n', $table::getSchema(), $table::getTableName(), - map( + mapWithKeys( $changes->getModifications(), - static fn(mixed $value, string $columnName) => $value !== null ? $table->getTypeOf($columnName)->toDatabase($value) : null, + static fn(string $columnName, mixed $value) => $value !== null ? $table->getTypeOf($columnName)->toDatabase($value) : null, ), ); } catch (UniqueConstraintViolationException $e) { @@ -60,7 +61,6 @@ final class TableManager $rows = $this->findBy($table, $primaryKey->getCondition($table)); if (\count($rows) === 1) { $row = \reset($rows); - \assert($row instanceof Row, 'It cannot return false as there must be one element in array'); return $row; } \assert(\count($rows) === 0); @@ -110,15 +110,15 @@ final class TableManager $dibiRows = $result->fetchAll(); - /** @var Row $rowClass */ + /** @var class-string<Row> $rowClass */ $rowClass = $table::getRowClass(); $modelRows = []; foreach ($dibiRows as $dibiRow) { \assert($dibiRow instanceof \Dibi\Row); $modelRows[] = $rowClass::reconstitute( - map( + mapWithKeys( $dibiRow->toArray(), - static fn(mixed $value, string $columnName) => $value !== null ? $table->getTypeOf($columnName)->fromDatabase($value) : null, + static fn(string $columnName, mixed $value) => $value !== null ? $table->getTypeOf($columnName)->fromDatabase($value) : null, ), ); } @@ -150,9 +150,9 @@ final class TableManager $this->connection->query( 'UPDATE %n.%n', $table::getSchema(), $table::getTableName(), 'SET %a', - map( + mapWithKeys( $changes->getModifications(), - static fn(mixed $value, string $columnName) => $value !== null ? $table->getTypeOf($columnName)->toDatabase($value) : null, + static fn(string $columnName, mixed $value) => $value !== null ? $table->getTypeOf($columnName)->toDatabase($value) : null, ), 'WHERE %ex', $primaryKey->getCondition($table)->toSql()->getValues(), ); diff --git a/src/Types/ArrayType.php b/src/Types/ArrayType.php index a5cc3dbc9c12651044a8a6464544d6e09855f45c..524863480be546d4ff17e0a098461dfbf7b5bd41 100644 --- a/src/Types/ArrayType.php +++ b/src/Types/ArrayType.php @@ -9,8 +9,8 @@ use Dibi\Literal; use Grifart\ClassScaffolder\Definition\Types\Type as PhpType; use Grifart\Tables\Database\ArrayType as DatabaseArrayType; use Grifart\Tables\Type; -use function Functional\map; use function Grifart\ClassScaffolder\Definition\Types\listOf; +use function Phun\map; /** * @template ItemType diff --git a/src/Types/CompositeType.php b/src/Types/CompositeType.php index eaf60c01478eb408ebacc8fef298afe22076a695..64c42f6c34bf87e7762dad4eb3eb40d576d1fe37 100644 --- a/src/Types/CompositeType.php +++ b/src/Types/CompositeType.php @@ -8,7 +8,8 @@ use Dibi\Expression; use Dibi\Literal; use Grifart\Tables\Database\DatabaseType; use Grifart\Tables\Type; -use function Functional\map; +use function Phun\map; +use function Phun\mapWithKeys; /** * @template T @@ -44,9 +45,9 @@ abstract class CompositeType implements Type { $args = [ new Literal('ROW('), - ...map( + ...mapWithKeys( $value, - fn(mixed $item, int $index) => $item !== null ? $this->types[$index]->toDatabase($item) : new Literal('NULL'), + fn(int $index, mixed $item) => $item !== null ? $this->types[$index]->toDatabase($item) : new Literal('NULL'), ), new Literal(')::'), $this->getDatabaseType()->toSql(), @@ -66,9 +67,9 @@ abstract class CompositeType implements Type $result = $this->parseComposite($value); \assert(\count($result) === \count($this->types)); - return map( + return mapWithKeys( $result, - fn($item, $index) => $item !== null ? $this->types[$index]->fromDatabase($item) : null, + fn($index, $item) => $item !== null ? $this->types[$index]->fromDatabase($item) : null, ); } diff --git a/src/functions.php b/src/functions.php index 891dea6c03e97d38c6d2686617f2cbb2503a19f7..5500ccff9f027cce068afa4a01e4913842b58bbe 100644 --- a/src/functions.php +++ b/src/functions.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Grifart\Tables; use Dibi\Expression as DibiExpression; -use function Functional\map; +use function Phun\map; /** * @template ValueType