From 6eb09c5684c06aed144eca016b2cd7fa3da0106a Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Wed, 10 Jul 2024 13:30:45 +0900 Subject: [PATCH] Update to Doctrine ORM 3.2 #10257 --- composer.json | 4 +- composer.lock | 447 +++++------------- phpstan-baseline.neon | 5 + src/Acl/Acl.php | 9 +- src/Acl/ModelResource.php | 5 +- src/Api/Input/Operator/SearchOperatorType.php | 6 +- src/ConfigProvider.php | 2 +- src/DBAL/Logging/Connection.php | 58 +++ src/DBAL/Logging/Driver.php | 38 ++ src/DBAL/Logging/ForwardSQLLogger.php | 39 -- src/DBAL/Logging/Middleware.php | 19 + src/DBAL/Logging/Statement.php | 46 ++ src/DBAL/Types/AbstractMoneyType.php | 20 +- src/DBAL/Types/ChronosType.php | 20 +- src/DBAL/Types/DateType.php | 19 +- src/DBAL/Types/EnumType.php | 5 - src/DBAL/Types/LocalizedType.php | 9 +- src/DBAL/Types/SetType.php | 5 - src/DBAL/Types/TimeType.php | 19 +- src/ORM/Query/NativeIn.php | 12 +- src/Repository/Traits/LogRepository.php | 9 +- src/Repository/Traits/MessageRepository.php | 9 +- src/Service/DataRestorer.php | 2 +- tests/DBAL/Types/CHFTypeTest.php | 4 +- tests/DBAL/Types/ChronosTypeTest.php | 10 +- tests/DBAL/Types/DateTypeTest.php | 10 +- tests/DBAL/Types/EnumTypeTest.php | 4 +- tests/DBAL/Types/LocalizedTypeTest.php | 6 +- tests/DBAL/Types/PhpEnumTypeTest.php | 3 +- tests/DBAL/Types/SetTypeTest.php | 4 +- tests/DBAL/Types/TimeTypeTest.php | 10 +- tests/Service/EnumAutoMigratorTest.php | 2 + tests/Traits/MariaDbQuotingConnection.php | 6 +- tests/Traits/TestWithEntityManager.php | 5 +- 34 files changed, 396 insertions(+), 475 deletions(-) create mode 100644 src/DBAL/Logging/Connection.php create mode 100644 src/DBAL/Logging/Driver.php delete mode 100644 src/DBAL/Logging/ForwardSQLLogger.php create mode 100644 src/DBAL/Logging/Middleware.php create mode 100644 src/DBAL/Logging/Statement.php diff --git a/composer.json b/composer.json index dc84dca..5bb513a 100644 --- a/composer.json +++ b/composer.json @@ -45,9 +45,9 @@ "ext-pdo": "*", "ext-readline": "*", "cakephp/chronos": "^3.0.3", - "doctrine/dbal": "^3.8", + "doctrine/dbal": "^4.0", "doctrine/migrations": "^3.8", - "ecodev/graphql-doctrine": "^10.0", + "ecodev/graphql-doctrine": "dev-doctrine3", "imagine/imagine": "^1.3", "laminas/laminas-diactoros": "^3.3", "laminas/laminas-log": "^2.17", diff --git a/composer.lock b/composer.lock index f938d04..34b6d87 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e31f085344e8d03568e4c0c219df1053", + "content-hash": "618a2d76b7cc996489939c661dbe32fb", "packages": [ { "name": "cakephp/chronos", @@ -123,99 +123,6 @@ }, "time": "2023-07-18T20:41:43+00:00" }, - { - "name": "doctrine/cache", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", - "shasum": "" - }, - "require": { - "php": "~7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", - "homepage": "https://www.doctrine-project.org/projects/cache.html", - "keywords": [ - "abstraction", - "apcu", - "cache", - "caching", - "couchdb", - "memcached", - "php", - "redis", - "xcache" - ], - "support": { - "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.2.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", - "type": "tidelift" - } - ], - "time": "2022-05-20T20:07:39+00:00" - }, { "name": "doctrine/collections", "version": "2.2.2", @@ -302,140 +209,44 @@ ], "time": "2024-04-18T06:56:21+00:00" }, - { - "name": "doctrine/common", - "version": "3.4.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", - "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", - "shasum": "" - }, - "require": { - "doctrine/persistence": "^2.0 || ^3.0", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9.0 || ^10.0", - "doctrine/collections": "^1", - "phpstan/phpstan": "^1.4.1", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", - "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^6.1", - "vimeo/psalm": "^4.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", - "homepage": "https://www.doctrine-project.org/projects/common.html", - "keywords": [ - "common", - "doctrine", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.4" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", - "type": "tidelift" - } - ], - "time": "2024-04-16T13:35:33+00:00" - }, { "name": "doctrine/dbal", - "version": "3.8.6", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "b7411825cf7efb7e51f9791dea19d86e43b399a1" + "reference": "50fda19f80724b55ff770bb4ff352407008e63c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/b7411825cf7efb7e51f9791dea19d86e43b399a1", - "reference": "b7411825cf7efb7e51f9791dea19d86e43b399a1", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/50fda19f80724b55ff770bb4ff352407008e63c5", + "reference": "50fda19f80724b55ff770bb4ff352407008e63c5", "shasum": "" }, "require": { - "composer-runtime-api": "^2", - "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1|^2", - "php": "^7.4 || ^8.0", + "php": "^8.1", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, "require-dev": { "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", - "jetbrains/phpstorm-stubs": "2023.1", + "jetbrains/phpstorm-stubs": "2023.2", "phpstan/phpstan": "1.11.5", + "phpstan/phpstan-phpunit": "1.4.0", "phpstan/phpstan-strict-rules": "^1.6", - "phpunit/phpunit": "9.6.19", - "psalm/plugin-phpunit": "0.18.4", + "phpunit/phpunit": "10.5.22", + "psalm/plugin-phpunit": "0.19.0", "slevomat/coding-standard": "8.13.1", "squizlabs/php_codesniffer": "3.10.1", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/console": "^4.4|^5.4|^6.0|^7.0", - "vimeo/psalm": "4.30.0" + "symfony/cache": "^6.3.8|^7.0", + "symfony/console": "^5.4|^6.3|^7.0", + "vimeo/psalm": "5.24.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." }, - "bin": [ - "bin/doctrine-dbal" - ], "type": "library", "autoload": { "psr-4": { @@ -488,7 +299,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.8.6" + "source": "https://github.com/doctrine/dbal/tree/4.0.4" }, "funding": [ { @@ -504,7 +315,7 @@ "type": "tidelift" } ], - "time": "2024-06-19T10:38:17+00:00" + "time": "2024-06-19T11:57:23+00:00" }, { "name": "doctrine/deprecations", @@ -986,61 +797,48 @@ }, { "name": "doctrine/orm", - "version": "2.19.6", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073" + "reference": "722cea6536775206e81744542b36fa7c9a4ea3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073", - "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073", + "url": "https://api.github.com/repos/doctrine/orm/zipball/722cea6536775206e81744542b36fa7c9a4ea3e5", + "reference": "722cea6536775206e81744542b36fa7c9a4ea3e5", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5 || ^2.1", - "doctrine/common": "^3.0.3", - "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/collections": "^2.2", + "doctrine/dbal": "^3.8.2 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3 || ^2", - "doctrine/lexer": "^2 || ^3", - "doctrine/persistence": "^2.4 || ^3", + "doctrine/lexer": "^3", + "doctrine/persistence": "^3.3.1", "ext-ctype": "*", - "php": "^7.1 || ^8.0", + "php": "^8.1", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", - "symfony/polyfill-php72": "^1.23", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "doctrine/annotations": "<1.13 || >= 3.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.3.9 || ^7.0" }, "require-dev": { - "doctrine/annotations": "^1.13 || ^2", - "doctrine/coding-standard": "^9.0.2 || ^12.0", - "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.11.1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "doctrine/coding-standard": "^12.0", + "phpbench/phpbench": "^1.0", + "phpstan/phpstan": "1.11.1", + "phpunit/phpunit": "^10.4.0", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "vimeo/psalm": "4.30.0 || 5.24.0" + "symfony/cache": "^5.4 || ^6.2 || ^7.0", + "vimeo/psalm": "5.24.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", - "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", - "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0" }, - "bin": [ - "bin/doctrine" - ], "type": "library", "autoload": { "psr-4": { @@ -1081,9 +879,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.19.6" + "source": "https://github.com/doctrine/orm/tree/3.2.1" }, - "time": "2024-06-26T17:24:40+00:00" + "time": "2024-06-26T21:48:58+00:00" }, { "name": "doctrine/persistence", @@ -1184,20 +982,20 @@ }, { "name": "ecodev/graphql-doctrine", - "version": "10.0.0", + "version": "dev-doctrine3", "source": { "type": "git", "url": "https://github.com/Ecodev/graphql-doctrine.git", - "reference": "087f5594434bfd02c0d24de57c57c0f1beafecab" + "reference": "37d9cc09c9c3a09f83c46b43cdd89488d73d4368" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ecodev/graphql-doctrine/zipball/087f5594434bfd02c0d24de57c57c0f1beafecab", - "reference": "087f5594434bfd02c0d24de57c57c0f1beafecab", + "url": "https://api.github.com/repos/Ecodev/graphql-doctrine/zipball/37d9cc09c9c3a09f83c46b43cdd89488d73d4368", + "reference": "37d9cc09c9c3a09f83c46b43cdd89488d73d4368", "shasum": "" }, "require": { - "doctrine/orm": "^2.15", + "doctrine/orm": "^3.2", "php": "^8.2", "psr/container": "^1.1 || ^2.0", "webonyx/graphql-php": "^15.7" @@ -1228,9 +1026,9 @@ ], "support": { "issues": "https://github.com/Ecodev/graphql-doctrine/issues", - "source": "https://github.com/Ecodev/graphql-doctrine/tree/10.0.0" + "source": "https://github.com/Ecodev/graphql-doctrine/tree/doctrine3" }, - "time": "2024-06-17T11:10:56+00:00" + "time": "2024-07-11T07:09:29+00:00" }, { "name": "imagine/imagine", @@ -3783,86 +3581,6 @@ ], "time": "2024-06-19T12:30:46+00:00" }, - { - "name": "symfony/polyfill-php80", - "version": "v1.30.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-05-31T15:07:36+00:00" - }, { "name": "symfony/service-contracts", "version": "v3.5.0", @@ -7769,6 +7487,86 @@ ], "time": "2024-05-31T14:57:53+00:00" }, + { + "name": "symfony/polyfill-php80", + "version": "v1.30.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T15:07:36+00:00" + }, { "name": "symfony/polyfill-php81", "version": "v1.30.0", @@ -8019,6 +7817,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "ecodev/graphql-doctrine": 20, "friendsofphp/php-cs-fixer": 0, "laminas/laminas-config-aggregator": 0, "laminas/laminas-i18n": 0, diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 95fe4a7..ef2898d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5,6 +5,11 @@ parameters: count: 1 path: src/Api/Enum/PhpEnumType.php + - + message: "#^Parameter \\#1 \\$className of method Ecodev\\\\Felix\\\\Api\\\\Input\\\\Operator\\\\SearchOperatorType\\:\\:fieldToDql\\(\\) expects ReflectionClass, ReflectionClass\\\\|null given\\.$#" + count: 1 + path: src/Api/Input/Operator/SearchOperatorType.php + - message: "#^Method Ecodev\\\\Felix\\\\DBAL\\\\Types\\\\PhpEnumType\\:\\:convertToDatabaseValue\\(\\) should return string\\|null but returns int\\|string\\.$#" count: 1 diff --git a/src/Acl/Acl.php b/src/Acl/Acl.php index 44f05a7..0b8ea47 100644 --- a/src/Acl/Acl.php +++ b/src/Acl/Acl.php @@ -4,7 +4,7 @@ namespace Ecodev\Felix\Acl; -use Doctrine\Common\Util\ClassUtils; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Ecodev\Felix\Model\CurrentUser; use Ecodev\Felix\Model\Model; use Exception; @@ -110,7 +110,7 @@ public function isAllowed($role = null, $resource = null, $privilege = null): bo */ public function isCurrentUserAllowed(Model|string $modelOrResource, string $privilege): bool { - $resource = is_string($modelOrResource) ? $modelOrResource : new ModelResource($this->getClass($modelOrResource), $modelOrResource); + $resource = is_string($modelOrResource) ? $modelOrResource : new ModelResource(DefaultProxyClassNameResolver::getClass($modelOrResource), $modelOrResource); $role = $this->getCurrentRole(); $this->reasons = []; @@ -134,11 +134,6 @@ public function reject(string $reason): false return false; } - private function getClass(Model $resource): string - { - return ClassUtils::getRealClass($resource::class); - } - private function getCurrentRole(): MultipleRoles|string { $user = CurrentUser::get(); diff --git a/src/Acl/ModelResource.php b/src/Acl/ModelResource.php index effe86d..5d9f63f 100644 --- a/src/Acl/ModelResource.php +++ b/src/Acl/ModelResource.php @@ -4,7 +4,7 @@ namespace Ecodev\Felix\Acl; -use Doctrine\Common\Util\ClassUtils; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Ecodev\Felix\Model\Model; use Ecodev\Felix\Utility; use InvalidArgumentException; @@ -34,7 +34,8 @@ public function __construct( throw new InvalidArgumentException('The class name must be an implementation of Model but given: ' . $class); } - $class = ClassUtils::getRealClass($class); + $resolver = new DefaultProxyClassNameResolver(); + $class = $resolver->resolveClassName($class); parent::__construct($class); } diff --git a/src/Api/Input/Operator/SearchOperatorType.php b/src/Api/Input/Operator/SearchOperatorType.php index f92b051..385f0f7 100644 --- a/src/Api/Input/Operator/SearchOperatorType.php +++ b/src/Api/Input/Operator/SearchOperatorType.php @@ -55,8 +55,8 @@ private function getSearchableFields(ClassMetadata $metadata, string $alias): ar // Find most textual fields for the entity $fields = []; foreach ($metadata->fieldMappings as $mapping) { - if (in_array($mapping['fieldName'], $whitelistedFields, true)) { - $fieldName = $mapping['fieldName']; + if (in_array($mapping->fieldName, $whitelistedFields, true)) { + $fieldName = $mapping->fieldName; $field = $alias . '.' . $fieldName; $fields[] = $this->fieldToDql($metadata->getReflectionClass(), $fieldName, $field); @@ -115,7 +115,7 @@ private function getSearchableFieldsOnJoin(UniqueNameFactory $uniqueNameFactory, private function searchOnJoinedEntity(UniqueNameFactory $uniqueNameFactory, ClassMetadata $metadata, QueryBuilder $queryBuilder, string $alias, string $fieldName): array { $association = $metadata->getAssociationMapping($fieldName); - $targetEntity = $association['targetEntity']; + $targetEntity = $association->targetEntity; $joinedMetadata = $queryBuilder->getEntityManager()->getMetadataFactory()->getMetadataFor($targetEntity); $joinedAlias = $uniqueNameFactory->createAliasName($targetEntity); diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index b2c22cb..738856b 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -16,7 +16,7 @@ public function __invoke(): array ], 'dependencies' => [ 'invokables' => [ - DBAL\Logging\ForwardSQLLogger::class, + DBAL\Logging\Middleware::class, Log\Formatter\Extras::class, ], 'factories' => [ diff --git a/src/DBAL/Logging/Connection.php b/src/DBAL/Logging/Connection.php new file mode 100644 index 0000000..99106ba --- /dev/null +++ b/src/DBAL/Logging/Connection.php @@ -0,0 +1,58 @@ +debug('Executing query: {sql}', ['sql' => $sql]); + + return parent::query($sql); + } + + public function exec(string $sql): int|string + { + _log()->debug('Executing statement: {sql}', ['sql' => $sql]); + + return parent::exec($sql); + } + + public function beginTransaction(): void + { + _log()->debug('Beginning transaction'); + + parent::beginTransaction(); + } + + public function commit(): void + { + _log()->debug('Committing transaction'); + + parent::commit(); + } + + public function rollBack(): void + { + _log()->debug('Rolling back transaction'); + + parent::rollBack(); + } +} diff --git a/src/DBAL/Logging/Driver.php b/src/DBAL/Logging/Driver.php new file mode 100644 index 0000000..370a25f --- /dev/null +++ b/src/DBAL/Logging/Driver.php @@ -0,0 +1,38 @@ +debug('Connecting to DB', $this->maskPassword($params)); + + return new Connection(parent::connect($params)); + } + + /** + * @param array $params + * + * @return array + */ + private function maskPassword(#[SensitiveParameter] array $params): array + { + if (isset($params['password'])) { + $params['password'] = '***REDACTED***'; + } + + return $params; + } +} diff --git a/src/DBAL/Logging/ForwardSQLLogger.php b/src/DBAL/Logging/ForwardSQLLogger.php deleted file mode 100644 index ad8b129..0000000 --- a/src/DBAL/Logging/ForwardSQLLogger.php +++ /dev/null @@ -1,39 +0,0 @@ -enabled) { - parent::stopQuery(); - - $this->forwardLog($this->queries[$this->currentQuery]); - } - } - - /** - * Forward query to file logger. - */ - private function forwardLog(array $query): void - { - $extra = [ - 'params' => $query['params'], - 'time' => number_format($query['executionMS'], 6), - ]; - - // Here we cannot inject the logger via DI, or it would be created too early and - // break unit tests by creating two parallel connection to DB and thus timeout - // when a test's transaction is pending but a log is trying to be written on the other connection - _log()->debug($query['sql'], $extra); - } -} diff --git a/src/DBAL/Logging/Middleware.php b/src/DBAL/Logging/Middleware.php new file mode 100644 index 0000000..065cae7 --- /dev/null +++ b/src/DBAL/Logging/Middleware.php @@ -0,0 +1,19 @@ +|array + */ + private array $params = []; + + public function __construct( + StatementInterface $statement, + private readonly string $sql, + ) { + parent::__construct($statement); + } + + public function bindValue(int|string $param, mixed $value, ParameterType $type): void + { + $this->params[$param] = $value; + + parent::bindValue($param, $value, $type); + } + + public function execute(): Result + { + $start = microtime(true); + $result = parent::execute(); + $end = microtime(true); + + _log()->debug($this->sql, [ + 'params' => $this->params, + 'time' => number_format(($end - $start) / 1000, 6), + ]); + + return $result; + } +} diff --git a/src/DBAL/Types/AbstractMoneyType.php b/src/DBAL/Types/AbstractMoneyType.php index 288fb8b..35113d3 100644 --- a/src/DBAL/Types/AbstractMoneyType.php +++ b/src/DBAL/Types/AbstractMoneyType.php @@ -4,15 +4,26 @@ namespace Ecodev\Felix\DBAL\Types; +use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Types\IntegerType; +use Doctrine\DBAL\Types\Type; use InvalidArgumentException; use Money\Money; -abstract class AbstractMoneyType extends IntegerType +abstract class AbstractMoneyType extends Type { abstract protected function createMoney(string $value): Money; + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string + { + return $platform->getIntegerTypeDeclarationSQL($column); + } + + public function getBindingType(): ParameterType + { + return ParameterType::INTEGER; + } + public function getName(): string { return 'Money'; @@ -44,9 +55,4 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform) throw new InvalidArgumentException('Cannot convert to database value: ' . var_export($value, true)); } - - public function requiresSQLCommentHint(AbstractPlatform $platform): bool - { - return true; - } } diff --git a/src/DBAL/Types/ChronosType.php b/src/DBAL/Types/ChronosType.php index 0f504fa..af825b0 100644 --- a/src/DBAL/Types/ChronosType.php +++ b/src/DBAL/Types/ChronosType.php @@ -7,11 +7,17 @@ use Cake\Chronos\Chronos; use DateTimeInterface; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Types\ConversionException; -use Doctrine\DBAL\Types\DateTimeType; +use Doctrine\DBAL\Types\Exception\InvalidFormat; +use Doctrine\DBAL\Types\Exception\InvalidType; +use Doctrine\DBAL\Types\Type; -final class ChronosType extends DateTimeType +final class ChronosType extends Type { + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string + { + return $platform->getDateTimeTypeDeclarationSQL($column); + } + /** * @return ($value is null ? null : string) */ @@ -25,7 +31,7 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform) return $value->format($platform->getDateTimeFormatString()); } - throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'Chronos']); + throw InvalidType::new($value, self::class, ['null', 'Chronos']); } /** @@ -38,9 +44,9 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Ch } if (!is_string($value) && !$value instanceof DateTimeInterface) { - throw ConversionException::conversionFailedFormat( - $value, - $this->getName(), + throw InvalidFormat::new( + (string) $value, + self::class, $platform->getDateTimeFormatString(), ); } diff --git a/src/DBAL/Types/DateType.php b/src/DBAL/Types/DateType.php index c3ea794..d15094a 100644 --- a/src/DBAL/Types/DateType.php +++ b/src/DBAL/Types/DateType.php @@ -6,10 +6,17 @@ use Cake\Chronos\ChronosDate; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Exception\InvalidFormat; +use Doctrine\DBAL\Types\Exception\InvalidType; +use Doctrine\DBAL\Types\Type; -final class DateType extends \Doctrine\DBAL\Types\DateType +final class DateType extends Type { + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string + { + return $platform->getDateTypeDeclarationSQL($column); + } + /** * @return ($value is null ? null : string) */ @@ -23,7 +30,7 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform) return $value->format($platform->getDateFormatString()); } - throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'ChronosDate']); + throw InvalidType::new($value, self::class, ['null', 'ChronosDate']); } /** @@ -36,9 +43,9 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Ch } if (!is_string($value)) { - throw ConversionException::conversionFailedFormat( - $value, - $this->getName(), + throw InvalidFormat::new( + (string) $value, + self::class, $platform->getDateFormatString(), ); } diff --git a/src/DBAL/Types/EnumType.php b/src/DBAL/Types/EnumType.php index 098f338..682f54d 100644 --- a/src/DBAL/Types/EnumType.php +++ b/src/DBAL/Types/EnumType.php @@ -74,11 +74,6 @@ public function getName(): string return $typeName; } - public function requiresSQLCommentHint(AbstractPlatform $platform): bool - { - return true; - } - public function getMappedDatabaseTypes(AbstractPlatform $platform): array { return ['enum']; diff --git a/src/DBAL/Types/LocalizedType.php b/src/DBAL/Types/LocalizedType.php index 68ca425..f287593 100644 --- a/src/DBAL/Types/LocalizedType.php +++ b/src/DBAL/Types/LocalizedType.php @@ -5,7 +5,8 @@ namespace Ecodev\Felix\DBAL\Types; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Exception\SerializationFailed; +use Doctrine\DBAL\Types\Exception\ValueNotConvertible; use Doctrine\DBAL\Types\JsonType; use JsonException; @@ -36,7 +37,7 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): arr $val = parent::convertToPHPValue($value, $platform); if (!is_array($val)) { - throw ConversionException::conversionFailedUnserialization('json', 'value in DB is not a JSON encoded associative array'); + throw ValueNotConvertible::new($value, 'json', 'value in DB is not a JSON encoded associative array'); } return $val; @@ -45,7 +46,7 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): arr public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): string { if (!is_array($value)) { - throw ConversionException::conversionFailedSerialization($value, 'json', 'value must be a PHP array'); + throw SerializationFailed::new($value, 'json', 'value must be a PHP array'); } if (!$value) { @@ -55,7 +56,7 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform) try { return json_encode($value, JSON_THROW_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } catch (JsonException $e) { - throw ConversionException::conversionFailedSerialization($value, 'json', $e->getMessage(), $e); + throw SerializationFailed::new($value, 'json', $e->getMessage(), $e); } } } diff --git a/src/DBAL/Types/SetType.php b/src/DBAL/Types/SetType.php index 0a7cc94..18cdb28 100644 --- a/src/DBAL/Types/SetType.php +++ b/src/DBAL/Types/SetType.php @@ -96,11 +96,6 @@ public function getName(): string return $typeName; } - public function requiresSQLCommentHint(AbstractPlatform $platform): bool - { - return true; - } - public function getMappedDatabaseTypes(AbstractPlatform $platform): array { return ['set']; diff --git a/src/DBAL/Types/TimeType.php b/src/DBAL/Types/TimeType.php index c1297d5..4c2fac3 100644 --- a/src/DBAL/Types/TimeType.php +++ b/src/DBAL/Types/TimeType.php @@ -6,10 +6,17 @@ use Cake\Chronos\ChronosTime; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Exception\InvalidFormat; +use Doctrine\DBAL\Types\Exception\InvalidType; +use Doctrine\DBAL\Types\Type; -final class TimeType extends \Doctrine\DBAL\Types\TimeType +final class TimeType extends Type { + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string + { + return $platform->getTimeTypeDeclarationSQL($column); + } + /** * @return ($value is null ? null : string) */ @@ -23,7 +30,7 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform) return $value->format($platform->getTimeFormatString()); } - throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'ChronosTime']); + throw InvalidType::new($value, self::class, ['null', 'ChronosTime']); } /** @@ -36,9 +43,9 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Ch } if (!is_string($value)) { - throw ConversionException::conversionFailedFormat( - $value, - $this->getName(), + throw InvalidFormat::new( + (string) $value, + self::class, $platform->getTimeFormatString(), ); } diff --git a/src/ORM/Query/NativeIn.php b/src/ORM/Query/NativeIn.php index 0c12929..91878c2 100644 --- a/src/ORM/Query/NativeIn.php +++ b/src/ORM/Query/NativeIn.php @@ -7,9 +7,9 @@ use Doctrine\ORM\Query\AST\Functions\FunctionNode; use Doctrine\ORM\Query\AST\Literal; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use Exception; /** @@ -43,18 +43,18 @@ public static function dql(string $field, string $nativeSql, bool $isNot = false public function parse(Parser $parser): void { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->field = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->nativeQuery = $parser->Literal(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->isNot = $parser->Literal(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } public function getSql(SqlWalker $sqlWalker): string diff --git a/src/Repository/Traits/LogRepository.php b/src/Repository/Traits/LogRepository.php index bfebad0..bde7781 100644 --- a/src/Repository/Traits/LogRepository.php +++ b/src/Repository/Traits/LogRepository.php @@ -19,14 +19,9 @@ trait LogRepository abstract protected function getEntityManager(); /** - * Creates a new QueryBuilder instance that is pre-populated for this entity name. - * - * @param string $alias - * @param null|string $indexBy the index for the from - * - * @return QueryBuilder + * Creates a new QueryBuilder instance that is prepopulated for this entity name. */ - abstract public function createQueryBuilder($alias, $indexBy = null); + abstract public function createQueryBuilder(string $alias, string|null $indexBy = null): QueryBuilder; /** * This should NOT be called directly, instead use `_log()` to log stuff. diff --git a/src/Repository/Traits/MessageRepository.php b/src/Repository/Traits/MessageRepository.php index f79a635..57b4361 100644 --- a/src/Repository/Traits/MessageRepository.php +++ b/src/Repository/Traits/MessageRepository.php @@ -10,14 +10,9 @@ trait MessageRepository { /** - * Creates a new QueryBuilder instance that is pre-populated for this entity name. - * - * @param string $alias - * @param null|string $indexBy the index for the from - * - * @return QueryBuilder + * Creates a new QueryBuilder instance that is prepopulated for this entity name. */ - abstract public function createQueryBuilder($alias, $indexBy = null); + abstract public function createQueryBuilder(string $alias, string|null $indexBy = null): QueryBuilder; /** * @return Message[] diff --git a/src/Service/DataRestorer.php b/src/Service/DataRestorer.php index 848dafe..0bb57b9 100644 --- a/src/Service/DataRestorer.php +++ b/src/Service/DataRestorer.php @@ -211,7 +211,7 @@ private function gePrimaryKey(string $tableName, string $columnName): string } // normal N-N relationship - return $this->namingStrategy->joinKeyColumnName($relation['table1']); + return $this->namingStrategy->joinKeyColumnName($relation['table1'], null); } return 'id'; diff --git a/tests/DBAL/Types/CHFTypeTest.php b/tests/DBAL/Types/CHFTypeTest.php index b4cac72..c951435 100644 --- a/tests/DBAL/Types/CHFTypeTest.php +++ b/tests/DBAL/Types/CHFTypeTest.php @@ -26,7 +26,7 @@ protected function setUp(): void public function testMoney(): void { - self::assertSame('INT', $this->type->getSqlDeclaration(['foo'], $this->platform)); + self::assertSame('INT', $this->type->getSqlDeclaration(['foo' => 'bar'], $this->platform)); // Should always return string $actualPhp = $this->type->convertToPHPValue(100, $this->platform); @@ -36,8 +36,6 @@ public function testMoney(): void // Should support null values self::assertNull($this->type->convertToPHPValue(null, $this->platform)); self::assertNull($this->type->convertToDatabaseValue(null, $this->platform)); - - self::assertTrue($this->type->requiresSQLCommentHint($this->platform)); } public function testConvertToPHPValueThrowsWithInvalidValue(): void diff --git a/tests/DBAL/Types/ChronosTypeTest.php b/tests/DBAL/Types/ChronosTypeTest.php index b2db9d0..cd923bf 100644 --- a/tests/DBAL/Types/ChronosTypeTest.php +++ b/tests/DBAL/Types/ChronosTypeTest.php @@ -8,7 +8,8 @@ use DateTimeImmutable; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; -use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Exception\InvalidFormat; +use Doctrine\DBAL\Types\Exception\InvalidType; use Ecodev\Felix\DBAL\Types\ChronosType; use PHPUnit\Framework\TestCase; @@ -26,8 +27,7 @@ protected function setUp(): void public function testConvertToDatabaseValue(): void { - self::assertSame('DATETIME', $this->type->getSqlDeclaration(['foo'], $this->platform)); - self::assertFalse($this->type->requiresSQLCommentHint($this->platform)); + self::assertSame('DATETIME', $this->type->getSqlDeclaration(['foo' => 'bar'], $this->platform)); $actual = $this->type->convertToDatabaseValue(new Chronos('2016-01-01 15:58:59'), $this->platform); self::assertSame('2016-01-01 15:58:59', $actual, 'support Chronos'); @@ -57,14 +57,14 @@ public function testConvertToPHPValue(): void public function testConvertToPHPValueThrowsWithInvalidValue(): void { - $this->expectException(ConversionException::class); + $this->expectException(InvalidFormat::class); $this->type->convertToPHPValue(123, $this->platform); } public function testConvertToDatabaseValueThrowsWithInvalidValue(): void { - $this->expectException(ConversionException::class); + $this->expectException(InvalidType::class); $this->type->convertToDatabaseValue(123, $this->platform); } diff --git a/tests/DBAL/Types/DateTypeTest.php b/tests/DBAL/Types/DateTypeTest.php index 288e0f7..13a50e1 100644 --- a/tests/DBAL/Types/DateTypeTest.php +++ b/tests/DBAL/Types/DateTypeTest.php @@ -7,7 +7,8 @@ use Cake\Chronos\ChronosDate; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; -use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Exception\InvalidFormat; +use Doctrine\DBAL\Types\Exception\InvalidType; use Ecodev\Felix\DBAL\Types\DateType; use PHPUnit\Framework\TestCase; @@ -25,8 +26,7 @@ protected function setUp(): void public function testConvertToDatabaseValue(): void { - self::assertSame('DATE', $this->type->getSqlDeclaration(['foo'], $this->platform)); - self::assertFalse($this->type->requiresSQLCommentHint($this->platform)); + self::assertSame('DATE', $this->type->getSqlDeclaration(['foo' => 'bar'], $this->platform)); $actual = $this->type->convertToDatabaseValue(new ChronosDate('2016-01-01'), $this->platform); self::assertSame('2016-01-01', $actual, 'support Chronos'); @@ -49,14 +49,14 @@ public function testConvertToPHPValue(): void public function testConvertToPHPValueThrowsWithInvalidValue(): void { - $this->expectException(ConversionException::class); + $this->expectException(InvalidFormat::class); $this->type->convertToPHPValue(123, $this->platform); } public function testConvertToDatabaseValueThrowsWithInvalidValue(): void { - $this->expectException(ConversionException::class); + $this->expectException(InvalidType::class); $this->type->convertToDatabaseValue(123, $this->platform); } diff --git a/tests/DBAL/Types/EnumTypeTest.php b/tests/DBAL/Types/EnumTypeTest.php index 0c51fa0..28d1233 100644 --- a/tests/DBAL/Types/EnumTypeTest.php +++ b/tests/DBAL/Types/EnumTypeTest.php @@ -30,7 +30,7 @@ protected function getPossibleValues(): array public function testEnum(): void { - self::assertSame("ENUM('value1', 'value2')", $this->type->getSqlDeclaration(['foo'], $this->platform)); + self::assertSame("ENUM('value1', 'value2')", $this->type->getSqlDeclaration(['foo' => 'bar'], $this->platform)); // Should always return string self::assertSame('value1', $this->type->convertToPHPValue('value1', $this->platform)); @@ -40,8 +40,6 @@ public function testEnum(): void self::assertNull($this->type->convertToPHPValue('', $this->platform)); self::assertNull($this->type->convertToDatabaseValue(null, $this->platform)); self::assertNull($this->type->convertToDatabaseValue('', $this->platform)); - - self::assertTrue($this->type->requiresSQLCommentHint($this->platform)); } public function testConvertToPHPValueThrowsWithInvalidValue(): void diff --git a/tests/DBAL/Types/LocalizedTypeTest.php b/tests/DBAL/Types/LocalizedTypeTest.php index fad3491..7972498 100644 --- a/tests/DBAL/Types/LocalizedTypeTest.php +++ b/tests/DBAL/Types/LocalizedTypeTest.php @@ -36,19 +36,19 @@ public function testConvertToDatabaseValue(): void public function testConvertToDatabaseValueWillThrowIfNull(): void { - $this->expectExceptionMessage("Could not convert PHP type 'NULL' to 'json', as an 'value must be a PHP array' error was triggered by the serialization"); + $this->expectExceptionMessage('Could not convert PHP type "null" to "json". An error was triggered by the serialization: value must be a PHP array'); $this->type->convertToDatabaseValue(null, $this->platform); } public function testConvertToDatabaseValueWillThrowIfString(): void { - $this->expectExceptionMessage("Could not convert PHP type 'string' to 'json', as an 'value must be a PHP array' error was triggered by the serialization"); + $this->expectExceptionMessage('Could not convert PHP type "string" to "json". An error was triggered by the serialization: value must be a PHP array'); $this->type->convertToDatabaseValue('', $this->platform); } public function testConvertToPHPValueWillThrowIfNotJsonArray(): void { - $this->expectExceptionMessage("Could not convert database value to 'json' as an error was triggered by the unserialization: 'value in DB is not a JSON encoded associative array'"); + $this->expectExceptionMessage('Could not convert database value to "json" as an error was triggered by the unserialization: value in DB is not a JSON encoded associative array'); $this->type->convertToPHPValue('"foo"', $this->platform); } diff --git a/tests/DBAL/Types/PhpEnumTypeTest.php b/tests/DBAL/Types/PhpEnumTypeTest.php index ecf5b0c..1d407cf 100644 --- a/tests/DBAL/Types/PhpEnumTypeTest.php +++ b/tests/DBAL/Types/PhpEnumTypeTest.php @@ -33,8 +33,7 @@ protected function getEnumType(): string public function testEnum(): void { - self::assertSame("ENUM('value1', 'value2')", $this->type->getSqlDeclaration(['foo'], $this->platform)); - self::assertTrue($this->type->requiresSQLCommentHint($this->platform)); + self::assertSame("ENUM('value1', 'value2')", $this->type->getSqlDeclaration(['foo' => 'bar'], $this->platform)); } /** diff --git a/tests/DBAL/Types/SetTypeTest.php b/tests/DBAL/Types/SetTypeTest.php index d1e5a7b..27ee996 100644 --- a/tests/DBAL/Types/SetTypeTest.php +++ b/tests/DBAL/Types/SetTypeTest.php @@ -31,7 +31,7 @@ protected function getPossibleValues(): array public function testSet(): void { - self::assertSame("SET('value1', 'value2')", $this->type->getSqlDeclaration(['foo'], $this->platform)); + self::assertSame("SET('value1', 'value2')", $this->type->getSqlDeclaration(['foo' => 'bar'], $this->platform)); // Should always return string self::assertSame(['value1', 'value2'], $this->type->convertToPHPValue('value1,value2', $this->platform)); @@ -41,8 +41,6 @@ public function testSet(): void self::assertSame([], $this->type->convertToPHPValue('', $this->platform)); self::assertNull($this->type->convertToDatabaseValue(null, $this->platform)); self::assertSame('', $this->type->convertToDatabaseValue([], $this->platform)); - - self::assertTrue($this->type->requiresSQLCommentHint($this->platform)); } public function testConvertToPHPValueThrowsWithInvalidValue(): void diff --git a/tests/DBAL/Types/TimeTypeTest.php b/tests/DBAL/Types/TimeTypeTest.php index e397d5f..9025980 100644 --- a/tests/DBAL/Types/TimeTypeTest.php +++ b/tests/DBAL/Types/TimeTypeTest.php @@ -7,7 +7,8 @@ use Cake\Chronos\ChronosTime; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; -use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Exception\InvalidFormat; +use Doctrine\DBAL\Types\Exception\InvalidType; use Ecodev\Felix\DBAL\Types\TimeType; use PHPUnit\Framework\TestCase; @@ -25,8 +26,7 @@ protected function setUp(): void public function testConvertToDatabaseValue(): void { - self::assertSame('TIME', $this->type->getSqlDeclaration(['foo'], $this->platform)); - self::assertFalse($this->type->requiresSQLCommentHint($this->platform)); + self::assertSame('TIME', $this->type->getSqlDeclaration(['foo' => 'bar'], $this->platform)); $actual = $this->type->convertToDatabaseValue(new ChronosTime('09:33'), $this->platform); self::assertSame('09:33:00', $actual, 'support Chronos'); @@ -49,14 +49,14 @@ public function testConvertToPHPValue(): void public function testConvertToPHPValueThrowsWithInvalidValue(): void { - $this->expectException(ConversionException::class); + $this->expectException(InvalidFormat::class); $this->type->convertToPHPValue(123, $this->platform); } public function testConvertToDatabaseValueThrowsWithInvalidValue(): void { - $this->expectException(ConversionException::class); + $this->expectException(InvalidType::class); $this->type->convertToDatabaseValue(123, $this->platform); } diff --git a/tests/Service/EnumAutoMigratorTest.php b/tests/Service/EnumAutoMigratorTest.php index 881356b..6917a21 100644 --- a/tests/Service/EnumAutoMigratorTest.php +++ b/tests/Service/EnumAutoMigratorTest.php @@ -59,6 +59,8 @@ protected function getEnumType(): string $enumAutoMigrator->postGenerateSchema($event); + // TODO HOW TO HAVE STILL AUTO-MANAGER ENUMS ? + self::assertNull($col1->getComment()); self::assertSame('(FelixEnum:59be1fe78104fed1c6b2e6aada4faf62)', $col2->getComment()); self::assertSame($col2->getComment(), $col3->getComment(), 'different enum that happen to have same definition have same hash, because it makes no difference for DB'); diff --git a/tests/Traits/MariaDbQuotingConnection.php b/tests/Traits/MariaDbQuotingConnection.php index f0f7803..7e31434 100644 --- a/tests/Traits/MariaDbQuotingConnection.php +++ b/tests/Traits/MariaDbQuotingConnection.php @@ -5,17 +5,13 @@ namespace EcodevTests\Felix\Traits; use Doctrine\DBAL\Connection; -use Doctrine\DBAL\ParameterType; -use Doctrine\DBAL\Types\Type; class MariaDbQuotingConnection extends Connection { /** * This replicate MariaDB quoting but without a real connection to DB for ease of testing. - * - * @param null|int|string|Type $type */ - public function quote(mixed $value, $type = ParameterType::STRING): string + public function quote(mixed $value): string { if (in_array($value, [false, null], true)) { return ''; diff --git a/tests/Traits/TestWithEntityManager.php b/tests/Traits/TestWithEntityManager.php index 91a52db..f06352a 100644 --- a/tests/Traits/TestWithEntityManager.php +++ b/tests/Traits/TestWithEntityManager.php @@ -23,11 +23,12 @@ public function setUp(): void // Create the entity manager $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/Blog/Model'], true); $config->addCustomNumericFunction('native_in', NativeIn::class); - $config->setNamingStrategy(new UnderscoreNamingStrategy(CASE_LOWER, true)); + $config->setNamingStrategy(new UnderscoreNamingStrategy(CASE_LOWER)); $connection = DriverManager::getConnection([ 'wrapperClass' => MariaDbQuotingConnection::class, - 'url' => 'sqlite:///:memory:', + 'driver' => 'sqlite3', + 'memory' => true, ]); $this->entityManager = new EntityManager($connection, $config);